def activate(self, ctx): info = idaapi.get_inf_structure() selection = idaapi.read_selection() start = selection[1] end = selection[2] if selection[0] == False: start = idaapi.get_screen_ea() if start == idaapi.BADADDR: print 'Easy Nop :: Screen EA == idaapi.BADADDR' return 0 end = start + idaapi.get_item_size(start) else: end += idaapi.get_item_size(end) if start == idaapi.BADADDR: print 'Easy Nop :: Selection EA == idaapi.BADADDR' return 0 if start == end: print 'Easy Nop :: Nothing to nop' return 0 for x in range(start, end): # Maybe theres a smarter way to get the nop value for different archs e.g. Assemble('nop') -> 0x90 idaapi.patch_byte(x, 0x90) for x in range(start + 1, end): idaapi.hide_item(x) # Must do this else it bugs out on 2x 1 byte instructions being nopped idaapi.hide_item(start) idaapi.unhide_item(start) # Search for hidden nops and add to count while idaapi.get_byte(end) == 0x90 and idaapi.is_hidden_item( end) == True: end += 1 count = end - start if count > 1: idaapi.set_cmt(start, "truncated nops (%d)" % (count), False) print end print start return 1
def activate(self, ctx): t0, t1, view = idaapi.twinpos_t(), idaapi.twinpos_t( ), idaapi.get_current_viewer() if idaapi.read_selection(view, t0, t1): start, end = t0.place(view).toea(), t1.place(view).toea() end += idaapi.get_item_size(end) else: start = idaapi.get_screen_ea() if start == idaapi.BADADDR: print('Easy Nop :: Screen EA == idaapi.BADADDR') return 0 end = start + idaapi.get_item_size(start) if start == idaapi.BADADDR: print('Easy Nop :: Selection EA == idaapi.BADADDR') return 0 if start == end: print('Easy Nop :: Nothing to nop') return 0 for x in range(start, end): # Maybe theres a smarter way to get the nop value for different archs e.g. Assemble('nop') -> 0x90 idaapi.patch_byte(x, 0x90) for x in range(start + 1, end): idaapi.hide_item(x) # Must do this else it bugs out on 2x 1 byte instructions being nopped idaapi.hide_item(start) idaapi.unhide_item(start) # Search for hidden nops and add to count while idaapi.get_byte(end) == 0x90 and idaapi.is_hidden_item( end) == True: end += 1 count = end - start if count > 1: idaapi.set_cmt(start, "truncated nops (%d)" % (count), False) print(end) print(start) return 1
def lines(start=None, end=None, reverse=False, selection=False): """Iterate lines in range. Args: start: Starting address, start of IDB if `None`. end: End address, end of IDB if `None`. reverse: Set to true to iterate in reverse order. selection: If set to True, replaces start and end with current selection. Returns: iterator of `Line` objects. """ if selection: start, end = get_selection() else: start, end = fix_addresses(start, end) if not reverse: item = idaapi.get_item_head(start) while item < end: yield Line(item) item += idaapi.get_item_size(item) else: # if reverse: item = idaapi.get_item_head(end - 1) while item >= start: yield Line(item) item = idaapi.get_item_head(item - 1)
def global_var(addr): name = idaapi.get_name(addr) if not name: return None size = idaapi.get_item_size(addr) return GlobalVariable(addr, name, size=size, last_change=int(time()))
def decomp(self, decompPath, gameFiles=None): if not gameFiles: gameFiles = self.gameFiles for file in sorted(gameFiles.keys(), key=gameFiles.__getitem__): if file.endswith('.s'): filename = file[:file.rindex('.')] decomp = '' # decompile all functions within file print("> Decompiling %s... " % (self._getBaseFilename(file)[:-2] + '.c')) ea = gameFiles[file][0] while ea < gameFiles[file][1]: if Function.isFunction(ea): func = Function.Function(ea) # include address for ease of search in case of label name changes decomp += '// 0x%07x\n' % func.func_ea # try to decompile, or put the asm try: decomp += str(idaapi.decompile(func.func_ea)) + '\n\n' except ida_hexrays.DecompilationFailure as e: print('\tFailed to decompile %07X <%s>' % (func.func_ea, func.getName())) decomp += 'int %s() { // could not decompile\n' % func.getName() decomp += '\tasm("%s"\n\t);\n}\n\n' % func.getFormattedDisasm().replace('\n', '\\\n\t').rstrip() ea = func.func_ea + func.getSize(withPool=True) else: ea += idaapi.get_item_size(ea) # write decomp to file.c if decomp: decomp = decomp.replace(' ', ' ') decomp = decomp.replace('\t', ' ') print(self.projPath, decompPath) cFile = open(self.projPath[0] + decompPath + self._getBaseFilename(file)[:-2] + '.c', 'w') cFile.write(decomp) cFile.close() print("Decompilation complete!")
def parse_prelink_info(): """Find and parse the kernel __PRELINK_INFO dictionary.""" segments = _find_prelink_info_segments() for segment in segments: prelink_info_string = ida_bytes.get_strlit_contents( segment, idaapi.get_item_size(segment), idaapi.get_str_type(segment)) prelink_info = kplist.kplist_parse(prelink_info_string) if prelink_info: return prelink_info _log(0, 'Could not find __PRELINK_INFO') return None
def extendThumbFuncToLastPop(func_ea, lastInsn_ea, verbose=True): """ Looks for another POP {..., PC}. Stops at the start of a new function, or at the start of labeled data. Otherwise, it makes sure the code is disassembled, and is thumb, and it extends the range of the function to the found POP {..., PC}. A corner case not accounted by this algorithm, is if the data is in the middle of code, but is jumped over. :param func_ea: addr to function to fix :param lastInsn_ea: address to the last instruction within the function, as registered in the IDB. :return: whether a fix ocurred or not """ ea = lastPop_ea = lastInsn_ea while not idc.Name(ea) or not idc.isData(idc.GetFlags(ea)): if idc.GetReg(ea, 'T') == 0: idc.SetRegEx(ea, 'T', 1, idc.SR_user) # if idc.isData(idc.GetFlags(ea)): # # if not thumb, make thumb # idc.del_items(ea, 0, 2) # idc.MakeCode(ea) if Instruction.isInsn(ea): insn = Instruction.Insn(ea) # update last POP {..., PC} detected if insn.itype == idaapi.ARM_pop and ((insn.getPushPopFlags() & (1 << 15)) != 0): lastPop_ea = ea # stop condition, assuming no PUSH {..., LR} in current function if insn.itype == idaapi.ARM_push and ((insn.getPushPopFlags() & (1 << 14)) != 0): break ea += idaapi.get_item_size(ea) # extend last function to last pop detected if lastPop_ea != lastInsn_ea: if verbose: print('%07X: End -> %07X <%s>' % (func_ea, lastPop_ea, Data.Data(lastPop_ea).getDisasm())) idc.SetFunctionEnd(func_ea, lastPop_ea + 2) return True return False
def lines(start=None, end=None, reverse=False): """Iterate lines in range. :param start: Starting address, start of IDB if `None`. :param end: End address, end of IDB if `None`. :return: iterator of `Line` objects. """ start, end = fix_addresses(start, end) if not reverse: item = idaapi.get_item_head(start) while item < end: yield Line(item) item += idaapi.get_item_size(item) else: # if reverse: item = idaapi.get_item_head(end - 1) while item > start: yield Line(item) item = idaapi.get_item_head(item - 1)
def renamed(self, ea, new_name, local_name): # #print("renamed(ea = %x, new_name = %s, local_name = %d)" % (ea, new_name, local_name)) if ida_struct.is_member_id(ea) or ida_struct.get_struc( ea) or ida_enum.get_enum_name(ea): return 0 ida_func = idaapi.get_func(ea) # global var renaming if ida_func is None: size = idaapi.get_item_size(ea) self.binsync_state_change(self.controller.push_artifact, GlobalVariable(ea, new_name, size=size)) # function name renaming elif ida_func.start_ea == ea: # grab the name instead from ida name = idc.get_func_name(ida_func.start_ea) self.binsync_state_change(self.controller.push_artifact, FunctionHeader(name, ida_func.start_ea)) return 0
def size(self): """Size (in bytes) of the line.""" return idaapi.get_item_size(self.ea)
import idaapi import idautils import idc for head in idautils.Heads(): for xr in idautils.XrefsFrom(head, 0): if xr.type == 19: next = head + idaapi.get_item_size(head) if idc.Byte(next) == 0xFF: continue for xr2 in idautils.XrefsFrom(next, 0): next_next = next + idaapi.get_item_size(next) if (xr2.type == 19) and (xr2.to == next_next): db = head + idaapi.get_item_size(head) if idc.Byte(head) == 0x0F: idaapi.patch_byte(head, 0x90) idaapi.patch_byte(head + 1, 0xE9) else: idaapi.patch_byte(head, 0xEB) idc.MakeUnknown(db, xr.to - db + 0x10, idaapi.DOUNK_SIMPLE) idc.MakeCode(xr.to) i = db while i < xr.to: if (i + 4) < xr.to: idc.MakeDword(i)
def BuildAsmString(self, instr, function): if instr.GetMnem() == 'retn': mnem = 'ret ' else: if instr.GetMnemPrefix(1) != '': mnem = instr.GetMnemPrefix(1) + ' ' + instr.GetMnem(1) + ' ' else: mnem = instr.GetMnem(1) + ' ' refs = list(function.GetRefsFrom(instr.GetOriginEA())) if len(refs) > 1 and instr.GetMnem() != "jmp": key = refs[0][0] if refs[0][1] else refs[1][0] if self.nasm: self.NasmWriteToFile("\t%s L%08x" % (instr.GetMnem(1), key), instr) else: if self.bb_head_ea.has_key(key): mnem += '%09xh' % self.bb_head_ea[key] return mnem else: for i in xrange(0, 6): idc.PatchByte(self.free_ea + i, 0x90) if self.jmp_deps.has_key(key): self.jmp_deps[key].append(self.free_ea) else: self.jmp_deps[key] = [self.free_ea] self.ref_instr[self.free_ea] = instr self.free_ea += 6 return '' if instr.GetMnem() == 'call': if instr.GetOpndType(1) in [2, 5, 6]: mnem += '%09xh' % instr.GetOpndValue(1) elif instr.GetOpndType(1) == 7: comment = instr.GetComment() if comment != None and comment == "Artificial: Gen from call $+5": mnem += '$+5' else: mnem += '%09xh' % instr.GetOpndValue(1) elif instr.GetOpndType(1) == 1: mnem += instr.GetOpnd(1) else: mnem += instr.GetOpnd(1) if self.nasm: self.NasmWriteToFile("\t%s" % mnem, instr) return mnem elif instr.GetMnem() == 'jmp': if self.nasm: tref_from = list(function.GetRefsFrom( instr.GetOriginEA()))[0][0] if tref_from == None: #can be unknown if debug: print ">Assemble:BuildAsmString - tref_from = None @ [%08x] " % instr.GetOriginEA( ), instr.GetOpnd(1) if instr.GetOpndType(1) == 2: size_prefix = idaapi.get_item_size( instr.GetOpndValue(1)) self.NasmWriteToFile( "\tjmp %s 0x%08x" % (instr.BytesToPrefix(size_prefix), instr.GetOpndValue(1)), instr) else: self.NasmWriteToFile("\tjmp %s" % instr.GetOpnd(1), instr) else: if len(refs) > 1: instr_string = "jmp %s" % instr.GetOpnd(1).replace( "SUBS", "sj_%08x_1" % instr.GetOriginEA()) self.NasmWriteToFile("\t%s\n" % instr_string) self.jmp_table_refs.append(instr_string) self.jmp_table += "\n" #self.NasmWriteToFile("\tsj_%08x " % instr.GetOriginEA()) counter = 1 name = 'sj_%08x' % instr.GetOriginEA() for ref in refs: #self.NasmWriteToFile("%s_%d dd L%08x\n" % (name, counter, ref[0])) self.jmp_table += "%s_%d dd L%08x\n" % ( name, counter, ref[0]) counter += 1 else: self.NasmWriteToFile("\tjmp L%08x" % tref_from, instr) return None if debug: print ">Assemble:BuildAsmString - Got mnem JMP ", refs if len(refs) > 1: key = refs[0][0] if refs[0][1] else refs[1][0] else: key = refs[0][0] if self.bb_head_ea.has_key(key): mnem += '%xh' % self.bb_head_ea[key] return mnem elif refs[0][0] == None: #NOTICE! mnem += instr.GetOpnd(1) return mnem else: for i in xrange(0, 6): idc.PatchByte(self.free_ea + i, 0x90) if self.jmp_deps.has_key(key): self.jmp_deps[key].append(self.free_ea) else: self.jmp_deps[key] = [self.free_ea] self.ref_instr[self.free_ea] = instr self.free_ea += 6 return None #regular (non CFG) instruction if instr.GetOpnd(1) != None and instr.GetOpnd(1) != '': if instr.GetOpndType(1) == 2 and re.search( r"\*.*?\+", instr.GetOpnd(1)) == None: op_size = idaapi.get_item_size(instr.GetOpndValue(1)) op_pref_size = instr.GetOpndPrefixSize(1) if op_pref_size != None: op_size = op_pref_size op_size_2 = 0 if instr.GetOpndType(2) == 1: op_size_2 = instr.GetRegSize(instr.GetOpnd(2)) if op_size >= op_size_2: opnd = '%s [0x%08x]' % (instr.BytesToPrefix(op_size), instr.GetOpndValue(1)) else: opnd = '%s [0x%08x]' % (instr.BytesToPrefix(op_size_2), instr.GetOpndValue(1)) mnem += opnd elif instr.GetOpndPrefix(1) != None: mnem += '%s %s' % (instr.GetOpndPrefix(1), instr.GetOpnd(1)) else: mnem += instr.GetOpnd(1) if instr.GetOpnd(2) != None: if instr.GetOpndType(2) == 2 and re.search( r"\*+", instr.GetOpnd(2)) == None: op_disas = instr.GetOpnd(2) op_size = idaapi.get_item_size(instr.GetOpndValue(2)) op_pref_size = instr.GetOpndPrefixSize(1) if op_pref_size != None: op_size = op_pref_size op_size_2 = 0 if instr.GetOpndType(1) == 1: op_size_2 = instr.GetRegSize(instr.GetOpnd(1)) if op_size >= op_size_2: opnd = '%s [0x%08x]' % (instr.BytesToPrefix(op_size), instr.GetOpndValue(2)) else: opnd = '%s [0x%08x]' % (instr.BytesToPrefix(op_size_2), instr.GetOpndValue(2)) if instr.GetMnem() == "lea": opnd = '[0x%08x]' % (instr.GetOpndValue(2)) mnem += ', ' + opnd else: mnem += ', ' + opnd else: mnem += ', ' + instr.GetOpnd(2) elif instr.GetOpnd(2) != None and instr.GetOpnd(2) != '': if instr.GetOpndType(2) == 2 and re.search( r"\*+", instr.GetOpnd(2)) == None: op_disas = instr.GetOpnd(2) op_size = idaapi.get_item_size(instr.GetOpndValue(2)) op_pref_size = instr.GetOpndPrefixSize(2) if op_pref_size != None: op_size = op_pref_size op_size_2 = 0 if instr.GetOpndType(1) == 1: op_size_2 = instr.GetRegSize(instr.GetOpnd(1)) if op_size >= op_size_2: opnd = '%s [0x%08x]' % (instr.BytesToPrefix(op_size), instr.GetOpndValue(2)) else: opnd = '%s [0x%08x]' % (instr.BytesToPrefix(op_size_2), instr.GetOpndValue(2)) mnem += opnd elif instr.GetOpndType( 2) == 3 and instr.GetMnem().upper()[:2] == "FS": #this is a special case to handle FS* fp instructions that have 1st argument hidden in IDA #and to handle the difference in masm vs nasm (tbyte bs tword). #NOTE: GetOpnd(1,1) is used because the first argument is empty when it gets populated # by the taint function, so original operand is in GetOpnd(2,0) and cleand (no prefix) # operand is in GetOpnd(1,1) opnd = '%s %s' % (instr.BytesToPrefix( instr.GetOpndPrefixSize(1)), instr.StripOpndPrefix(instr.GetOpnd(2))) mnem += ' ' + opnd else: mnem += ' ' + instr.GetOpnd(2) if self.nasm: self.NasmWriteToFile("\t%s" % mnem, instr) return mnem
def size(ea): """Return the size of the array at address ``ea``""" return idaapi.get_item_size(ea)
def getArrayLength(ea): sz,ele = idaapi.get_item_size(ea),getSize(ea) return sz // ele
def getArrayLength(ea): sz, ele = idaapi.get_item_size(ea), getSize(ea) return sz // ele
__author__ = 'wartortell' import idaapi import idautils import idc bad_jump_count = 0 for head in idautils.Heads(): for xref in idautils.XrefsFrom(head, 0): # Find direct jump instructions if xref.type == 19: next_head = head + idaapi.get_item_size(head) # Make sure we aren't handling jump tables if idc.Byte(next_head) == 0xFF: continue # Now check that the next instruction is a direct jump of length 0 for xref2 in idautils.XrefsFrom(next_head, 0): third_head = next_head + idaapi.get_item_size(next_head) if (xref2.type == 19) and (xref2.to == third_head): db = head + idaapi.get_item_size(head) print "Bad jump: %8X -> %8X, changing to direct JMP" % (head, xref.to) # Change head to a direct jump if idc.Byte(head) == 0x0F: idaapi.patch_byte(head, 0x90)
def BuildAsmString(self, instr, function): if instr.GetMnem() == 'retn': mnem = 'ret ' else: if instr.GetMnemPrefix(1) != '': mnem = instr.GetMnemPrefix(1) + ' ' + instr.GetMnem(1) + ' ' else: mnem = instr.GetMnem(1) + ' ' refs = list(function.GetRefsFrom(instr.GetOriginEA())) if len(refs) > 1 and instr.GetMnem() != "jmp": key = refs[0][0] if refs[0][1] else refs[1][0] if self.nasm: self.NasmWriteToFile("\t%s L%08x" % (instr.GetMnem(1), key), instr) else: if self.bb_head_ea.has_key(key): mnem += '%09xh' % self.bb_head_ea[key] return mnem else: for i in xrange(0,6): idc.PatchByte(self.free_ea + i, 0x90) if self.jmp_deps.has_key(key): self.jmp_deps[key].append(self.free_ea) else: self.jmp_deps[key] = [self.free_ea] self.ref_instr[self.free_ea] = instr self.free_ea += 6 return '' if instr.GetMnem() == 'call': if instr.GetOpndType(1) in [2,5,6]: mnem += '%09xh' % instr.GetOpndValue(1) elif instr.GetOpndType(1) == 7: comment = instr.GetComment() if comment != None and comment == "Artificial: Gen from call $+5": mnem += '$+5' else: mnem += '%09xh' % instr.GetOpndValue(1) elif instr.GetOpndType(1) == 1: mnem += instr.GetOpnd(1) else: mnem += instr.GetOpnd(1) if self.nasm: self.NasmWriteToFile("\t%s" % mnem, instr) return mnem elif instr.GetMnem() == 'jmp': if self.nasm: tref_from = list(function.GetRefsFrom(instr.GetOriginEA()))[0][0] if tref_from == None: #can be unknown if debug: print ">Assemble:BuildAsmString - tref_from = None @ [%08x] " % instr.GetOriginEA(), instr.GetOpnd(1) if instr.GetOpndType(1) == 2: size_prefix = idaapi.get_item_size(instr.GetOpndValue(1)) self.NasmWriteToFile("\tjmp %s 0x%08x" % (instr.BytesToPrefix(size_prefix), instr.GetOpndValue(1)), instr) else: self.NasmWriteToFile("\tjmp %s" % instr.GetOpnd(1), instr) else: if len(refs) > 1: instr_string = "jmp %s" % instr.GetOpnd(1).replace("SUBS", "sj_%08x_1" % instr.GetOriginEA()) self.NasmWriteToFile("\t%s\n" % instr_string ) self.jmp_table_refs.append(instr_string) self.jmp_table += "\n" #self.NasmWriteToFile("\tsj_%08x " % instr.GetOriginEA()) counter = 1 name = 'sj_%08x' % instr.GetOriginEA() for ref in refs: #self.NasmWriteToFile("%s_%d dd L%08x\n" % (name, counter, ref[0])) self.jmp_table += "%s_%d dd L%08x\n" % (name, counter, ref[0]) counter += 1 else: self.NasmWriteToFile("\tjmp L%08x" % tref_from, instr) return None if debug: print ">Assemble:BuildAsmString - Got mnem JMP ", refs if len(refs) > 1: key = refs[0][0] if refs[0][1] else refs[1][0] else: key = refs[0][0] if self.bb_head_ea.has_key(key): mnem += '%xh' % self.bb_head_ea[key] return mnem elif refs[0][0] == None: #NOTICE! mnem += instr.GetOpnd(1) return mnem else: for i in xrange(0,6): idc.PatchByte(self.free_ea + i, 0x90) if self.jmp_deps.has_key(key): self.jmp_deps[key].append(self.free_ea) else: self.jmp_deps[key] = [self.free_ea] self.ref_instr[self.free_ea] = instr self.free_ea += 6 return None #regular (non CFG) instruction if instr.GetOpnd(1) != None and instr.GetOpnd(1) != '': if instr.GetOpndType(1) == 2 and re.search(r"\*.*?\+", instr.GetOpnd(1)) == None: op_size = idaapi.get_item_size(instr.GetOpndValue(1)) op_pref_size = instr.GetOpndPrefixSize(1) if op_pref_size != None: op_size = op_pref_size op_size_2 = 0 if instr.GetOpndType(2) == 1: op_size_2 = instr.GetRegSize(instr.GetOpnd(2)) if op_size >= op_size_2: opnd = '%s [0x%08x]' % (instr.BytesToPrefix(op_size), instr.GetOpndValue(1)) else: opnd = '%s [0x%08x]' % (instr.BytesToPrefix(op_size_2), instr.GetOpndValue(1)) mnem += opnd elif instr.GetOpndPrefix(1) != None: mnem += '%s %s' % (instr.GetOpndPrefix(1), instr.GetOpnd(1)) else: mnem += instr.GetOpnd(1) if instr.GetOpnd(2) != None: if instr.GetOpndType(2) == 2 and re.search(r"\*+", instr.GetOpnd(2)) == None: op_disas = instr.GetOpnd(2) op_size = idaapi.get_item_size(instr.GetOpndValue(2)) op_pref_size = instr.GetOpndPrefixSize(1) if op_pref_size != None: op_size = op_pref_size op_size_2 = 0 if instr.GetOpndType(1) == 1: op_size_2 = instr.GetRegSize(instr.GetOpnd(1)) if op_size >= op_size_2: opnd = '%s [0x%08x]' % (instr.BytesToPrefix(op_size), instr.GetOpndValue(2)) else: opnd = '%s [0x%08x]' % (instr.BytesToPrefix(op_size_2), instr.GetOpndValue(2)) if instr.GetMnem() == "lea": opnd = '[0x%08x]' % (instr.GetOpndValue(2)) mnem += ', ' + opnd else: mnem += ', ' + opnd else: mnem += ', ' + instr.GetOpnd(2) elif instr.GetOpnd(2) != None and instr.GetOpnd(2) != '': if instr.GetOpndType(2) == 2 and re.search(r"\*+", instr.GetOpnd(2)) == None: op_disas = instr.GetOpnd(2) op_size = idaapi.get_item_size(instr.GetOpndValue(2)) op_pref_size = instr.GetOpndPrefixSize(2) if op_pref_size != None: op_size = op_pref_size op_size_2 = 0 if instr.GetOpndType(1) == 1: op_size_2 = instr.GetRegSize(instr.GetOpnd(1)) if op_size >= op_size_2: opnd = '%s [0x%08x]' % (instr.BytesToPrefix(op_size), instr.GetOpndValue(2)) else: opnd = '%s [0x%08x]' % (instr.BytesToPrefix(op_size_2), instr.GetOpndValue(2)) mnem += opnd elif instr.GetOpndType(2) == 3 and instr.GetMnem().upper()[:2] == "FS": #this is a special case to handle FS* fp instructions that have 1st argument hidden in IDA #and to handle the difference in masm vs nasm (tbyte bs tword). #NOTE: GetOpnd(1,1) is used because the first argument is empty when it gets populated # by the taint function, so original operand is in GetOpnd(2,0) and cleand (no prefix) # operand is in GetOpnd(1,1) opnd = '%s %s' % (instr.BytesToPrefix(instr.GetOpndPrefixSize(1)), instr.StripOpndPrefix(instr.GetOpnd(2))) mnem += ' ' + opnd else: mnem += ' ' + instr.GetOpnd(2) if self.nasm: self.NasmWriteToFile("\t%s" % mnem, instr) return mnem
__author__ = 'wartortell' import idaapi import idautils import idc bad_jump_count = 0 for head in idautils.Heads(): for xref in idautils.XrefsFrom(head, 0): # Find direct jump instructions if xref.type == 19: next_head = head + idaapi.get_item_size(head) # Make sure we aren't handling jump tables if idc.Byte(next_head) == 0xFF: continue # Now check that the next instruction is a direct jump of length 0 for xref2 in idautils.XrefsFrom(next_head, 0): third_head = next_head + idaapi.get_item_size(next_head) if (xref2.type == 19) and (xref2.to == third_head): db = head + idaapi.get_item_size(head) print "Bad jump: %8X -> %8X, changing to direct JMP" % ( head, xref.to) # Change head to a direct jump if idc.Byte(head) == 0x0F:
def length(ea): """Return the number of elements in the array at address ``ea``""" sz, ele = idaapi.get_item_size(ea), idaapi.get_full_data_elsize( ea, idaapi.getFlags(ea)) return sz // ele