def handle_operand(self, insn, op, isRead): uFlag = get_flags(insn.ea) is_offs = is_off(uFlag, op.n) is_stroffs = is_stroff(uFlag, op.n) dref_flag = dr_R if isRead else dr_W def_arg = is_defarg(uFlag, op.n) optype = op.type if optype == o_imm: if is_offs: insn.add_off_drefs(op, dr_O, 0) if op.specflag1 & self.FL_VAL32: if isEnabled(op.specval): ri = idaapi.refinfo_t() init_flags = REF_OFF32|REFINFO_NOBASE if op.specflag1 & self.FL_SUB: init_flags = init_flags|REFINFO_SUBTRACT OffBase = op.specval + op.value else: OffBase = op.specval - op.value ri.init(init_flags, OffBase) idaapi.op_offset_ex(insn.ea, op.n, ri) elif optype == o_displ: if is_offs: OffAddr = op.specval if OffAddr == 0: ri = idaapi.refinfo_t() Status = idaapi.get_refinfo(insn.ea, op.n, ri) OffAddr = ri.base + op.addr insn.create_op_data(OffAddr, op) insn.add_dref(OffAddr, op.offb, dref_flag) elif is_stroffs: insn.add_off_drefs(op, dref_flag, OOF_ADDR) if op.specflag1 & self.FL_VAL32: if isEnabled(op.specval): ri = idaapi.refinfo_t() init_flags = REF_OFF32|REFINFO_NOBASE if op.specflag1 & self.FL_SIGNED: OffBase = op.specval + (0xFFFF & (- op.addr)) else: OffBase = op.specval - op.addr ri.init(init_flags, OffBase) idaapi.op_offset_ex(insn.ea, op.n, ri) elif may_create_stkvars() and not def_arg and op.reg == self.ireg_sp: self.add_stkvar(insn, op, op.addr, STKVAR_VALID_SIZE) elif optype == o_near: if insn.get_canon_feature() & CF_CALL: XrefType = fl_CN else: XrefType = fl_JN insn.add_cref(op.addr, op.offb, XrefType)
def mt_ascii(self): ri = refinfo_t() ri.flags = ASCSTR_C ri.target = -1 mt = opinfo_t() mt.ri = ri return mt
def mt_address(self): ri = refinfo_t() ri.flags = self.REF_OFF ri.target = 0 mt = opinfo_t() mt.ri = ri return mt
def make_view(self, object_version, address): # apply view ri = idaapi.refinfo_t() ri.target = idc.BADADDR ri.base = 0 ri.tdelta = 0 for ((view_offset, operand), view_value) in object_version.get_offset_valueviews().iteritems(): if view_value == 'signeddecimal': if not (idaapi.is_invsign( address + view_offset, idaapi.getFlags(address + view_offset), operand)): idaapi.op_dec(address + view_offset, operand) # we assume defaut operand is unsigned ! idaapi.toggle_sign(address + view_offset, operand) elif view_value == 'unsigneddecimal': idaapi.op_dec(address + view_offset, operand) elif view_value == 'signedhexadecimal': idaapi.op_hex(address + view_offset, operand) if not (idaapi.is_invsign( address + view_offset, idaapi.getFlags(address + view_offset), operand)): idaapi.toggle_sign(address + view_offset, operand) elif view_value == 'unsignedhexadecimal': idaapi.op_hex(address + view_offset, operand) if idaapi.is_invsign(address + view_offset, idaapi.getFlags(address + view_offset), operand): idaapi.toggle_sign(address + view_offset, operand) elif view_value.startswith('offset'): dash = view_value.find("-") if dash != -1: op_type_str = view_value[dash + 1:] op_type = YaToolIDATools.OFFSET_TYPE_MAP[op_type_str] else: op_type = idc.REF_OFF32 ri.flags = op_type idaapi.op_offset_ex(address + view_offset, 1, ri) # idaapi.set_op_type(address + view_offset, idaapi.offflag(), operand) elif view_value == 'char': idaapi.op_chr(address + view_offset, operand) elif view_value == 'binary': idaapi.op_bin(address + view_offset, operand) elif view_value == 'octal': idaapi.op_oct(address + view_offset, operand) for ((register_offset, register_name), (end_offset, new_name) ) in object_version.get_offset_registerviews().iteritems(): func = idaapi.get_func(address) funcEA = func.startEA ret = idaapi.add_regvar(func, funcEA + register_offset, funcEA + end_offset, register_name, new_name, None) if ret != REGVAR_ERROR_OK: logger.warning( "make register_view failed: func=0x%08X, 0x%08X->0x%08X %s->%s, error=%d" % (funcEA, funcEA + register_offset, funcEA + end_offset, register_name, new_name, ret))
def __call__(self): mt = idaapi.opinfo_t() if idaapi.isStruct(self.flag): mt.tid = self.extra['id'] if idaapi.isOff0(self.flag) or idaapi.isOff1(self.flag): mt.ri = idaapi.refinfo_t(self.extra['flags'], self.extra['base'], self.extra['target'], self.extra['tdelta']) if idaapi.isASCII(self.flag): mt.strtype = self.extra['strtype'] sptr = idaapi.get_struc(self.sid) idaapi.set_member_type(sptr, self.soff, self.flag, mt, self.eoff - self.soff)
def __call__(self): mt = idaapi.opinfo_t() if idaapi.isStruct(self.flag): mt.tid = self.extra['id'] if idaapi.isOff0(self.flag) or idaapi.isOff1(self.flag): mt.ri = idaapi.refinfo_t(self.extra['flags'], self.extra['base'], self.extra['target'], self.extra['tdelta']) if idaapi.isASCII(self.flag): mt.strtype = self.extra['strtype'] sptr = idaapi.get_struc(self.sid) idaapi.add_struc_member(sptr, self.fieldname.encode('utf-8'), self.offset, self.flag, mt, self.nbytes)
def make_basic_block(self, object_version, address): # # call the architecture dependent plugin ########### # self.arch_plugin.make_basic_block_prehook(object_version, address) # create basic block name self.make_name(object_version, address, True) # apply view self.make_view(object_version, address) # apply hidden area self.make_hidden_area(object_version, address) for ((xref_offset, operand), xref_list) in object_version.get_xrefed_id_map().iteritems(): struc_path = {} struc_off_delta = {} for (xref_value, xref_attributes) in xref_list: # # fetch structure ################### # # it's a struc (normal case) if xref_value in self.struc_ids: struc_id = self.struc_ids[xref_value] path_idx = 0 if xref_attributes is not None: try: struc_off_delta[ operand] = self.yatools.try_read_hex_value( xref_attributes['delta']) except KeyError: pass try: path_idx = self.yatools.try_read_hex_value( xref_attributes['path_idx']) except KeyError: pass try: struc_path_off = struc_path[operand] except KeyError: struc_path_off = {} struc_path[operand] = struc_path_off struc_path_off[path_idx] = struc_id # This is a struc member : it happens when the "struc path" contains unions elif xref_value in self.strucmember_ids: member_id = self.strucmember_ids[xref_value] path_idx = 0 if xref_attributes is not None: try: struc_off_delta[ operand] = self.yatools.try_read_hex_value( xref_attributes['delta']) except KeyError: pass try: path_idx = self.yatools.try_read_hex_value( xref_attributes['path_idx']) except KeyError: pass try: struc_path_off = struc_path[operand] except KeyError: struc_path_off = {} struc_path[operand] = struc_path_off struc_path_off[path_idx] = member_id # apply stackframe elif xref_value in self.stackframemembers_stackframes: # create operand as stack variable idaapi.op_stkvar(address + xref_offset, operand) # # apply enums ################### # try: enum_id = self.enum_ids[xref_value] idaapi.op_enum(address + xref_offset, operand, enum_id, 0) except KeyError: pass # # apply reference info ################## # ref_info_valid = False try: (reference_info_base, reference_info_flags) = self.reference_infos[xref_value] ref_info_valid = True except KeyError: pass if ref_info_valid: try: ri = idaapi.refinfo_t() ri.base = reference_info_base ri.flags = reference_info_flags ri.tdelta = 0 ri.target = idc.BADADDR idaapi.op_offset_ex(address + xref_offset, operand, ri) except OverflowError: logger.error( "OverflowError while committing address=0x%08X, " "operand=%d, flags=0x%08X, target=0x%08X, value=0x%08X " % (address + xref_offset, operand, reference_info_flags, idc.BADADDR, reference_info_base)) traceback.print_exc() # # now apply structures ################## # for (operand, struc_path_off) in struc_path.iteritems(): path_len = len(struc_path_off) path = idaapi.tid_array(path_len) for i in xrange(0, path_len): path[i] = struc_path_off[i] delta = 0 try: delta = struc_off_delta[operand] except KeyError: pass if DEBUG_EXPORTER: logger.debug( "apply struc : 0x%016X:0x%02X, path_len=%d, delta=%d" % (address + xref_offset, operand, path_len, delta)) idaapi.op_stroff(address + xref_offset, operand, path.cast(), path_len, delta) # # now call the architecture dependent plugin ######### # self.arch_plugin.make_basic_block_posthook(object_version, address)