class ReilEmulatorTaintTests(unittest.TestCase): def setUp(self): self._arch_info = X86ArchitectureInformation(ARCH_X86_MODE_32) self._emulator = ReilEmulator(self._arch_info) self._asm_parser = X86Parser() self._translator = X86Translator() def test_arithmetic(self): asm_instrs = self._asm_parser.parse("add eax, ebx") self.__set_address(0xdeadbeef, [asm_instrs]) reil_instrs = self._translator.translate(asm_instrs) regs_initial = { "eax": 0x1, "ebx": 0x2, } self._emulator.set_register_taint("ebx", True) regs_final, _ = self._emulator.execute_lite(reil_instrs, context=regs_initial) self.assertEqual(self._emulator.get_register_taint("eax"), True) def test_store_mem_1(self): asm_instrs = self._asm_parser.parse("mov [eax], ebx") self.__set_address(0xdeadbeef, [asm_instrs]) reil_instrs = self._translator.translate(asm_instrs) regs_initial = { "eax": 0xcafecafe, "ebx": 0x2, } self._emulator.set_register_taint("ebx", True) regs_final, _ = self._emulator.execute_lite(reil_instrs, context=regs_initial) self.assertEqual( self._emulator.get_memory_taint(regs_initial['eax'], 4), True) def test_store_mem_2(self): asm_instrs = self._asm_parser.parse("mov [eax], ebx") self.__set_address(0xdeadbeef, [asm_instrs]) reil_instrs = self._translator.translate(asm_instrs) regs_initial = { "eax": 0xcafecafe, "ebx": 0x2, } self._emulator.set_register_taint("eax", True) regs_final, _ = self._emulator.execute_lite(reil_instrs, context=regs_initial) self.assertEqual( self._emulator.get_memory_taint(regs_initial['eax'], 4), False) def test_load_mem_1(self): asm_instrs = self._asm_parser.parse("mov eax, [ebx]") self.__set_address(0xdeadbeef, [asm_instrs]) reil_instrs = self._translator.translate(asm_instrs) regs_initial = { "eax": 0x2, "ebx": 0xcafecafe, } self._emulator.set_memory_taint(regs_initial["ebx"], 4, True) regs_final, _ = self._emulator.execute_lite(reil_instrs, context=regs_initial) self.assertEqual(self._emulator.get_register_taint("eax"), True) def __set_address(self, address, asm_instrs): addr = address for asm_instr in asm_instrs: asm_instr.address = addr addr += 1
class ReilEmulatorTests(unittest.TestCase): def setUp(self): self._arch_info = X86ArchitectureInformation(ARCH_X86_MODE_32) self._emulator = ReilEmulator(self._arch_info.address_size) self._emulator.set_arch_registers(self._arch_info.registers_gp_all) self._emulator.set_arch_registers_size(self._arch_info.registers_size) self._emulator.set_reg_access_mapper(self._arch_info.alias_mapper) self._asm_parser = X86Parser() self._translator = X86Translator() def test_add(self): asm_instrs = self._asm_parser.parse("add eax, ebx") self.__set_address(0xdeadbeef, [asm_instrs]) reil_instrs = self._translator.translate(asm_instrs) regs_initial = { "eax" : 0x1, "ebx" : 0x2, } regs_final, _ = self._emulator.execute_lite( reil_instrs, context=regs_initial ) self.assertEqual(regs_final["eax"], 0x3) self.assertEqual(regs_final["ebx"], 0x2) def test_loop(self): # 0x08048060 : b8 00 00 00 00 mov eax,0x0 # 0x08048065 : bb 0a 00 00 00 mov ebx,0xa # 0x0804806a : 83 c0 01 add eax,0x1 # 0x0804806d : 83 eb 01 sub ebx,0x1 # 0x08048070 : 83 fb 00 cmp ebx,0x0 # 0x08048073 : 75 f5 jne 0x0804806a asm_instrs_str = [(0x08048060, "mov eax,0x0", 5)] asm_instrs_str += [(0x08048065, "mov ebx,0xa", 5)] asm_instrs_str += [(0x0804806a, "add eax,0x1", 3)] asm_instrs_str += [(0x0804806d, "sub ebx,0x1", 3)] asm_instrs_str += [(0x08048070, "cmp ebx,0x0", 3)] asm_instrs_str += [(0x08048073, "jne 0x0804806a", 2)] asm_instrs = [] for addr, asm, size in asm_instrs_str: asm_instr = self._asm_parser.parse(asm) asm_instr.address = addr asm_instr.size = size asm_instrs.append(asm_instr) reil_instrs = [self._translator.translate(instr) for instr in asm_instrs] regs_final, _ = self._emulator.execute( reil_instrs, 0x08048060 << 8, context=[] ) self.assertEqual(regs_final["eax"], 0xa) self.assertEqual(regs_final["ebx"], 0x0) def test_mov(self): asm_instrs = [self._asm_parser.parse("mov eax, 0xdeadbeef")] asm_instrs += [self._asm_parser.parse("mov al, 0x12")] asm_instrs += [self._asm_parser.parse("mov ah, 0x34")] self.__set_address(0xdeadbeef, asm_instrs) reil_instrs = self._translator.translate(asm_instrs[0]) reil_instrs += self._translator.translate(asm_instrs[1]) reil_instrs += self._translator.translate(asm_instrs[2]) regs_initial = { "eax" : 0xffffffff, } regs_final, _ = self._emulator.execute_lite(reil_instrs, context=regs_initial) self.assertEqual(regs_final["eax"], 0xdead3412) def __set_address(self, address, asm_instrs): addr = address for asm_instr in asm_instrs: asm_instr.address = addr addr += 1
class ReilEmulatorTests(unittest.TestCase): def setUp(self): self._arch_info = X86ArchitectureInformation(ARCH_X86_MODE_32) self._emulator = ReilEmulator(self._arch_info) self._asm_parser = X86Parser() self._reil_parser = ReilParser() self._translator = X86Translator() def test_add(self): asm_instrs = self._asm_parser.parse("add eax, ebx") self.__set_address(0xdeadbeef, [asm_instrs]) reil_instrs = self._translator.translate(asm_instrs) regs_initial = { "eax": 0x1, "ebx": 0x2, } regs_final, _ = self._emulator.execute_lite(reil_instrs, context=regs_initial) self.assertEqual(regs_final["eax"], 0x3) self.assertEqual(regs_final["ebx"], 0x2) def test_loop(self): # 0x08048060 : b8 00 00 00 00 mov eax,0x0 # 0x08048065 : bb 0a 00 00 00 mov ebx,0xa # 0x0804806a : 83 c0 01 add eax,0x1 # 0x0804806d : 83 eb 01 sub ebx,0x1 # 0x08048070 : 83 fb 00 cmp ebx,0x0 # 0x08048073 : 75 f5 jne 0x0804806a asm_instrs_str = [(0x08048060, "mov eax,0x0", 5)] asm_instrs_str += [(0x08048065, "mov ebx,0xa", 5)] asm_instrs_str += [(0x0804806a, "add eax,0x1", 3)] asm_instrs_str += [(0x0804806d, "sub ebx,0x1", 3)] asm_instrs_str += [(0x08048070, "cmp ebx,0x0", 3)] asm_instrs_str += [(0x08048073, "jne 0x0804806a", 2)] asm_instrs = [] for addr, asm, size in asm_instrs_str: asm_instr = self._asm_parser.parse(asm) asm_instr.address = addr asm_instr.size = size asm_instrs.append(asm_instr) reil_instrs = self.__translate(asm_instrs) regs_final, _ = self._emulator.execute(reil_instrs, start=0x08048060 << 8) self.assertEqual(regs_final["eax"], 0xa) self.assertEqual(regs_final["ebx"], 0x0) def test_mov(self): asm_instrs = [self._asm_parser.parse("mov eax, 0xdeadbeef")] asm_instrs += [self._asm_parser.parse("mov al, 0x12")] asm_instrs += [self._asm_parser.parse("mov ah, 0x34")] self.__set_address(0xdeadbeef, asm_instrs) reil_instrs = self._translator.translate(asm_instrs[0]) reil_instrs += self._translator.translate(asm_instrs[1]) reil_instrs += self._translator.translate(asm_instrs[2]) regs_initial = { "eax": 0xffffffff, } regs_final, _ = self._emulator.execute_lite(reil_instrs, context=regs_initial) self.assertEqual(regs_final["eax"], 0xdead3412) def test_pre_hanlder(self): def pre_hanlder(emulator, instruction, parameter): paramter.append(True) asm = ["mov eax, ebx"] x86_instrs = map(self._asm_parser.parse, asm) self.__set_address(0xdeadbeef, x86_instrs) reil_instrs = map(self._translator.translate, x86_instrs) paramter = [] self._emulator.set_instruction_pre_handler(pre_hanlder, paramter) reil_ctx_out, reil_mem_out = self._emulator.execute_lite( reil_instrs[0]) self.assertTrue(len(paramter) > 0) def test_post_hanlder(self): def post_hanlder(emulator, instruction, parameter): paramter.append(True) asm = ["mov eax, ebx"] x86_instrs = map(self._asm_parser.parse, asm) self.__set_address(0xdeadbeef, x86_instrs) reil_instrs = map(self._translator.translate, x86_instrs) paramter = [] self._emulator.set_instruction_post_handler(post_hanlder, paramter) reil_ctx_out, reil_mem_out = self._emulator.execute_lite( reil_instrs[0]) self.assertTrue(len(paramter) > 0) def test_zero_division_error_1(self): asm_instrs = [self._asm_parser.parse("div ebx")] self.__set_address(0xdeadbeef, asm_instrs) reil_instrs = self._translator.translate(asm_instrs[0]) regs_initial = { "eax": 0x2, "edx": 0x2, "ebx": 0x0, } self.assertRaises(ReilCpuZeroDivisionError, self._emulator.execute_lite, reil_instrs, context=regs_initial) def test_zero_division_error_2(self): instrs = ["mod [DWORD eax, DWORD ebx, DWORD t0]"] reil_instrs = self._reil_parser.parse(instrs) reil_instrs[0].address = 0xdeadbeef00 regs_initial = { "eax": 0x2, "ebx": 0x0, } self.assertRaises(ReilCpuZeroDivisionError, self._emulator.execute_lite, reil_instrs, context=regs_initial) def test_invalid_address_error_1(self): asm_instrs = [self._asm_parser.parse("jmp eax")] self.__set_address(0xdeadbeef, asm_instrs) reil_instrs = self.__translate(asm_instrs) regs_initial = { "eax": 0xffffffff, } self.assertRaises(ReilCpuInvalidAddressError, self._emulator.execute, reil_instrs, start=0xdeadbeef << 8, registers=regs_initial) def test_invalid_address_error_2(self): asm_instrs = [self._asm_parser.parse("mov eax, 0xdeadbeef")] self.__set_address(0xdeadbeef, asm_instrs) reil_instrs = self.__translate(asm_instrs) regs_initial = { "eax": 0xffffffff, } self.assertRaises(ReilCpuInvalidAddressError, self._emulator.execute, reil_instrs, start=0xdeadbef0 << 8, registers=regs_initial) # Auxiliary methods # ======================================================================== # def __set_address(self, address, asm_instrs): addr = address for asm_instr in asm_instrs: asm_instr.address = addr addr += 1 def __translate(self, asm_instrs): instr_container = ReilContainer() asm_instr_last = None instr_seq_prev = None for asm_instr in asm_instrs: instr_seq = ReilSequence() for reil_instr in self._translator.translate(asm_instr): instr_seq.append(reil_instr) if instr_seq_prev: instr_seq_prev.next_sequence_address = instr_seq.address instr_container.add(instr_seq) instr_seq_prev = instr_seq if instr_seq_prev: if asm_instr_last: instr_seq_prev.next_sequence_address = ( asm_instr_last.address + asm_instr_last.size) << 8 # instr_container.dump() return instr_container
class ReilEmulatorTaintTests(unittest.TestCase): def setUp(self): self._arch_info = X86ArchitectureInformation(ARCH_X86_MODE_32) self._emulator = ReilEmulator(self._arch_info) self._asm_parser = X86Parser() self._translator = X86Translator() def test_arithmetic(self): asm_instrs = self._asm_parser.parse("add eax, ebx") self.__set_address(0xdeadbeef, [asm_instrs]) reil_instrs = self._translator.translate(asm_instrs) regs_initial = { "eax" : 0x1, "ebx" : 0x2, } self._emulator.set_register_taint("ebx", True) regs_final, _ = self._emulator.execute_lite( reil_instrs, context=regs_initial ) self.assertEqual(self._emulator.get_register_taint("eax"), True) def test_store_mem_1(self): asm_instrs = self._asm_parser.parse("mov [eax], ebx") self.__set_address(0xdeadbeef, [asm_instrs]) reil_instrs = self._translator.translate(asm_instrs) regs_initial = { "eax" : 0xcafecafe, "ebx" : 0x2, } self._emulator.set_register_taint("ebx", True) regs_final, _ = self._emulator.execute_lite( reil_instrs, context=regs_initial ) self.assertEqual(self._emulator.get_memory_taint(regs_initial['eax'], 4), True) def test_store_mem_2(self): asm_instrs = self._asm_parser.parse("mov [eax], ebx") self.__set_address(0xdeadbeef, [asm_instrs]) reil_instrs = self._translator.translate(asm_instrs) regs_initial = { "eax" : 0xcafecafe, "ebx" : 0x2, } self._emulator.set_register_taint("eax", True) regs_final, _ = self._emulator.execute_lite( reil_instrs, context=regs_initial ) self.assertEqual(self._emulator.get_memory_taint(regs_initial['eax'], 4), False) def test_load_mem_1(self): asm_instrs = self._asm_parser.parse("mov eax, [ebx]") self.__set_address(0xdeadbeef, [asm_instrs]) reil_instrs = self._translator.translate(asm_instrs) regs_initial = { "eax" : 0x2, "ebx" : 0xcafecafe, } self._emulator.set_memory_taint(regs_initial["ebx"], 4, True) regs_final, _ = self._emulator.execute_lite( reil_instrs, context=regs_initial ) self.assertEqual(self._emulator.get_register_taint("eax"), True) def __set_address(self, address, asm_instrs): addr = address for asm_instr in asm_instrs: asm_instr.address = addr addr += 1
class ReilEmulatorTests(unittest.TestCase): def setUp(self): self._arch_info = X86ArchitectureInformation(ARCH_X86_MODE_32) self._emulator = ReilEmulator(self._arch_info) self._asm_parser = X86Parser() self._reil_parser = ReilParser() self._translator = X86Translator() def test_add(self): asm_instrs = self._asm_parser.parse("add eax, ebx") self.__set_address(0xdeadbeef, [asm_instrs]) reil_instrs = self._translator.translate(asm_instrs) regs_initial = { "eax" : 0x1, "ebx" : 0x2, } regs_final, _ = self._emulator.execute_lite( reil_instrs, context=regs_initial ) self.assertEqual(regs_final["eax"], 0x3) self.assertEqual(regs_final["ebx"], 0x2) def test_loop(self): # 0x08048060 : b8 00 00 00 00 mov eax,0x0 # 0x08048065 : bb 0a 00 00 00 mov ebx,0xa # 0x0804806a : 83 c0 01 add eax,0x1 # 0x0804806d : 83 eb 01 sub ebx,0x1 # 0x08048070 : 83 fb 00 cmp ebx,0x0 # 0x08048073 : 75 f5 jne 0x0804806a asm_instrs_str = [(0x08048060, "mov eax,0x0", 5)] asm_instrs_str += [(0x08048065, "mov ebx,0xa", 5)] asm_instrs_str += [(0x0804806a, "add eax,0x1", 3)] asm_instrs_str += [(0x0804806d, "sub ebx,0x1", 3)] asm_instrs_str += [(0x08048070, "cmp ebx,0x0", 3)] asm_instrs_str += [(0x08048073, "jne 0x0804806a", 2)] asm_instrs = [] for addr, asm, size in asm_instrs_str: asm_instr = self._asm_parser.parse(asm) asm_instr.address = addr asm_instr.size = size asm_instrs.append(asm_instr) reil_instrs = self.__translate(asm_instrs) regs_final, _ = self._emulator.execute( reil_instrs, start=0x08048060 << 8 ) self.assertEqual(regs_final["eax"], 0xa) self.assertEqual(regs_final["ebx"], 0x0) def test_mov(self): asm_instrs = [self._asm_parser.parse("mov eax, 0xdeadbeef")] asm_instrs += [self._asm_parser.parse("mov al, 0x12")] asm_instrs += [self._asm_parser.parse("mov ah, 0x34")] self.__set_address(0xdeadbeef, asm_instrs) reil_instrs = self._translator.translate(asm_instrs[0]) reil_instrs += self._translator.translate(asm_instrs[1]) reil_instrs += self._translator.translate(asm_instrs[2]) regs_initial = { "eax" : 0xffffffff, } regs_final, _ = self._emulator.execute_lite(reil_instrs, context=regs_initial) self.assertEqual(regs_final["eax"], 0xdead3412) def test_pre_hanlder(self): def pre_hanlder(emulator, instruction, parameter): paramter.append(True) asm = ["mov eax, ebx"] x86_instrs = map(self._asm_parser.parse, asm) self.__set_address(0xdeadbeef, x86_instrs) reil_instrs = map(self._translator.translate, x86_instrs) paramter = [] self._emulator.set_instruction_pre_handler(pre_hanlder, paramter) reil_ctx_out, reil_mem_out = self._emulator.execute_lite( reil_instrs[0] ) self.assertTrue(len(paramter) > 0) def test_post_hanlder(self): def post_hanlder(emulator, instruction, parameter): paramter.append(True) asm = ["mov eax, ebx"] x86_instrs = map(self._asm_parser.parse, asm) self.__set_address(0xdeadbeef, x86_instrs) reil_instrs = map(self._translator.translate, x86_instrs) paramter = [] self._emulator.set_instruction_post_handler(post_hanlder, paramter) reil_ctx_out, reil_mem_out = self._emulator.execute_lite( reil_instrs[0] ) self.assertTrue(len(paramter) > 0) def test_zero_division_error_1(self): asm_instrs = [self._asm_parser.parse("div ebx")] self.__set_address(0xdeadbeef, asm_instrs) reil_instrs = self._translator.translate(asm_instrs[0]) regs_initial = { "eax" : 0x2, "edx" : 0x2, "ebx" : 0x0, } self.assertRaises(ReilCpuZeroDivisionError, self._emulator.execute_lite, reil_instrs, context=regs_initial) def test_zero_division_error_2(self): instrs = ["mod [DWORD eax, DWORD ebx, DWORD t0]"] reil_instrs = self._reil_parser.parse(instrs) regs_initial = { "eax" : 0x2, "ebx" : 0x0, } self.assertRaises(ReilCpuZeroDivisionError, self._emulator.execute_lite, reil_instrs, context=regs_initial) def test_invalid_address_error_1(self): asm_instrs = [self._asm_parser.parse("jmp eax")] self.__set_address(0xdeadbeef, asm_instrs) reil_instrs = self.__translate(asm_instrs) regs_initial = { "eax" : 0xffffffff, } self.assertRaises(ReilCpuInvalidAddressError, self._emulator.execute, reil_instrs, start=0xdeadbeef << 8, registers=regs_initial) def test_invalid_address_error_2(self): asm_instrs = [self._asm_parser.parse("mov eax, 0xdeadbeef")] self.__set_address(0xdeadbeef, asm_instrs) reil_instrs = self.__translate(asm_instrs) regs_initial = { "eax" : 0xffffffff, } self.assertRaises(ReilCpuInvalidAddressError, self._emulator.execute, reil_instrs, start=0xdeadbef0 << 8, registers=regs_initial) # Auxiliary methods # ======================================================================== # def __set_address(self, address, asm_instrs): addr = address for asm_instr in asm_instrs: asm_instr.address = addr addr += 1 def __translate(self, asm_instrs): instr_container = ReilContainer() asm_instr_last = None instr_seq_prev = None for asm_instr in asm_instrs: instr_seq = ReilSequence() for reil_instr in self._translator.translate(asm_instr): instr_seq.append(reil_instr) if instr_seq_prev: instr_seq_prev.next_sequence_address = instr_seq.address instr_container.add(instr_seq) instr_seq_prev = instr_seq if instr_seq_prev: if asm_instr_last: instr_seq_prev.next_sequence_address = (asm_instr_last.address + asm_instr_last.size) << 8 # instr_container.dump() return instr_container
class GadgetTools(): def __init__ (self, binary): self.elf = elffile.ELFFile(binary) if self.elf.elfclass == 32: self.arch_info = X86ArchitectureInformation(ARCH_X86_MODE_32) if self.elf.elfclass == 64: self.arch_info = X86ArchitectureInformation(ARCH_X86_MODE_64) self.emulator = ReilEmulator(self.arch_info.address_size) self.emulator.set_arch_registers(self.arch_info.registers_gp) self.emulator.set_arch_registers_size(self.arch_info.register_size) self.emulator.set_reg_access_mapper(self.arch_info.register_access_mapper()) self.classifier = GadgetClassifier(self.emulator, self.arch_info) self.smt_solver = SmtSolver() self.smt_translator = SmtTranslator(self.smt_solver, self.arch_info.address_size) self.smt_translator.set_reg_access_mapper(self.arch_info.register_access_mapper()) self.smt_translator.set_arch_registers_size(self.arch_info.register_size) self.code_analyzer = CodeAnalyzer(self.smt_solver, self.smt_translator) self.gadgets = {} self.classified_gadgets = {} self.regset = RegSet(self) self.ccf = CCFlag(self) self.ams = ArithmeticStore(self) self.memstr = MemoryStore(self) self.reil_translator = X86Translator(architecture_mode=self.arch_info.architecture_mode, translation_mode=FULL_TRANSLATION) def find_gadgets(self, max_instr=10, max_bytes=15): logging.info('searching gadgets in binary..') for s in self.elf.iter_sections(): if (s.header.sh_type == 'SHT_PROGBITS') and (s.header.sh_flags & 0x4): sz = s.header.sh_size base = s.header.sh_addr mem = Memory(lambda x, y : s.data()[x - base], None) gfinder = GadgetFinder(X86Disassembler(architecture_mode=self.arch_info.architecture_mode), mem, self.reil_translator) logging.info("searching gadgets in section " + s.name + "...") for g in gfinder.find(base, base + sz - 1, max_instr, max_bytes): ret = g.instrs[-1].asm_instr if not isinstance(ret, Ret): continue if len(ret.operands) > 0 and ret.operands[0].immediate > 0x10: continue self.gadgets[g.address] = g logging.info("found {0} gadgets".format(len(self.gadgets))) def classify_gadgets(self): #setting 0 to cf flags to avoid impossible random value invalidates results rflags = self.classifier.set_reg_init({'cf': 0}) for g in self.gadgets.itervalues(): tgs = self.classifier.classify(g) for tg in tgs: if tg.type not in self.classified_gadgets: self.classified_gadgets[tg.type] = [] self.classified_gadgets[tg.type].append(tg) def find_reg_set_gadgets(self): self.regset.add(self.gadgets.itervalues()) def read_carrier_flag(self, g): self.emulator.reset() regs_init = utils.make_random_regs_context(self.arch_info) self.emulator.execute_lite(g.get_ir_instrs(), regs_init) return 'eflags' in self.emulator.registers def find_arithmetic_mem_set_gadgets(self): self.ams.add(self.classified_gadgets[GadgetType.ArithmeticStore]) def get_stack_slide_chunk(self, slide): #TODO not use only pop gadgets and chain more slide if we wan't longer slide return self.regset.get_slide_stack_chunk(slide) def get_ret_func_chunk(self, args, address): """Return a chainable chunk that return to address and set up args or registers as if a function was called with args. Args: args (list): the list of args to setup as function arguments address (int): the address where to return """ if self.arch_info.architecture_size == 64: if len(args) > 6: raise BaseException("chunk for calling a function whit more of six args isn't implemented") args_regs = ['rdi', 'rsi', 'rdx', 'rcx', 'r8', 'r9'] regs_values = {args_regs[i] : a for i, a in enumerate(args)} regs_c = self.regset.get_chunk(regs_values) ret_c = PayloadChunk("", self.arch_info, address) return PayloadChunk.get_general_chunk([regs_c, ret_c]) if self.arch_info.architecture_size == 32: slide_c = self.regset.get_slide_stack_chunk(len(args) * 4) print slide_c ret_c = RetToAddress32(args, address, self.arch_info) print ret_c return PayloadChunk.get_general_chunk([ret_c, slide_c]) def get_mem_set_libc_read_chunk(self, location, fd, size, read_address): if self.arch_info.architecture_size == 64: print "TO IMPLEMENT" return if self.arch_info.architecture_size == 32: slide_chunk = self.regset.get_slide_stack_chunk(4 * 3) pl_chunk = MemSetLibcRead32(location, fd, size, read_address, self.arch_info) return PayloadChunk.get_general_chunk([pl_chunk, slide_chunk]) def build_mem_add(self, location, offset, size, mem_pre = None): return self.ams.get_memory_add_chunk(location, offset, size, mem_pre) def check_mem_side_effects_and_stack_end(self, g, regs_init, location, size): stack_reg = 'esp' if (self.arch_info.architecture_size == 64): stack_reg = 'rsp' stack_base = 0x50 regs_init[stack_reg] = stack_base #TODO fix try and execute (zero div in mv where finding ccf) try: cregs, mem_final = self.emulator.execute_lite(g.get_ir_instrs(), regs_init) except: pass mem_side_effects = [] for addr in mem_final.get_addresses(): if addr in [location + i for i in xrange(size/8)]: continue sp, vp = mem_final.try_read_prev(addr, 8) sn, vn = mem_final.try_read(addr, 8) #quick fix. We should disting between reading from stack and read side effetcs if sn and not sp and (addr >= stack_base - abs(stack_base - cregs[stack_reg]) and addr <= stack_base + abs(stack_base - cregs[stack_reg])): continue if (sp and sn and vp != vn) or (sn and not sp) : mem_side_effects.append(addr) return mem_side_effects, cregs[stack_reg] - stack_base - self.arch_info.address_size / 8 def find_memory_store(self): self.mem_set_gadgets = {} if not GadgetType.StoreMemory in self.classified_gadgets: return self.memstr.add(self.classified_gadgets[GadgetType.StoreMemory]) def find_ccfs(self): self.ccf.add(self.gadgets.values())
class ReilEmulatorTests(unittest.TestCase): def setUp(self): self._arch_info = X86ArchitectureInformation(ARCH_X86_MODE_32) self._emulator = ReilEmulator(self._arch_info.address_size) self._emulator.set_arch_registers(self._arch_info.registers_gp_all) self._emulator.set_arch_registers_size(self._arch_info.registers_size) self._emulator.set_reg_access_mapper(self._arch_info.alias_mapper) self._asm_parser = X86Parser() self._translator = X86Translator() def test_add(self): asm_instrs = self._asm_parser.parse("add eax, ebx") self.__set_address(0xdeadbeef, [asm_instrs]) reil_instrs = self._translator.translate(asm_instrs) regs_initial = { "eax": 0x1, "ebx": 0x2, } regs_final, _ = self._emulator.execute_lite(reil_instrs, context=regs_initial) self.assertEqual(regs_final["eax"], 0x3) self.assertEqual(regs_final["ebx"], 0x2) def test_loop(self): # 0x08048060 : b8 00 00 00 00 mov eax,0x0 # 0x08048065 : bb 0a 00 00 00 mov ebx,0xa # 0x0804806a : 83 c0 01 add eax,0x1 # 0x0804806d : 83 eb 01 sub ebx,0x1 # 0x08048070 : 83 fb 00 cmp ebx,0x0 # 0x08048073 : 75 f5 jne 0x0804806a asm_instrs_str = [(0x08048060, "mov eax,0x0", 5)] asm_instrs_str += [(0x08048065, "mov ebx,0xa", 5)] asm_instrs_str += [(0x0804806a, "add eax,0x1", 3)] asm_instrs_str += [(0x0804806d, "sub ebx,0x1", 3)] asm_instrs_str += [(0x08048070, "cmp ebx,0x0", 3)] asm_instrs_str += [(0x08048073, "jne 0x0804806a", 2)] asm_instrs = [] for addr, asm, size in asm_instrs_str: asm_instr = self._asm_parser.parse(asm) asm_instr.address = addr asm_instr.size = size asm_instrs.append(asm_instr) reil_instrs = [ self._translator.translate(instr) for instr in asm_instrs ] regs_final, _ = self._emulator.execute(reil_instrs, 0x08048060 << 8, context=[]) self.assertEqual(regs_final["eax"], 0xa) self.assertEqual(regs_final["ebx"], 0x0) def test_mov(self): asm_instrs = [self._asm_parser.parse("mov eax, 0xdeadbeef")] asm_instrs += [self._asm_parser.parse("mov al, 0x12")] asm_instrs += [self._asm_parser.parse("mov ah, 0x34")] self.__set_address(0xdeadbeef, asm_instrs) reil_instrs = self._translator.translate(asm_instrs[0]) reil_instrs += self._translator.translate(asm_instrs[1]) reil_instrs += self._translator.translate(asm_instrs[2]) regs_initial = { "eax": 0xffffffff, } regs_final, _ = self._emulator.execute_lite(reil_instrs, context=regs_initial) self.assertEqual(regs_final["eax"], 0xdead3412) def __set_address(self, address, asm_instrs): addr = address for asm_instr in asm_instrs: asm_instr.address = addr addr += 1