from PyCPU import * from PyDebug import * from PyEmu import PEPyEmu rawinstruction = "\x66\x89\x45\xF6" instruction = pydasm.get_instruction(rawinstruction, pydasm.MODE_32) pyinstruction = PyInstruction(instruction) disasm = pydasm.get_instruction_string(instruction, pydasm.FORMAT_INTEL, 0).rstrip(" ") #DebugInstruction(pyinstruction) emu = PEPyEmu() emu.cpu.set_debug(1) emu.set_register("EDX", 0xfe) print "EAX: 0x%08x EDX: 0x%08x" % (emu.cpu.EAX, emu.cpu.EDX) print "Executing [%s]..." % disasm, # An oversight in pydasm mnemonic parsing pyinstruction.mnemonic = pyinstruction.mnemonic.split() if pyinstruction.mnemonic[0] in ["rep", "repe", "repne", "lock"]: pyinstruction.mnemonic = pyinstruction.mnemonic[1] else: pyinstruction.mnemonic = pyinstruction.mnemonic[0] # Check if we support this instruction if pyinstruction.mnemonic in emu.cpu.supported_instructions: # Execute! if not emu.cpu.supported_instructions[pyinstruction.mnemonic](
c = textsection.data[x] emu.set_memory(codebase + x, int(ord(c)), size=1) print "[*] Text section loaded into memory" print "[*] Loading data section bytes into memory" for x in range(len(datasection.data)): c = datasection.data[x] emu.set_memory(database + x, int(ord(c)), size=1) print "[*] Data section loaded into memory\n" emu.set_register("EIP", address) #emu.set_stack_variable(0x10, 0x00000000, name="var_10") #emu.set_stack_variable(0x0c, 0x11111111, name="var_c") #emu.set_stack_variable(0x08, 0x22222222, name="var_8") #emu.set_stack_variable(0x04, 0x33333333, name="var_4") emu.set_stack_argument(0x8, 0x10, name="arg_0") emu.set_stack_argument(0xc, 0x20, name="arg_4") c = None while c != "x": if not emu.execute(): sys.exit(-1) emu.dump_regs()
emu.set_memory(database + x, int(ord(c)), size=1) print "[*] RData Loaded in memory" print "[*] Loading data section bytes into memory" database = 0x40d000 print len(datasection.data) for y in range(len(datasection.data)): c = datasection.data[y] #print "0x%08x"%(database + x + y) if int(ord(c)) == 0xbb: print "#################0x%08x"%(database+x+y) emu.set_memory(database + y, int(ord(c)), size=1) print "[*] Data section loaded into memory\n" print "%08x"%emu.get_register("EIP") print "%08x"%address emu.set_register("EIP", address) print "%08x"%emu.get_register("EIP") #emu.set_stack_variable(0x10, 0x00000000, name="var_10") #emu.set_stack_variable(0x0c, 0x11111111, name="var_c") #emu.set_stack_variable(0x08, 0x22222222, name="var_8") #emu.set_stack_variable(0x04, 0x33333333, name="var_4") emu.set_stack_argument(0x8, 0x10, name="arg_0") emu.set_stack_argument(0xc, 0x20, name="arg_4") c = None while c != "x": if not emu.execute(): sys.exit(-1)
class AVEngine: def __init__(self): self.imagebase = 0 self.codebase = 0 self.database = 0 self.bytesobs =0 self.deobsbytes=0 self.entrypoint =0 self.pe = 0 self.emu=0 self.obsfucated=0 def SearchString(self,text, pattern, no_of_split): patterns=pattern.split("*", no_of_split) for pattern in patterns: offset = text.find(pattern) if(offset == -1): print "not found" ,hex(ord(pattern[0])), offset return 0 text= text[offset+len(pattern):] return 1 def init(self ,filename): if filename: self.pe = pefile.PE(filename) else: print "[!] Blank filename specified" sys.exit(2) self.imagebase = self.pe.OPTIONAL_HEADER.ImageBase self.codebase = self.pe.OPTIONAL_HEADER.ImageBase + self.pe.OPTIONAL_HEADER.BaseOfCode self.database = self.pe.OPTIONAL_HEADER.ImageBase + self.pe.OPTIONAL_HEADER.BaseOfData self.entrypoint = self.pe.OPTIONAL_HEADER.ImageBase + self.pe.OPTIONAL_HEADER.AddressOfEntryPoint print "[*] Image Base Addr: 0x%08x" % (self.imagebase) print "[*] Code Base Addr: 0x%08x" % (self.codebase) print "[*] Data Base Addr: 0x%08x" % (self.database) print "[*] Entry Point Addr: 0x%08x\n" % (self.entrypoint) self.emu = PEPyEmu() def isfileobsfucated(self): ep = self.pe.OPTIONAL_HEADER.AddressOfEntryPoint ep_ava = ep+self.pe.OPTIONAL_HEADER.ImageBase data = self.pe.get_memory_mapped_image()[ep:ep+40] #idata = array.array('B', [0xb9,0x5a,0x01,0x00,0x00,0x43,0x4b,0xbe,0x00,0x10,0x40,0x00,0xb3,0xa6,0x8a,0x16,0x32,0xd3]) idata = array.array('B', [0xB9,0x2A,0xBE,0x2A,0xB3,0x2A,0x8A,0x16,0x32,0xD3,0x8A,0x1E,0x88,0x16,0x46,0xE2,0x2A,0xE9]) signature = idata.tostring() #ret= data.find(data,signature,4) ret= self.SearchString(data,signature,5) #print "Signature " ,ret self.obsfucated = ret return ret def initalizesections(self): for section in self.pe.sections: if section.Name.startswith(".text"): textsection = section elif section.Name.startswith(".rdata"): datasection = section self.codelen = len(textsection.data) for x in range(len(textsection.data)): c = textsection.data[x] self.emu.set_memory(self.codebase + x, int(ord(c)), size=1) self.datalen = len(datasection.data) for x in range(len(datasection.data)): c = datasection.data[x] self.emu.set_memory(self.database + x, int(ord(c)), size=1) self.emu.set_stack_argument(0x8, 0x10, name="arg_0") self.emu.set_stack_argument(0xc, 0x20, name="arg_4") def checkmalware(self) : if(self.obsfucated) : self.deobsbytes =abs(self.bytesobs-(self.emu.get_register("EIP")-self.codebase)) #print "diff " , diff exec_code =self.emu.get_memory(self.emu.get_register("EIP") ,self.deobsbytes ) #print hex(ord(exec_code[0])) else : self.initalizesections() exec_code = self.emu.get_memory(self.codebase ,self.codelen ) idata = array.array('B', [0x68,0x2A,0x6A,0x01,0x6A,0x00,0xE8]) signature = idata.tostring() ret = self.SearchString(exec_code,signature,2) if ret : print "bad code " else: print "good code " def deobsfucate(self) : self.initalizesections() ep = self.pe.OPTIONAL_HEADER.AddressOfEntryPoint ep_ava = ep+self.pe.OPTIONAL_HEADER.ImageBase data = self.pe.get_memory_mapped_image()[ep:ep+40] offset=0 self.emu.set_register("EIP", self.entrypoint) self.emu.set_register("ECX", 0x00000000) self.emu.set_register("BL", 0x00) self.emu.set_register("DL", 0x00) instruction = "NOP" while not instruction.startswith("loop") : #offset < len(data): i = pydasm.get_instruction(data[offset:], pydasm.MODE_32) instruction=pydasm.get_instruction_string(i, pydasm.FORMAT_INTEL, ep_ava+offset) offset+=i.length print instruction #c = raw_input("emulator> ") while 1 : value1 = self.emu.get_register("ECX") value2 = self.emu.get_register("BL") value3 = self.emu.get_register("DL") if(value1 != 0 and value2 !=0 and value3 != 0): break; self.emu.execute() self.bytesobs = value1 byte_obs = value1 while value1 !=0: self.emu.execute() value1 =self.emu.get_register("ECX") i = pydasm.get_instruction(data[offset:], pydasm.MODE_32) instruction=pydasm.get_instruction_string(i, pydasm.FORMAT_INTEL, ep_ava+offset) print instruction offset+=i.length self.emu.execute() #offset+=((ep_ava+offset)- emu.get_register("EIP")) nxt_offset = self.emu.get_register("EIP")- (ep_ava+offset) offset+=nxt_offset instruction = "nop" while not instruction.startswith("jmp") : # offset < len(data) i = pydasm.get_instruction(data[offset:], pydasm.MODE_32) instruction=pydasm.get_instruction_string(i, pydasm.FORMAT_INTEL, ep_ava+offset) self.emu.execute() offset+=i.length print instruction #c = raw_input("emulator> ") ret=instruction.find("0x") jmp_address= instruction[ret+2:]
def findObsSignature(filename): if filename: pe = pefile.PE(filename) else: print "[!] Blank filename specified" sys.exit(2) imagebase = pe.OPTIONAL_HEADER.ImageBase codebase = pe.OPTIONAL_HEADER.ImageBase + pe.OPTIONAL_HEADER.BaseOfCode database = pe.OPTIONAL_HEADER.ImageBase + pe.OPTIONAL_HEADER.BaseOfData entrypoint = pe.OPTIONAL_HEADER.ImageBase + pe.OPTIONAL_HEADER.AddressOfEntryPoint print "[*] Image Base Addr: 0x%08x" % (imagebase) print "[*] Code Base Addr: 0x%08x" % (codebase) print "[*] Data Base Addr: 0x%08x" % (database) print "[*] Entry Point Addr: 0x%08x\n" % (entrypoint) ep = pe.OPTIONAL_HEADER.AddressOfEntryPoint ep_ava = ep+pe.OPTIONAL_HEADER.ImageBase data = pe.get_memory_mapped_image()[ep:ep+40] offset=0 #idata = array.array('B', [0xb9,0x5a,0x01,0x00,0x00,0x43,0x4b,0xbe,0x00,0x10,0x40,0x00,0xb3,0xa6,0x8a,0x16,0x32,0xd3]) idata = array.array('B', [0xB9,0x2A,0xBE,0x2A,0xB3,0x2A,0x8A,0x16,0x32,0xD3,0x8A,0x1E,0x88,0x16,0x46,0xE2,0x2A,0xE9]) signature = idata.tostring() #ret= data.find(data,signature,4) ret= SearchString(data,signature,5) print "Signature " ,ret emu = PEPyEmu() #emu.debug(1) for section in pe.sections: if section.Name.startswith(".text"): textsection = section elif section.Name.startswith(".rdata"): datasection = section for x in range(len(textsection.data)): c = textsection.data[x] emu.set_memory(codebase + x, int(ord(c)), size=1) for x in range(len(datasection.data)): c = datasection.data[x] emu.set_memory(database + x, int(ord(c)), size=1) ep = pe.OPTIONAL_HEADER.AddressOfEntryPoint ep_ava = ep+pe.OPTIONAL_HEADER.ImageBase data = pe.get_memory_mapped_image()[ep:ep+40] emu.set_stack_argument(0x8, 0x10, name="arg_0") emu.set_stack_argument(0xc, 0x20, name="arg_4") if (ret): offset=0 emu.set_register("EIP", entrypoint) emu.set_register("ECX", 0x00000000) emu.set_register("BL", 0x00) emu.set_register("DL", 0x00) instruction = "NOP" while not instruction.startswith("loop") : #offset < len(data): i = pydasm.get_instruction(data[offset:], pydasm.MODE_32) instruction=pydasm.get_instruction_string(i, pydasm.FORMAT_INTEL, ep_ava+offset) offset+=i.length print instruction #c = raw_input("emulator> ") while 1 : value1 = emu.get_register("ECX") value2 = emu.get_register("BL") value3 = emu.get_register("DL") if(value1 != 0 and value2 !=0 and value3 != 0): break; emu.execute() byte_obs = value1 while value1 !=0: emu.execute() value1 =emu.get_register("ECX") i = pydasm.get_instruction(data[offset:], pydasm.MODE_32) instruction=pydasm.get_instruction_string(i, pydasm.FORMAT_INTEL, ep_ava+offset) print instruction offset+=i.length emu.execute() #offset+=((ep_ava+offset)- emu.get_register("EIP")) print "after jump" resu = emu.get_register("EIP")- (ep_ava+offset) print " %x " % resu print "%x" % emu.get_register("EIP") offset+=resu instruction = "nop" while not instruction.startswith("jmp") : #offset < len(data): if ord(data[0]) == 0x90: print "nop" i = pydasm.get_instruction(data[offset:], pydasm.MODE_32) print "i " , i instruction=pydasm.get_instruction_string(i, pydasm.FORMAT_INTEL, ep_ava+offset) emu.execute() offset+=i.length print instruction #c = raw_input("emulator> ") ret=instruction.find("0x") jmp_address= instruction[ret+2:] #print "ret " , ret, hex(jmp_address) #emu.execute() #emu.execute() #print " I am here1 " emu.dump_regs() diff =abs(byte_obs-(emu.get_register("EIP")-codebase)) print "diff " , diff exec_code =emu.get_memory(emu.get_register("EIP") ,diff ) print hex(ord(exec_code[0])) idata = array.array('B', [0x68,0x2A,0x6A,0x01,0x6A,0x00,0xE8]) signature = idata.tostring() ret = SearchString(exec_code,signature,2) if ret : print "bad code " else: print "good code "
import pydasm from PyCPU import * from PyDebug import * from PyEmu import PEPyEmu rawinstruction = "\x66\x89\x45\xF6" instruction = pydasm.get_instruction(rawinstruction, pydasm.MODE_32) pyinstruction = PyInstruction(instruction) disasm = pydasm.get_instruction_string(instruction, pydasm.FORMAT_INTEL, 0).rstrip(" ") #DebugInstruction(pyinstruction) emu = PEPyEmu() emu.cpu.set_debug(1) emu.set_register("EDX", 0xfe) print "EAX: 0x%08x EDX: 0x%08x" % (emu.cpu.EAX, emu.cpu.EDX) print "Executing [%s]..." % disasm, # An oversight in pydasm mnemonic parsing pyinstruction.mnemonic = pyinstruction.mnemonic.split() if pyinstruction.mnemonic[0] in ["rep", "repe", "repne", "lock"]: pyinstruction.mnemonic = pyinstruction.mnemonic[1] else: pyinstruction.mnemonic = pyinstruction.mnemonic[0] # Check if we support this instruction if pyinstruction.mnemonic in emu.cpu.supported_instructions: # Execute! if not emu.cpu.supported_instructions[pyinstruction.mnemonic](pyinstruction):