def track_register_value(reg_name, start_ea, end_ea=BADADDR): bread_crumbs = {} fn = idaapi.get_func(ea) curr = start_ea curr_loc = reg_name prev_loc = None while curr != idaapi.BADADDR: if curr != end_ea: xb = idaapi.xrefblk_t() ok = xb.first_to(curr, idaapi.XREF_ALL) while ok and xb.iscode: if xb.type in [idaapi.fl_JF, idaapi.fl_JN]: done = True break ok = xb.next_to() if done: break mark_ea(curr) next = idaapi.BADADDR xb = idaapi.xrefblk_t() ok = xb.first_from(curr, idaapi.XREF_ALL) while ok and xb.iscode: if xb.type in [idaapi.fl_JF, idaapi.fl_JN]: done = True break elif xb.type == idaapi.fl_F: next = xb.to ok = xb.next_from() if done: break curr = next
def handle_block(self, ea): curr = ea done = False while curr != idaapi.BADADDR: if curr != ea: xb = idaapi.xrefblk_t() ok = xb.first_to(curr, idaapi.XREF_ALL) while ok and xb.iscode: if xb.type in [idaapi.fl_JF, idaapi.fl_JN]: done = True break ok = xb.next_to() if done: break self.mark_ea(curr) next = idaapi.BADADDR xb = idaapi.xrefblk_t() ok = xb.first_from(curr, idaapi.XREF_ALL) while ok and xb.iscode: if xb.type in [idaapi.fl_JF, idaapi.fl_JN]: done = True break elif xb.type == idaapi.fl_F: next = xb.to ok = xb.next_from() if done: break curr = next
def __handle_block__(self, ea): curr = ea func = idaapi.get_func(ea) # Mark the complete function with one color if func is not None: self.__set_function_color__(func.startEA) done = False while curr != idaapi.BADADDR: if curr != ea: xb = idaapi.xrefblk_t() ok = xb.first_to(curr, idaapi.XREF_ALL) while ok and xb.iscode: if xb.type in [idaapi.fl_JF, idaapi.fl_JN]: done = True break ok = xb.next_to() if done: break self.__set_instruction_color__(curr) next_ = idaapi.BADADDR xb = idaapi.xrefblk_t() ok = xb.first_from(curr, idaapi.XREF_ALL) while ok and xb.iscode: if xb.type in [idaapi.fl_JF, idaapi.fl_JN]: done = True break elif xb.type == idaapi.fl_F: next_ = xb.to ok = xb.next_from() if done: break curr = next_
def is_read_only_inited_var(self, address): s: segment_t = getseg(address) if s is None: return False if s.perm != (SEGPERM_READ | SEGPERM_WRITE): return False if is_loaded(address): return False ref_finder = xrefblk_t() is_ok = ref_finder.first_to(address, XREF_DATA) while is_ok: if ref_finder.type == dr_W: return False is_ok = ref_finder.next_to() return True
def SetBasicBlockColor(ea, MARKED_BASIC_BLOCK_COLOR): curr = ea done = False while curr != idaapi.BADADDR: if curr != ea: xb = idaapi.xrefblk_t() ok = xb.first_to(curr, idaapi.XREF_ALL) while ok and xb.iscode: if xb.type in [idaapi.fl_JF, idaapi.fl_JN]: done = True break ok = xb.next_to() if done: break SetInstructionColor(curr, MARKED_BASIC_BLOCK_COLOR) next = idaapi.BADADDR xb = idaapi.xrefblk_t() ok = xb.first_from(curr, idaapi.XREF_ALL) while ok and xb.iscode: if xb.type in [idaapi.fl_JF, idaapi.fl_JN]: done = True break elif xb.type == idaapi.fl_F: next = xb.to ok = xb.next_from() if done: break curr = next
def XrefsTo(ea, flags=0): """ Return all references to address 'ea' @param ea: Reference address @param flags: any of idaapi.XREF_* flags Example: for xref in XrefsTo(here(), 0): print xref.type, XrefTypeName(xref.type), \ 'from', hex(xref.frm), 'to', hex(xref.to) """ xref = idaapi.xrefblk_t() if xref.first_to(ea, flags): yield _copy_xref(xref) while xref.next_to(): yield _copy_xref(xref)
def XrefsTo(ea, flags=0): """ Return all references to address 'ea' @param ea: Reference address @param flags: any of idaapi.XREF_* flags Example:: for xref in XrefsTo(here(), 0): print xref.type, XrefTypeName(xref.type), \ 'from', hex(xref.frm), 'to', hex(xref.to) """ xref = idaapi.xrefblk_t() if xref.first_to(ea, flags): yield _copy_xref(xref) while xref.next_to(): yield _copy_xref(xref)
def down(self): '''Return all the structures that are referenced by this specific structure.''' x, sid = idaapi.xrefblk_t(), self.id # grab structures that this one references ok = x.first_from(sid, 0) if not ok: return [] # continue collecting all structures that this one references res = [(x.to, x.iscode, x.type)] while x.next_from(): res.append((x.to, x.iscode, x.type)) # convert refs into a list of OREFs refs = [ interface.OREF(xrto, xriscode, interface.ref_t.of(xrtype)) for xrto, xriscode, xrtype in res ] # return it as a tuple return map(utils.compose(operator.itemgetter(0), instance), refs)
import idaapi addr = AskAddr(0xFFFFFFFF, "Enter start address of the Symbols.") MARKED_FUNC_COLOR = 0xffd7d7 MARKED_ITEM_COLOR = 0xffd6a9 c_addr = idaapi.get_func(addr).startEA print "Current Address: 0x%08x"%c_addr funcs = {} while c_addr != BADADDR: xb = idaapi.xrefblk_t() print "Current Address: 0x%08x"%c_addr ok = xb.first_to(c_addr,idaapi.XREF_ALL) if ok and c_addr != xb.frm: t = xb.frm if idaapi.get_func(t): f = idaapi.get_func(t) if not f.startEA in funcs: funs[f.startEA] = f c_addr = t set_item_color(c_addr) else: break else: break print "New Address: 0x%08x"%c_addr while ok and xb.iscode: print str(xb.type)
import idaapi addr = AskAddr(0xFFFFFFFF, "Enter start address of the Symbols.") MARKED_FUNC_COLOR = 0xffd7d7 MARKED_ITEM_COLOR = 0xffd6a9 c_addr = idaapi.get_func(addr).startEA print "Current Address: 0x%08x" % c_addr funcs = {} while c_addr != BADADDR: xb = idaapi.xrefblk_t() print "Current Address: 0x%08x" % c_addr ok = xb.first_to(c_addr, idaapi.XREF_ALL) if ok and c_addr != xb.frm: t = xb.frm if idaapi.get_func(t): f = idaapi.get_func(t) if not f.startEA in funcs: funs[f.startEA] = f c_addr = t set_item_color(c_addr) else: break else: break print "New Address: 0x%08x" % c_addr while ok and xb.iscode: print str(xb.type)
def AnalyzeRange( self, startEA, endEA ): CurrentAddress = startEA CurrentBlockAddress = CurrentAddress NewBlockStart = True last_op_code = '' while CurrentAddress < endEA: if idaapi.isCode( idaapi.get_flags_novalue( CurrentAddress ) ): idaapi.decode_insn( CurrentAddress ) op_code = idaapi.ua_mnem( CurrentAddress ) operands=[] disasm_line = op_code + ' ' for i in range(0, 6, 1): operand = idaapi.ua_outop2( CurrentAddress, i ) if not operand: break; operand = idaapi.tag_remove( operand ) operands.append( operand ) if i != 0: disasm_line += ',' disasm_line += operand #disasm_line = idaapi.tag_remove( idaapi.generate_disasm_line( CurrentAddress ) ) xref = idaapi.xrefblk_t() ret = xref.first_to( CurrentAddress, idaapi.XREF_FAR ) while ret: ret = xref.next_to() NewBlockStart = True if NewBlockStart and last_op_code[0:3] != 'ret' and last_op_code != 'new block': self.AddToMap( CurrentBlockAddress, CurrentAddress, None, 'link') if NewBlockStart: CurrentBlockAddress = CurrentAddress self.BlockData[CurrentBlockAddress]=[] if self.DebugLevel > 2: print '='*80 if self.DebugLevel > 2: print hex(CurrentAddress), disasm_line self.BlockData[CurrentBlockAddress].append( ( CurrentAddress, disasm_line ) ) NewBlockStart = False CallIsResolved = False ret = xref.first_from( CurrentAddress, idaapi.XREF_FAR ) while ret: if xref.iscode: if op_code == 'jmp' and xref.to == CurrentAddress + idaapi.cvar.cmd.size: NewBlockStart = True elif op_code == 'call': CallIsResolved = True self.AddToMap( CurrentBlockAddress,xref.to, operands[0], 'call') else: if len(operands) > 0 : self.AddToMap( CurrentBlockAddress,xref.to, operands[0], 'from') NewBlockStart = True ret = xref.next_from() if ( op_code == 'call' or op_code =='' ) and not CallIsResolved: self.AddToMap( CurrentBlockAddress, operands[0], operands[0], 'call') if NewBlockStart and op_code != 'jmp': self.AddToMap( CurrentBlockAddress, CurrentAddress + idaapi.cvar.cmd.size, '', 'link') if op_code[0:3] == 'ret': NewBlockStart = True last_op_code = op_code CurrentAddress += idaapi.cvar.cmd.size else: CurrentAddress += 1
def refs(self): """Return the (address, opnum, type) of all the references (code & data) to this structure within the database. If `opnum` is None, then the `address` has the structure applied to it. If `opnum` is defined, then the instruction at `address` references a field that is the specified structure. """ x, sid = idaapi.xrefblk_t(), self.id # grab first reference to structure ok = x.first_to(sid, 0) if not ok: return [] # collect rest of it's references refs = [(x.frm, x.iscode, x.type)] while x.next_to(): refs.append((x.frm, x.iscode, x.type)) # calculate the high-byte which is used to differentiate an address from a structure bits = math.trunc(math.ceil(math.log(idaapi.BADADDR) / math.log(2.0))) highbyte = 0xff << (bits - 8) # iterate through figuring out if sid is applied to an address or another structure res = [] for ref, _, _ in refs: # structure (probably a frame member) if ref & highbyte == highbyte: # get sptr, mptr name = idaapi.get_member_fullname(ref) mptr, _ = idaapi.get_member_by_fullname(name) if not isinstance(mptr, idaapi.member_t): cls = self.__class__ raise TypeError( "{:s} : Unexpected type {!r} for netnode '{:s}'". format('.'.join((__name__, cls.__name__)), mptr.__class__, name)) sptr = idaapi.get_sptr(mptr) # get frame, func_t frname, _ = name.split('.', 2) frid = internal.netnode.get(frname) ea = idaapi.get_func_by_frame(frid) f = idaapi.get_func(ea) # now find all xrefs to member within function xl = idaapi.xreflist_t() idaapi.build_stkvar_xrefs(xl, f, mptr) # now we can add it for xr in xl: ea, opnum, state = xr.ea, int( xr.opnum), instruction.op_state(ea, opnum) res.append( interface.OREF(ea, opnum, interface.ref_t.of_state(state))) continue # address res.append(interface.OREF(ref, None, interface.ref_t.of_state( '*'))) # using '*' to describe being applied to the an address return res
def refs(self): '''Return the (address, opnum, type) of all the references to this member within the database.''' mid = self.id # calculate the high-byte which is used to determine an address from a structure bits = int(math.ceil(math.log(idaapi.BADADDR) / math.log(2.0))) highbyte = 0xff << (bits - 8) # if structure is a frame.. if internal.netnode.name.get(self.__owner.id).startswith('$ '): name, mptr = self.fullname, self.ptr sptr = idaapi.get_sptr(mptr) # get frame, func_t frname, _ = name.split('.', 2) frid = internal.netnode.get(frname) ea = idaapi.get_func_by_frame(frid) f = idaapi.get_func(ea) # now find all xrefs to member within function xl = idaapi.xreflist_t() idaapi.build_stkvar_xrefs(xl, f, mptr) # now we can add it res = [] for xr in xl: ea, opnum = xr.ea, int(xr.opnum) res.append( interface.OREF( ea, opnum, interface.ref_t(xr.type, instruction.op_state(ea, opnum)))) # FIXME return res # otherwise, it's a structure..which means we need to specify the member to get refs for x = idaapi.xrefblk_t() ok = x.first_to(mid, 0) if not ok: return [] # collect all references available refs = [(x.frm, x.iscode, x.type)] while x.next_to(): refs.append((x.frm, x.iscode, x.type)) # now figure out which operand has the structure member applied to it res = [] for ea, _, t in refs: ops = ((idx, internal.netnode.sup.get(ea, 0xf + idx)) for idx in range(idaapi.UA_MAXOP) if internal.netnode.sup.get(ea, 0xf + idx) is not None) ops = ((idx, interface.node.sup_opstruct( val, idaapi.get_inf_structure().is_64bit())) for idx, val in ops) ops = (idx for idx, ids in ops if self.__owner.id in ids) # sanity res.extend( interface.OREF(ea, int(op), interface.ref_t.of(t)) for op in ops) return res
def AnalyzeRange(self, startEA, endEA): CurrentAddress = startEA CurrentBlockAddress = CurrentAddress NewBlockStart = True last_op_code = '' while CurrentAddress < endEA: if idaapi.isCode(idaapi.get_flags_novalue(CurrentAddress)): idaapi.decode_insn(CurrentAddress) op_code = idaapi.ua_mnem(CurrentAddress) operands = [] disasm_line = op_code + ' ' for i in range(0, 6, 1): operand = idaapi.ua_outop2(CurrentAddress, i) if not operand: break operand = idaapi.tag_remove(operand) operands.append(operand) if i != 0: disasm_line += ',' disasm_line += operand #disasm_line = idaapi.tag_remove( idaapi.generate_disasm_line( CurrentAddress ) ) xref = idaapi.xrefblk_t() ret = xref.first_to(CurrentAddress, idaapi.XREF_FAR) while ret: ret = xref.next_to() NewBlockStart = True if NewBlockStart and last_op_code[ 0:3] != 'ret' and last_op_code != 'new block': self.AddToMap(CurrentBlockAddress, CurrentAddress, None, 'link') if NewBlockStart: CurrentBlockAddress = CurrentAddress self.BlockData[CurrentBlockAddress] = [] if self.DebugLevel > 2: print '=' * 80 if self.DebugLevel > 2: print hex(CurrentAddress), disasm_line self.BlockData[CurrentBlockAddress].append( (CurrentAddress, disasm_line)) NewBlockStart = False CallIsResolved = False ret = xref.first_from(CurrentAddress, idaapi.XREF_FAR) while ret: if xref.iscode: if op_code == 'jmp' and xref.to == CurrentAddress + idaapi.cvar.cmd.size: NewBlockStart = True elif op_code == 'call': CallIsResolved = True self.AddToMap(CurrentBlockAddress, xref.to, operands[0], 'call') else: if len(operands) > 0: self.AddToMap(CurrentBlockAddress, xref.to, operands[0], 'from') NewBlockStart = True ret = xref.next_from() if (op_code == 'call' or op_code == '') and not CallIsResolved: self.AddToMap(CurrentBlockAddress, operands[0], operands[0], 'call') if NewBlockStart and op_code != 'jmp': self.AddToMap(CurrentBlockAddress, CurrentAddress + idaapi.cvar.cmd.size, '', 'link') if op_code[0:3] == 'ret': NewBlockStart = True last_op_code = op_code CurrentAddress += idaapi.cvar.cmd.size else: CurrentAddress += 1