def read_closure(settings, worklist, heaps, pointer): try: info_pointer = ptrutil.dereference(settings, pointer, heaps, []).untagged assert isinstance(info_pointer, StaticValue) info_address = info_pointer.value info_type = info.read_closure_type(settings, info_address) if settings.opts.verbose: print(" Type:", info_type) if info_type[:11] == 'constructor': num_ptrs = ptrutil.read_half_word(settings, settings.text_offset + info_address - settings.rt.halfword.size*4) num_non_ptrs = ptrutil.read_half_word(settings, settings.text_offset + info_address - settings.rt.halfword.size*3) args = [] arg_pointer = ptrutil.make_tagged(settings, pointer)._replace(tag = 0) for i in range(num_ptrs + num_non_ptrs): arg_pointer = ptrutil.pointer_offset(settings, arg_pointer, settings.rt.word.size); args.append(ptrutil.dereference(settings, arg_pointer.untagged, heaps, [])) arg_pattern = 'p' * num_ptrs + 'n' * num_non_ptrs for arg in args[:num_ptrs]: worklist.append(ClosureWork(heaps = heaps, pointer = arg.untagged)) return Apply(func = Pointer(info_pointer), func_type = 'constructor', args = interp_args(args, arg_pattern), pattern = arg_pattern) elif info_type[:11] == 'indirection': tagged = ptrutil.make_tagged(settings, pointer)._replace(tag = 0) offset = ptrutil.pointer_offset(settings, tagged, settings.rt.word.size) new_ptr = ptrutil.dereference(settings, offset.untagged, heaps, []) if settings.opts.verbose: print() worklist.append(ClosureWork(heaps = heaps, pointer = new_ptr.untagged)) return Pointer(new_ptr.untagged) elif info_type[:8] == 'function': arg_pattern = info.read_arg_pattern(settings, info_address) else: arg_pattern = '' worklist.append(FunctionThunkWork(heaps = heaps, address = info_address, main_register = ptrutil.make_tagged(settings, pointer)._replace(tag = len(arg_pattern)), arg_pattern = arg_pattern)) return Pointer(info_pointer) except: e_type, e_obj, e_tb = sys.exc_info() print("Error when processing closure at", show.show_pretty_pointer(settings, pointer)) print(" Error:", e_obj) print(" Error Location:", e_tb.tb_lineno) print(" No Disassembly Available") print() return UnknownInterpretation()
def read_memory_operand(self, operand): if base_register(operand.base) in self.registers: assert operand.index == capstone.x86.X86_REG_INVALID return ptrutil.pointer_offset( self.settings, self.registers[base_register(operand.base)], operand.disp) else: return UnknownValue()
def read_closure(settings, interps, heaps, pointer): try: if isinstance(pointer, Argument) or isinstance(pointer, CaseArgument) or isinstance(pointer, Offset) and isinstance(pointer.base, CasePointer): return if settings.opts.verbose: print("Found closure:") print(" Pointer:", show.show_pretty_pointer(settings, pointer)) if isinstance(pointer, StaticValue) and show.name_is_library(show.get_name_for_address(settings, pointer.value)): if settings.opts.verbose: print(" Library defined!") print() return info_pointer = ptrutil.dereference(settings, pointer, heaps, []).untagged assert isinstance(info_pointer, StaticValue) info_address = info_pointer.value info_type = info.read_closure_type(settings, info_address) if info_type[:11] == 'constructor': num_ptrs = ptrutil.read_half_word(settings, settings.text_offset + info_address - settings.rt.halfword.size*4) num_non_ptrs = ptrutil.read_half_word(settings, settings.text_offset + info_address - settings.rt.halfword.size*3) args = [] arg_pointer = ptrutil.make_tagged(settings, pointer)._replace(tag = 0) for i in range(num_ptrs + num_non_ptrs): arg_pointer = ptrutil.pointer_offset(settings, arg_pointer, settings.rt.word.size); args.append(ptrutil.dereference(settings, arg_pointer.untagged, heaps, [])) arg_pattern = 'p' * num_ptrs + 'n' * num_non_ptrs interps[pointer] = Apply(func = Pointer(info_pointer), func_type = 'constructor', args = interp_args(args, arg_pattern), pattern = arg_pattern) if settings.opts.verbose: print() for arg in args[:num_ptrs]: read_closure(settings, interps, arg.untagged) return elif info_type[:8] == 'function': arg_pattern = info.read_arg_pattern(settings, info_address) else: arg_pattern = '' if settings.opts.verbose: print() interps[pointer] = Pointer(info_pointer) read_function_thunk(settings, interps, heaps, info_address, ptrutil.make_tagged(settings, pointer)._replace(tag = len(arg_pattern)), arg_pattern) except: e_type, e_obj, e_tb = sys.exc_info() print("Error when processing closure at", show.show_pretty_pointer(settings, pointer)) print(" Error:", e_obj) print(" Error Location:", e_tb.tb_lineno) print(" No Disassembly Available") print()
def simulate(self, instructions): for insn in instructions: if insn.mnemonic == "add": assert insn.operands[1].type == capstone.x86.X86_OP_IMM self.store( insn.operands[0], ptrutil.pointer_offset(self.settings, self.load(insn.operands[0]), insn.operands[1].imm), ) if ( insn.operands[0].type == capstone.x86.X86_OP_REG and base_register(insn.operands[0].reg) == self.settings.rt.heap_register ): self.heap += [None] * (insn.operands[1].imm // self.settings.rt.word.size) elif insn.mnemonic == "mov": self.store(insn.operands[0], self.load(insn.operands[1])) elif insn.mnemonic == "lea": self.store(insn.operands[0], self.read_memory_operand(insn.operands[1].mem))
def simulate(self, instructions): for insn in instructions: if insn.mnemonic == 'add': assert insn.operands[1].type == capstone.x86.X86_OP_IMM self.store( insn.operands[0], ptrutil.pointer_offset(self.settings, self.load(insn.operands[0]), insn.operands[1].imm)) if insn.operands[ 0].type == capstone.x86.X86_OP_REG and base_register( insn.operands[0].reg ) == self.settings.rt.heap_register: self.heap += [None] * (insn.operands[1].imm // self.settings.rt.word.size) elif insn.mnemonic == 'mov': self.store(insn.operands[0], self.load(insn.operands[1])) elif insn.mnemonic == 'lea': self.store(insn.operands[0], self.read_memory_operand(insn.operands[1].mem))
def read_memory_operand(self, operand): if base_register(operand.base) in self.registers: assert operand.index == capstone.x86.X86_REG_INVALID return ptrutil.pointer_offset(self.settings, self.registers[base_register(operand.base)], operand.disp) else: return UnknownValue()