def visit_expr(self, expression): # Checks if expression is reference by pointer or by value if expression.op == idaapi.cot_memptr: struct_type = expression.x.type.get_pointed_object() elif expression.op == idaapi.cot_memref: struct_type = expression.x.type else: return 0 # Getting information about structure, field offset, address and one line corresponding to code ordinal = helper.get_ordinal(struct_type) field_offset = expression.m ea = self.__find_ref_address(expression) usage_type = self.__get_type(expression) if ea == idaapi.BADADDR or not ordinal: logger.warning( "Failed to parse at address {0}, ordinal - {1}, type - {2}". format(helper.to_hex(ea), ordinal, struct_type.dstr())) one_line = self.__get_line() occurrence_offset = ea - self.__function_address xref_info = (occurrence_offset, one_line, usage_type) # Saving results if ordinal not in self.__result: self.__result[ordinal] = {field_offset: [xref_info]} elif field_offset not in self.__result[ordinal]: self.__result[ordinal][field_offset] = [xref_info] else: self.__result[ordinal][field_offset].append(xref_info) return 0
def data(self, column): if column == 0: return self.name elif column == 1: return self.tinfo.get_pointed_object().dstr() elif column == 2: addresses = self.addresses if len(addresses) > 1: return "LIST" elif len(addresses) == 1: return helper.to_hex(addresses[0])
def __get_type(self, cexpr): """ Returns one of the following types: 'R' - read value, 'W' - write value, 'A' - function argument""" child = cexpr for p in reversed(self.parents): assert p, "Failed to get type at " + helper.to_hex( self.__function_address) if p.cexpr.op == idaapi.cot_call: return 'Arg' if not p.is_expr(): return 'R' if p.cexpr.op == idaapi.cot_asg: if p.cexpr.x == child: return 'W' return 'R' child = p.cexpr
def _manipulate(self, cexpr, obj): super(SearchVisitor, self)._manipulate(cexpr, obj) if obj.tinfo and not helper.is_legal_type(obj.tinfo): logger.warn("Variable obj.name has weird type at {}".format( helper.to_hex(self._find_asm_address(cexpr)))) return if cexpr.type.is_ptr(): member = self.__extract_member_from_pointer(cexpr, obj) else: member = self.__extract_member_from_xword(cexpr, obj) if member: logger.debug( "\tCreating member with type {}, {}, offset - {}".format( member.type_name, member.scanned_variables, member.offset)) self.__temporary_structure.add_row(member)
def _get_member(self, offset, cexpr, obj, tinfo=None, obj_ea=None): if offset < 0: logger.error( "Considered to be imposible: offset - {}, obj - {}".format( offset, helper.to_hex(self._find_asm_address(cexpr)))) raise AssertionError applicable = not self.crippled cexpr_ea = self._find_asm_address(cexpr) scan_obj = ScannedObject.create(obj, cexpr_ea, self.__origin, applicable) if obj_ea: if temporary_structure.VirtualTable.check_address(obj_ea): return temporary_structure.VirtualTable( offset, obj_ea, scan_obj, self.__origin) if helper.is_code_ea(obj_ea): cfunc = helper.decompile_function(obj_ea) if cfunc: tinfo = cfunc.type tinfo.create_ptr(tinfo) else: tinfo = const.DUMMY_FUNC return temporary_structure.Member(offset, tinfo, scan_obj, self.__origin) # logger.warn("Want to see this ea - {},".format(Helper.to_hex(cexpr_ea))) if not tinfo or tinfo.equals_to(const.VOID_TINFO) or tinfo.equals_to( const.CONST_VOID_TINFO): return temporary_structure.VoidMember(offset, scan_obj, self.__origin) if tinfo.equals_to(const.CHAR_TINFO): return temporary_structure.VoidMember(offset, scan_obj, self.__origin, char=True) if tinfo.equals_to(const.CONST_PCHAR_TINFO): tinfo = const.PCHAR_TINFO elif tinfo.equals_to(const.CONST_PVOID_TINFO): tinfo = const.PVOID_TINFO else: tinfo.clr_const() return temporary_structure.Member(offset, tinfo, scan_obj, self.__origin)
def get_information(self): return [helper.to_hex(self.address), self.name, self.tinfo.dstr()]