def get_call_convention(): ida_db_info_structure = idaapi.get_inf_structure() compiler_info = ida_db_info_structure.cc cc = { idaapi.CM_CC_INVALID: "invalid", idaapi.CM_CC_UNKNOWN: "unknown", idaapi.CM_CC_VOIDARG: "voidargs", idaapi.CM_CC_CDECL: "cdecl", idaapi.CM_CC_ELLIPSIS: "ellipsis", idaapi.CM_CC_STDCALL: "stdcall", idaapi.CM_CC_PASCAL: "pascal", idaapi.CM_CC_FASTCALL: "fastcall", idaapi.CM_CC_THISCALL: "thiscall", idaapi.CM_CC_MANUAL: "manual", }[compiler_info.cm & idaapi.CM_CC_MASK] # XXX if ConfigHelpers.get_arch().startswith( "powerpc") and ida_db_info_structure.abiname == "sysv": return "svr" if ConfigHelpers.get_arch() == "x64": if ConfigHelpers.get_file_type() == 'elf': return "sysv" else: return "ms" if ConfigHelpers.get_arch().startswith('arm'): return "aapcs" elif cc not in ("stdcall", "cdecl", "fastcall"): return "stdcall" else: return cc
def main(): if not idaapi.is_debugger_on(): idc.Warning("Please run the process first!") return if idaapi.get_process_state() != -1: idc.Warning("Please suspend the debugger first!") return info = idaapi.get_inf_structure() if info.is_64bit(): long_size = 8 elif info.is_32bit(): long_size = 4 else: idc.Warning("Only 32 or 64 bit is supported!") return # only avail from IdaPython r232 if hasattr(idaapi, "NearestName"): # get all debug names dn = idaapi.get_debug_names(idaapi.cvar.inf.minEA, idaapi.cvar.inf.maxEA) # initiate a nearest name search (using debug names) nn = idaapi.NearestName(dn) else: nn = None RetAddrStackWalk(nn, long_size)
def ev_decorate_name(self, name, mangle, cc, optional_type): logging.debug("##########ev_decorate_name") logging.debug("NAME=" + str(name)) logging.debug("MANGLE?=" + str(mangle)) logging.debug("CC=" + str(cc)) logging.debug("OptionalType=" + str(optional_type)) logging.debug("procName=" + str(idaapi.get_inf_structure().procName)) # Compiler Info "compiler_info_t cc; ///< Target compiler" from ida.hpp logging.debug("cc.id=" + str(idaapi.get_inf_structure().cc.id)) #get_compiler_name # FROM: idaapi.gen_decorate_name(name, mangle, cc, type) -> bool gen_decorate_name(name, mangle, cc, optional_type) logging.debug("NAME POST Decoration:" + str(name)) return name
def supported_cpu(): info = idaapi.get_inf_structure() cpuname = info.procname.lower() if cpuname == "metapc" or cpuname.startswith("arm") or cpuname.startswith( "mips"): return True return False
def go(self): idaapi.set_processor_type("arm", idc.SETPROC_ALL | idc.SETPROC_FATAL) inf = idaapi.get_inf_structure() inf.af &= ~idc.AF_MARKCODE # this is so that IDA does not find functions inside .data segments inf.af2 &= ~idc.AF2_FTAIL # don't create function tails inf.af2 |= idc.AF2_PURDAT # control flow to data segment is ignored print "0) Loading NIDs" self.load_nids() print "1) Mapping kernel VA" self.dump_first_level() print "2) Finding module table using heuristic" self.find_module_ptr() print "3) Creating segments" self.process_chunks() print "4) Resolving imports/exports" self.resolve_impexp() print "5) Waiting for IDA to analyze the program, this will take a while..." idc.Wait() print "6) Analyzing system instructions" from highlight_arm_system_insn import run_script run_script() print "7) Adding MOVT/MOVW pair xrefs" add_xrefs()
def main(ea): # Get Function Bytes start = idc.GetFunctionAttr(ea, FUNCATTR_START) end = idc.GetFunctionAttr(ea, FUNCATTR_END) length = end - start code = "" for byte in idc.GetManyBytes(start, length): code += byte # Determine Architecture info = idaapi.get_inf_structure() proc = info.procName if info.is_64bit(): if proc == "metapc": md = Cs(CS_ARCH_X86, CS_MODE_64) elif proc == "ARM": md = Cs(CS_ARCH_ARM64, CS_MODE_ARM) elif info.is_32bit(): if proc == "metapc": md = Cs(CS_ARCH_X86, CS_MODE_32) elif proc == "ARM": md = Cs(CS_ARCH_ARM, CS_MODE_ARM) # If need change: CS_MODE_THUMB # Disassemble with Capstone and print for i in md.disasm(code, start): try: db = "" for ba in i.bytes: db += str("%X " %(ba)).rjust(3, "0") print("%x:\t%s\t%s\t%s" %(i.address, str(db).ljust(24, " "), i.mnemonic, i.op_str)) except Exception as e: print "Exception: {}".format(e)
def get_file_type(): ida_db_info_structure = idaapi.get_inf_structure() f_type = ida_db_info_structure.filetype if f_type in ConfigHelpers.ftypes: return ConfigHelpers.ftypes[f_type] else: return "binary"
def make_word(ea): info = idaapi.get_inf_structure() if info.is_32bit(): return ida_bytes.create_dword(ea, 4) elif info.is_64bit(): return ida_bytes.create_qword(ea, 8) return False
def guess_machine(): "Return an instance of Machine corresponding to the IDA guessed processor" processor_name = GetLongPrm(INF_PROCNAME) info = idaapi.get_inf_structure() if info.is_64bit(): size = 64 elif info.is_32bit(): size = 32 else: size = None if processor_name == "metapc": size2machine = { 64: "x86_64", 32: "x86_32", None: "x86_16", } machine = Machine(size2machine[size]) elif processor_name == "ARM": # TODO ARM/thumb # hack for thumb: set armt = True in globals :/ # set bigendiant = True is bigendian # Thumb, size, endian info2machine = { (True, 32, True): "armtb", (True, 32, False): "armtl", (False, 32, True): "armb", (False, 32, False): "arml", (False, 64, True): "aarch64b", (False, 64, False): "aarch64l", } is_armt = globals().get('armt', False) is_bigendian = info.is_be() infos = (is_armt, size, is_bigendian) if not infos in info2machine: raise NotImplementedError('not fully functional') machine = Machine(info2machine[infos]) from miasm2.analysis.disasm_cb import guess_funcs, guess_multi_cb from miasm2.analysis.disasm_cb import arm_guess_subcall, arm_guess_jump_table guess_funcs.append(arm_guess_subcall) guess_funcs.append(arm_guess_jump_table) elif processor_name == "msp430": machine = Machine("msp430") elif processor_name == "mipsl": machine = Machine("mips32l") elif processor_name == "mipsb": machine = Machine("mips32b") elif processor_name == "PPC": machine = Machine("ppc32b") else: print repr(processor_name) raise NotImplementedError('not fully functional') return machine
def get_word_len(): info = idaapi.get_inf_structure() if info.is_64bit(): return 8 elif info.is_32bit(): return 4 raise Exception("Unknown address size")
def get_word(ea): info = idaapi.get_inf_structure() if info.is_32bit(): return idaapi.get_32bit(ea) elif info.is_64bit(): return idaapi.get_64bit(ea) return BADADDR
def init(): """ All tinfo should be reinitialized between session. Otherwise they could have wrong type """ global VOID_TINFO, PVOID_TINFO, CONST_PVOID_TINFO, BYTE_TINFO, PBYTE_TINFO, LEGAL_TYPES, X_WORD_TINFO, \ PX_WORD_TINFO, DUMMY_FUNC, CONST_PCHAR_TINFO, CHAR_TINFO, PCHAR_TINFO, CONST_VOID_TINFO, \ WORD_TINFO, PWORD_TINFO, EA64, EA_SIZE EA64 = idaapi.get_inf_structure().is_64bit() EA_SIZE = 8 if EA64 else 4 VOID_TINFO = idaapi.tinfo_t(idaapi.BT_VOID) PVOID_TINFO.create_ptr(VOID_TINFO) CONST_VOID_TINFO = idaapi.tinfo_t(idaapi.BT_VOID | idaapi.BTM_CONST) CONST_PVOID_TINFO.create_ptr( idaapi.tinfo_t(idaapi.BT_VOID | idaapi.BTM_CONST)) CONST_PCHAR_TINFO.create_ptr( idaapi.tinfo_t(idaapi.BTF_CHAR | idaapi.BTM_CONST)) CHAR_TINFO = idaapi.tinfo_t(idaapi.BTF_CHAR) PCHAR_TINFO.create_ptr(idaapi.tinfo_t(idaapi.BTF_CHAR)) BYTE_TINFO = idaapi.tinfo_t(idaapi.BTF_BYTE) PBYTE_TINFO = idaapi.dummy_ptrtype(1, False) X_WORD_TINFO = idaapi.get_unk_type(EA_SIZE) PX_WORD_TINFO = idaapi.dummy_ptrtype(EA_SIZE, False) WORD_TINFO = idaapi.tinfo_t(idaapi.BT_UNK_WORD) PWORD_TINFO.create_ptr(idaapi.tinfo_t(idaapi.BT_UNK_WORD)) func_data = idaapi.func_type_data_t() func_data.rettype = PVOID_TINFO func_data.cc = idaapi.CM_CC_UNKNOWN DUMMY_FUNC = idaapi.tinfo_t() DUMMY_FUNC.create_func(func_data, idaapi.BT_FUNC) LEGAL_TYPES = [ PVOID_TINFO, PX_WORD_TINFO, PWORD_TINFO, PBYTE_TINFO, X_WORD_TINFO ]
def initialize(): if m.initialized: return info = idaapi.get_inf_structure() if info.is_64bit(): m.ptr_size = 8 m.get_ptr = idc.Qword m.mem_fmt = "%016X" m.pack_fmt = "<Q" elif info.is_32bit(): m.ptr_size = 4 m.get_ptr = idc.Dword m.mem_fmt = "%08X" m.pack_fmt = "<L" m.cpu_name = info.procname.lower() m.is_be = idaapi.cvar.inf.is_be() m.filetype = info.filetype m.is_pefile = (m.filetype == idaapi.f_PE) m.thread_id = idaapi.get_current_thread() if m.cpu_name == "metapc": m.registers = {4: regs.x86, 8: regs.x64}[m.ptr_size] elif m.cpu_name.startswith("arm"): m.registers = {4: regs.arm, 8: regs.aarch64}[m.ptr_size] elif m.cpu_name.startswith("mips"): m.registers = regs.mips m.initialized = True
def create_pointer(addr, force_size=None): if force_size is not 4 and (idaapi.get_inf_structure().is_64bit() or force_size is 8): MakeQword(addr) return Qword(addr), 8 else: MakeDword(addr) return Dword(addr), 4
def createAnalyzer(logger): """Create a CPU-based analyzer to be used by the program. Args: logger (logger): logger instance Return Value: Created analyzer instance (None if CPU isn't supported yet) """ # Code taken from: # https://reverseengineering.stackexchange.com/questions/11396/how-to-get-the-cpu-architecture-via-idapython # Kudos to tmr232 info = idaapi.get_inf_structure() if info.is_64bit(): bits = 64 elif info.is_32bit(): bits = 32 # quite rare else: bits = 16 # At the moment we don't care about the processors endianness. # Check if we support this CPU proc_name = info.procName logger.info("Processor: %s, %dbit", proc_name, bits) if proc_name not in analyzers_factory: logger.error("Processor %s is NOT supported yet :(", proc_name) return None # Can now create the analyzer instance return analyzers_factory[proc_name](logger, bits)
def get_memory_model(): ida_db_info_structure = idaapi.get_inf_structure() compiler_info = ida_db_info_structure.cc if compiler_info.cm & idaapi.C_PC_FLAT == idaapi.C_PC_FLAT: return "flat" else: return "segmented"
def create_runtime_ms(): debug('Attempting to find runtime_morestack function for hooking on...') text_seg = get_text_seg() if text_seg is None: debug('Failed to get text segment') return None # Opcodes for "mov large dword ptr ds:1003h, 0", binary search is faster than text search opcodes = 'c7 05 03 10 00 00 00 00 00 00' if idaapi.get_inf_structure().is_64bit(): # Opcodes for "mov qword ptr ds:dword_1000+3, 0" opcodes = '48 c7 04 25 03 10 00 00 00 00 00 00' runtime_ms_end = idaapi.find_binary(text_seg.start_ea, text_seg.end_ea, opcodes, 0, SEARCH_DOWN) if runtime_ms_end == BADADDR: debug('Failed to find opcodes associated with runtime_morestack: %s' % opcodes) return None runtime_ms = idaapi.get_func(runtime_ms_end) if runtime_ms is None: debug('Failed to get runtime_morestack function from address @ 0x%x' % runtime_ms_end) return None if idc.set_name(runtime_ms.start_ea, "runtime_morestack", SN_PUBLIC): debug('Successfully found runtime_morestack') else: debug('Failed to rename function @ 0x%x to runtime_morestack' % runtime_ms.start_ea) return runtime_ms
def create_pointer(addr, force_size=None): if force_size is not 4 and (idaapi.get_inf_structure().is_64bit() or force_size is 8): ida_bytes.create_data(addr, FF_QWORD, 8, ida_idaapi.BADADDR) return idc.get_qword(addr), 8 else: ida_bytes.create_data(addr, FF_DWORD, 4, ida_idaapi.BADADDR) return idc.get_wide_dword(addr), 4
def init(self): if is_gte_ida74() == False: print("[-] {0} : for ida >= 7.4 only".format(self.wanted_name)) return idaapi.PLUGIN_SKIP if idaapi.ph.id != idaapi.PLFM_386 and not idaapi.get_inf_structure( ).is_64bit(): print("[-] {0} : for x64 only".format(self.wanted_name)) return idaapi.PLUGIN_SKIP if not ida_hexrays.init_hexrays_plugin(): print("[-] {0} : no decompiler available, skipping".format( self.wanted_name)) return idaapi.PLUGIN_SKIP self.add_filter(VMXVmwrite()) self.add_filter(VMXVmread()) self.add_filter(VMXVoidReturn(ida_allins.NN_vmlaunch, "__vmx_vmlaunch")) self.add_filter(VMXVoidReturn(ida_allins.NN_vmresume, "__vmx_vmresume")) self.add_filter(VMXVoid(ida_allins.NN_vmxoff, "__vmx_off")) self.add_filter(VMXVMCSReturn(ida_allins.NN_vmclear, "__vmx_vmclear")) self.add_filter(VMXVMCSReturn(ida_allins.NN_vmptrld, "__vmx_vmptrld")) self.add_filter(VMXVMCSReturn(ida_allins.NN_vmptrst, "__vmx_vmptrst")) self.add_filter(VMXVMCSReturn(ida_allins.NN_vmxon, "__vmx_on")) return idaapi.PLUGIN_KEEP
def detect_arch(): #heuristically determine what architecture we're on #only x86-64 and arm64 are supported is_le = False bits = 0 info = get_inf_structure() arch = ARCH_UNKNOWN if info.is_64bit(): bits = 64 elif info.is_32bit(): bits = 32 else: bits = 16 if not info.is_be(): is_le = True procname = info.procName if bits == 64 and is_le: if procname == "ARM": msg("Detected architecture: arm64\n") arch = ARCH_ARM64 elif procname == "metapc": msg("Detected architecture: x86_64\n") arch = ARCH_X86_64 return arch
def get_arch(): ret = {} info = idaapi.get_inf_structure() if info.is_64bit(): bits = 64 elif info.is_32bit(): bits = 32 else: bits = 16 try: is_be = info.is_be() except: is_be = info.mf endian = "big" if is_be else "little" #print 'Processor: {}, {}bit, {} endian'.format(info.procName, bits, endian) if info.procName == "metapc": ret["platform"] = "x86" elif info.procName == "ARM": ret["platform"] = "ARM" else: ret["platform"] = "unknown" ret["bits"] = bits ret["endian"] = endian return ret
def get_processor_name(): inf = idaapi.get_inf_structure() eos = inf.procName.find(chr(0)) if eos > 0: return inf.procName[:eos] else: return inf.procName
class myIdaPlugin(idaapi.plugin_t): flags = idaapi.PLUGIN_KEEP wanted_name = "AndroidBreakpoint" wanted_hotkey = "Alt-F9" comment = "usual bp in android" help = "Something helpful" def init(self): print("init func") try: # result=idaapi.register_and_attach_to_menu("Options/path","name","label","",0,self.run(0),None) register(bpInit) register(bpInitArray) idaapi.attach_action_to_menu("Edit/AndroidBreakpoint/", bpInit.name, idaapi.SETMENU_APP) idaapi.attach_action_to_menu("Edit/AndroidBreakpoint/", bpInitArray.name, idaapi.SETMENU_APP) except BaseException, e: print(e) idainfo = idaapi.get_inf_structure() if idainfo.filetype != idaapi.f_ELF: print("idb isn't elf,skip") return idaapi.PLUGIN_SKIP return idaapi.PLUGIN_KEEP
def is_64bit(): """ Determine IDB binary architecture. is_32bit() always returns True, whereas is_64bit() returns False on 32-bit binaries. """ info = idaapi.get_inf_structure() return info.is_64bit()
def guess_machine(): "Return an instance of Machine corresponding to the IDA guessed processor" processor_name = GetLongPrm(INF_PROCNAME) info = idaapi.get_inf_structure() if info.is_64bit(): size = 64 elif info.is_32bit(): size = 32 else: size = None if processor_name == "metapc": size2machine = { 64: "x86_64", 32: "x86_32", None: "x86_16", } machine = Machine(size2machine[size]) elif processor_name == "ARM": # TODO ARM/thumb # hack for thumb: set armt = True in globals :/ # set bigendiant = True is bigendian # Thumb, size, endian info2machine = {(True, 32, True): "armtb", (True, 32, False): "armtl", (False, 32, True): "armb", (False, 32, False): "arml", (False, 64, True): "aarch64b", (False, 64, False): "aarch64l", } is_armt = globals().get('armt', False) is_bigendian = info.is_be() infos = (is_armt, size, is_bigendian) if not infos in info2machine: raise NotImplementedError('not fully functional') machine = Machine(info2machine[infos]) from miasm2.analysis.disasm_cb import guess_funcs, guess_multi_cb from miasm2.analysis.disasm_cb import arm_guess_subcall, arm_guess_jump_table guess_funcs.append(arm_guess_subcall) guess_funcs.append(arm_guess_jump_table) elif processor_name == "msp430": machine = Machine("msp430") elif processor_name == "mipsl": machine = Machine("mips32l") elif processor_name == "mipsb": machine = Machine("mips32b") elif processor_name == "PPC": machine = Machine("ppc32b") else: print repr(processor_name) raise NotImplementedError('not fully functional') return machine
def init(self): info = idaapi.get_inf_structure() if info.procName != "ARM" or info.filetype != idaapi.f_ELF: print "Support only ARM ELF" return idaapi.PLUGIN_SKIP return idaapi.PLUGIN_OK
def verify_processor_settings(self): ''' The intent here is to validate the processor has been set to ARM. In a better world, I would be able to check the processor sub options. In a perfect world, I could set these myself, or would know the IDA APIs a little better. ''' info = idaapi.get_inf_structure() return info.procName == "ARM"
def get_processor_architecture(): info = idaapi.get_inf_structure() if info.is_64bit(): return "64" elif info.is_32bit(): return "" else: return "Error"
def getArchitecture(self): # https://reverseengineering.stackexchange.com/a/11398 info = idaapi.get_inf_structure() procname = info.procName if procname in self._processor_map: return self._processor_map[procname] else: raise ValueError("Unsupported Architecture")
def get_native_size(): info = idaapi.get_inf_structure() if info.is_64bit(): return 8 elif info.is_32bit(): return 4 else: return 2
def get_ptrsize(): info = idaapi.get_inf_structure() ptr_size = None if info.is_64bit(): ptr_size = 8 elif info.is_32bit(): ptr_size = 4 return ptr_size
def get_native_size(): """Get the native word size in normal 8-bit bytes.""" info = idaapi.get_inf_structure() if info.is_32bit(): return 4 elif info.is_64bit(): return 8 else: return 2
def get_proc_type(): """ Get processor type @return: Returns the processor type or None on failure. """ try: inf = idaapi.get_inf_structure() return inf.procName() except Exception as ex: raise RuntimeError("Could not retrieve processor type: %s" %ex)
def output_segments(out): """Dump binary segmentation.""" info = idaapi.get_inf_structure() size = "r32" if info.is_32bit else "r64" out.writelines(('(', info.get_proc_name()[1], ' ', size, ' (')) for seg in idautils.Segments(): out.write("\n({} {} {:d} ({:#x} {:d}))".format( idaapi.get_segm_name(seg), "code" if idaapi.segtype(seg) == idaapi.SEG_CODE else "data", idaapi.get_fileregion_offset(seg), seg, idaapi.getseg(seg).size())) out.write("))\n")
def load_file(li, neflags, format): """ Load the file into database @param li: a file-like object which can be used to access the input data @param neflags: options selected by the user, see loader.hpp @return: 0-failure, 1-ok """ li.seek(0) vmlinux = li.read(li.size()) do_get_arch(kallsyms, vmlinux) do_kallsyms(kallsyms, vmlinux) # print_kallsyms(kallsyms, vmlinux) if kallsyms['numsyms'] == 0: print '[!]get kallsyms error...' return 0 idaapi.set_processor_type("arm", SETPROC_ALL|SETPROC_FATAL) if kallsyms['arch'] == 64: idaapi.get_inf_structure().lflags |= idaapi.LFLG_64BIT li.file2base(0, kallsyms['_start'], kallsyms['_start']+li.size(), True) s = idaapi.segment_t() s.bitness = kallsyms['arch'] / 32 s.startEA = kallsyms['_start'] s.endEA = kallsyms['_start']+li.size() idaapi.add_segm_ex(s,".text","CODE",ADDSEG_OR_DIE) for i in xrange(kallsyms['numsyms']): if kallsyms['type'][i] in ['t','T']: idaapi.add_entry(kallsyms['address'][i], kallsyms['address'][i], kallsyms['name'][i], 1) else: idaapi.add_entry(kallsyms['address'][i], kallsyms['address'][i], kallsyms['name'][i], 0) print "Android vmlinux loaded..." return 1
def getProcessInfo(self): #Get basic information from the file being Debugged idainfo = idaapi.get_inf_structure() #Get the name of the input file we want to trace app_name = idc.GetInputFile() Print ("The input file is %s" % app_name ) #Check to see what type of file we're tracing #And set up the proper debugger and input monitor if idainfo.filetype == idaapi.f_PE: Print ("Windows PE file" ) os_type = "windows" elif idainfo.filetype == idaapi.f_MACHO: Print ("Mac OSX Macho file") os_type = "macosx" #debugger = "macosx" #checkInput = InputMonitor.checkMacLibs elif idainfo.filetype == idaapi.f_ELF: Print ("Linux ELF file") os_type = "linux" #debugger = "linux" #checkInput = InputMonitor.checkLinuxLibs else: Print ("Unknown binary, unable to debug") return None #Check the debugged executable if its 32 or 64bit if idainfo.is_64bit(): Print("This binary is 64 bit") os_arch = "64" elif idainfo.is_32bit(): Print( "This binary is 32 bit" ) os_arch = "32" else: Print( "Bad binary. ARM processor?" ) os_arch = "ARM" #Get the file type for the executable being debugger fileType = idaapi.get_file_type_name() #For ARM libraries returns 'ELF for ARM (Shared object) Print( fileType ) return (app_name,os_type,os_arch)
def _get_arch(): arch = dict() info = idaapi.get_inf_structure() arch['type'] = info.procName.lower() arch['size'] = "b32" if info.is_32bit(): arch['size'] = "b32" if info.is_64bit(): arch['size'] = "b64" if idaapi.cvar.inf.version >= 700: arch['endian'] = "be" if idaapi.cvar.inf.is_be() else "le"; else: arch['endian'] = "be" if idaapi.cvar.inf.mf else "le"; if info.procName.lower().startswith('mips'): arch['type'] = 'mips' return arch
def get_native_size(): """ Get the native OS size @return: 16, 32, 64 value indicating the native size or None if failed. """ try: inf = idaapi.get_inf_structure() if inf.is_32bit(): return 32 elif inf.is_64bit(): return 64 else: # Native size is neither 32 or 64 bit. assuming 16 bit. return 16 except Exception as ex: raise RuntimeError("Could not Could not retrieve native OS size: %s" %ex)
def get_arch_dynamic(): """ Determine the execution environments architecture. :return: 'x64' or 'x86' if arch could be determined, else None """ info = idaapi.get_inf_structure() if info.is_64bit(): return 64 elif info.is_32bit(): return 32 else: env = idaapi.dbg_get_registers() if env[17][0] == 'RAX': return 64 elif env[17][0] == 'EAX': return 32 else: return None
def dump_loader_info(output_filename): """Dump information for BAP's loader into output_filename.""" from idautils import Segments import idc idaapi.autoWait() with open(output_filename, 'w+') as out: info = idaapi.get_inf_structure() size = "r32" if info.is_32bit else "r64" out.write("(%s %s (" % (info.get_proc_name()[1], size)) for seg in Segments(): out.write("\n(%s %s %d (0x%X %d))" % ( idaapi.get_segm_name(seg), "code" if idaapi.segtype(seg) == idaapi.SEG_CODE else "data", idaapi.get_fileregion_offset(seg), seg, idaapi.getseg(seg).size())) out.write("))\n")
def architecture(self): """Return the IDA guessed processor Ripped from Miasm2 / examples / ida / utils """ processor_name = idc.GetLongPrm(idc.INF_PROCNAME) if processor_name in self.IDAarch2MiasmArch: name = self.IDAarch2MiasmArch[processor_name] elif processor_name == "metapc": # HACK: check 32/64 using INF_START_SP inf = idaapi.get_inf_structure() if inf.is_32bit(): name = "x86_32" elif inf.is_64bit(): name = "x86_64" elif idc.GetLongPrm(idc.INF_START_SP) == 0x80: name = "x86_16" else: raise ValueError('cannot guess 32/64 bit! (%x)' % max_size) elif processor_name == "ARM": # TODO ARM/thumb # hack for thumb: set armt = True in globals :/ # set bigendiant = True is bigendian is_armt = globals().get('armt', False) is_bigendian = globals().get('bigendian', False) if is_armt: if is_bigendian: name = "armtb" else: name = "armtl" else: if is_bigendian: name = "armb" else: name = "arml" else: print repr(processor_name) raise ValueError("Unknown corresponding architecture") return name
def get_arch(): (arch, mode) = (None, None) for x in idaapi.ph_get_regnames(): name = x if name.upper() == 'AX': arch = KS_ARCH_X86 info = idaapi.get_inf_structure() if info.is_64bit(): mode = KS_MODE_64 elif info.is_32bit(): mode = KS_MODE_32 else: mode = KS_MODE_16 break elif name.upper() == 'R0': arch = KS_ARCH_ARM mode = KS_MODE_ARM break return (arch, mode)
def _initialize(self): if self.op_t.type not in (idaapi.o_displ, idaapi.o_phrase): raise exceptions.OperandNotPhrase("Operand is not of type o_phrase or o_displ.") proc_name = idaapi.get_inf_structure().procName if proc_name != "metapc": raise exceptions.PhraseProcessorNotSupported( "Phrase analysis not supported for processor {}".format(proc_name) ) specflag1 = self.op_t.specflag1 specflag2 = self.op_t.specflag2 scale = 1 << ((specflag2 & 0xC0) >> 6) offset = self.op_t.addr if specflag1 == 0: index = None base_ = self.op_t.reg elif specflag1 == 1: index = (specflag2 & 0x38) >> 3 base_ = (specflag2 & 0x07) >> 0 if self.op_t.reg == 0xC: if base_ & 4: base_ += 8 if index & 4: index += 8 else: raise exceptions.PhraseNotSupported("o_displ, o_phrase : Not implemented yet : %x" % specflag1) # HACK: This is a really ugly hack. For some reason, phrases of the form `[esp + ...]` (`sp`, `rsp` as well) # set both the `index` and the `base` to `esp`. This is not significant, as `esp` cannot be used as an # index, but it does cause issues with the parsing. # This is only relevant to Intel architectures. if (index == base_ == idautils.procregs.sp.reg) and (scale == 1): index = None self.scale = scale self.index_id = index self.base_id = base_ self.offset = offset
def __init__(self): # To be set by the architecture specific module if specific instructions # exist for the purpose # self.INSTRUCTIONS_CALL = [] self.INSTRUCTIONS_CONDITIONAL_BRANCH = [] self.INSTRUCTIONS_UNCONDITIONAL_BRANCH = [] self.INSTRUCTIONS_RET = [] self.INSTRUCTIONS_BRANCH = [] if hasattr( idaapi, 'get_inf_structure' ): inf = idaapi.get_inf_structure() else: inf = idaapi.cvar.inf # Find the null character of the string (if any) # null_idx = inf.procName.find(chr(0)) if null_idx > 0: self.processor_name = inf.procName[:null_idx] else: self.processor_name = inf.procName self.os_type = inf.ostype self.asmtype = inf.asmtype # RegExp to parse stack variable names as IDA # returns an string containing some sort of reference # to their frame. # self.stack_name_parse = re.compile(r'.*fr[0-9a-f]+\.([^ ].*)') self.current_instruction_type = None # To be filled by the architecture module # self.arch_name = None
def __init__(self): self.flags = idaapi.ph_get_flag() # instead of checking ph flags, should __EA64__ be used? self.is_64bit = (self.flags & idaapi.PR_USE64) != 0 self.is_32bit = (self.flags & idaapi.PR_USE32) != 0 self.is_stack_up = (self.flags & idaapi.PR_STACK_UP) != 0 self.id = idaapi.ph_get_id() self.is_assemble_supported = (self.flags & idaapi.PR_ASSEMBLE) != 0 self.is_delayslot_proc = (self.flags & idaapi.PR_DELAYED) != 0 # processor default ret instruction (icode, not opcode!) self.ret_icodes = [idaapi.ph_get_icode_return()] # ptrsize in bytes self.ptrsize = 2 if self.is_32bit: self.ptrsize = 4 if self.is_64bit: self.ptrsize = 8 self.ptrsize_pyfmt_mapper = {2:"H", 4:"I", 8:"Q"} self.ptrsize_mask_mapper = {2:0xFFFF, 4:0xFFFFFFFF, 8:0xFFFFFFFFFFFFFFFF} self.datafmt_mapper = {2:"%04X", 4:"%08X", 8:"%016X"} self.endianness = idaapi.get_inf_structure().mf
def get_hardware_mode(): (arch, mode) = (None, None) # heuristically detect hardware setup info = idaapi.get_inf_structure() cpuname = info.procName.lower() if cpuname == "metapc": arch = KS_ARCH_X86 if info.is_64bit(): mode = KS_MODE_64 elif info.is_32bit(): mode = KS_MODE_32 else: mode = KS_MODE_16 elif cpuname.startswith("arm"): # ARM or ARM64 if info.is_64bit(): arch = KS_ARCH_ARM64 mode = KS_MODE_LITTLE_ENDIAN else: arch = KS_ARCH_ARM # either big-endian or little-endian if cpuname == "arm": mode = KS_MODE_ARM | KS_MODE_LITTLE_ENDIAN else: mode = KS_MODE_ARM | KS_MODE_BIG_ENDIAN elif cpuname.startswith("sparc"): arch = KS_ARCH_SPARC if info.is_64bit(): mode = KS_MODE_SPARC64 else: mode = KS_MODE_SPARC32 if cpuname == "sparcb": mode += KS_MODE_BIG_ENDIAN else: mode += KS_MODE_LITTLE_ENDIAN elif cpuname.startswith("ppc"): arch = KS_ARCH_PPC if info.is_64bit(): mode = KS_MODE_PPC64 else: mode = KS_MODE_PPC32 if cpuname == "ppc": # do not support Little Endian mode for PPC mode += KS_MODE_BIG_ENDIAN elif cpuname.startswith("mips"): arch = KS_ARCH_MIPS if info.is_64bit(): mode = KS_MODE_MIPS64 else: mode = KS_MODE_MIPS32 if cpuname == "mipsl": mode += KS_MODE_LITTLE_ENDIAN else: mode += KS_MODE_BIG_ENDIAN elif cpuname.startswith("systemz") or cpuname.startswith("s390x"): arch = KS_ARCH_SYSTEMZ mode = KS_MODE_BIG_ENDIAN return (arch, mode)
def init(self): self.hexrays_inited = False self.registered_actions = [] self.registered_hx_actions = [] global ARCH global BITS ARCH = idaapi.ph_get_id() info = idaapi.get_inf_structure() if info.is_64bit(): BITS = 64 elif info.is_32bit(): BITS = 32 else: BITS = 16 print "LazyIDA (v1.0.0.3) plugin has been loaded." # Register menu actions menu_actions = ( idaapi.action_desc_t(ACTION_CONVERT[0], "Convert to string", menu_action_handler_t(ACTION_CONVERT[0]), None, None, 80), idaapi.action_desc_t(ACTION_CONVERT[1], "Convert to hex string", menu_action_handler_t(ACTION_CONVERT[1]), None, None, 8), idaapi.action_desc_t(ACTION_CONVERT[2], "Convert to C/C++ array (BYTE)", menu_action_handler_t(ACTION_CONVERT[2]), None, None, 38), idaapi.action_desc_t(ACTION_CONVERT[3], "Convert to C/C++ array (WORD)", menu_action_handler_t(ACTION_CONVERT[3]), None, None, 38), idaapi.action_desc_t(ACTION_CONVERT[4], "Convert to C/C++ array (DWORD)", menu_action_handler_t(ACTION_CONVERT[4]), None, None, 38), idaapi.action_desc_t(ACTION_CONVERT[5], "Convert to C/C++ array (QWORD)", menu_action_handler_t(ACTION_CONVERT[5]), None, None, 38), idaapi.action_desc_t(ACTION_CONVERT[6], "Convert to python list (BYTE)", menu_action_handler_t(ACTION_CONVERT[6]), None, None, 201), idaapi.action_desc_t(ACTION_CONVERT[7], "Convert to python list (WORD)", menu_action_handler_t(ACTION_CONVERT[7]), None, None, 201), idaapi.action_desc_t(ACTION_CONVERT[8], "Convert to python list (DWORD)", menu_action_handler_t(ACTION_CONVERT[8]), None, None, 201), idaapi.action_desc_t(ACTION_CONVERT[9], "Convert to python list (QWORD)", menu_action_handler_t(ACTION_CONVERT[9]), None, None, 201), idaapi.action_desc_t(ACTION_XORDATA, "Get xored data", menu_action_handler_t(ACTION_XORDATA), None, None, 9), idaapi.action_desc_t(ACTION_FILLNOP, "Fill with NOPs", menu_action_handler_t(ACTION_FILLNOP), None, None, 9), idaapi.action_desc_t(ACTION_SCANVUL, "Scan format string vulnerabilities", menu_action_handler_t(ACTION_SCANVUL), None, None, 160), ) for action in menu_actions: idaapi.register_action(action) self.registered_actions.append(action.name) # Register hotkey actions hotkey_actions = ( idaapi.action_desc_t(ACTION_COPYEA, "Copy EA", hotkey_action_handler_t(ACTION_COPYEA), "w", "Copy current EA", 0), ) for action in hotkey_actions: idaapi.register_action(action) self.registered_actions.append(action.name) # Add ui hook self.ui_hook = UI_Hook() self.ui_hook.hook() # Add hexrays ui callback if idaapi.init_hexrays_plugin(): addon = idaapi.addon_info_t() addon.id = "tw.l4ys.lazyida" addon.name = "LazyIDA" addon.producer = "Lays" addon.url = "https://github.com/L4ys/LazyIDA" addon.version = "1.0.0.3" idaapi.register_addon(addon) hx_actions = ( idaapi.action_desc_t(ACTION_HX_REMOVERETTYPE, "Remove return type", hexrays_action_handler_t(ACTION_HX_REMOVERETTYPE), "v"), idaapi.action_desc_t(ACTION_HX_COPYEA, "Copy ea", hexrays_action_handler_t(ACTION_HX_COPYEA), "w"), idaapi.action_desc_t(ACTION_HX_COPYNAME, "Copy name", hexrays_action_handler_t(ACTION_HX_COPYNAME), "c"), ) for action in hx_actions: idaapi.register_action(action) self.registered_hx_actions.append(action.name) self.hx_hook = HexRays_Hook() idaapi.install_hexrays_callback(self.hx_hook.callback) self.hexrays_inited = True return idaapi.PLUGIN_KEEP
def init(self): self.__member_type = idc.FF_DWRD if idaapi.get_inf_structure().is_32bit() else idc.FF_QWRD self.__pointer_size = 4 if idaapi.get_inf_structure().is_32bit() else 8 self.__main_window = self.__CreateWindow() return idaapi.PLUGIN_KEEP
def getIdaArchitecture(self): inf = idaapi.get_inf_structure() return inf.procName
try: # For IDA 6.8 and older using PySide # from PySide import QtGui, QtGui as QtWidgets, QtCore # from PySide.QtCore import Qt from PySide import QtGui as QtWidgets except ImportError: try: # For IDA 6.9 and newer using PyQt5 # from PyQt5 import QtGui, QtWidgets, QtCore # from PyQt5.QtCore import Qt from PyQt5 import QtWidgets except ImportError: print 'Cannot import required Qt Modules' info = get_inf_structure() if info.is_64bit(): from mw_monitor.coverage_reader_64 import read_coverage elif info.is_32bit(): from mw_monitor.coverage_reader_32 import read_coverage fname = QtWidgets.QFileDialog.getOpenFileName(None, 'Open file', 'C:\\') # Load the file with the coverage f_in = open(fname[0], "rb") cov = read_coverage(f_in) print "Data read, painting blocks..." for addr in cov: for i in range(addr, addr + cov[addr]): SetColor(i, CIC_ITEM, 0xc6e2ff)
# based on the user-define smart_prolog and smart_epilog regular expressions for that architecture. # # Inputs: start_addr: Start address for segment to define as data # end_addr: End address for segment to define as data # data_type: Type of data to set segment to (dependent on architecture) # ############################################################################################## import re import idaapi ################### USER DEFINED VALUES ################### # Enter a regular expression for how this architecture usually begins and ends functions. # If the architecture does not dictate how to start or end a function use r".*" to allow # for any instruction processor_name = idaapi.get_inf_structure().procName if processor_name == '8051': # 8051 Architecture Prologue and Epilogue smart_prolog = re.compile(r".*") smart_epilog = re.compile(r"reti{0,1}") elif processor_name == 'PIC18Cxx': # PIC18 Architecture Prologue and Epilogue smart_prolog = re.compile(r".*") smart_epilog = re.compile(r"return 0") elif processor_name == 'm32r': # Mitsubishi M32R Architecutre Prologue and Epilogue smart_prolog = re.compile(r"push +lr")
# See the License for the specific language governing permissions and # limitations under the License. import collections import idaapi import idautils import idc import itertools import struct import inspect import ida_ua import ida_bytes _DEBUG_FILE = None _DEBUG_PREFIX = "" _INFO = idaapi.get_inf_structure() # Map of the external functions names which does not return to a tuple containing information # like the number of agruments and calling convention of the function. _NORETURN_EXTERNAL_FUNC = {} FUNC_LSDA_ENTRIES = collections.defaultdict() IS_ARM = "ARM" in _INFO.procName # True if we are running on an ELF file. IS_ELF = (idaapi.f_ELF == _INFO.filetype) or \ (idc.GetLongPrm(idc.INF_FILETYPE) == idc.FT_ELF) # True if this is a Windows PE file. IS_PE = idaapi.f_PE == _INFO.filetype
def get_proc_name(): info = idaapi.get_inf_structure(); return info.get_proc_name();
def load_file(li, neflags, format): """ Load the file into database @param li: a file-like object which can be used to access the input data @param neflags: options selected by the user, see loader.hpp @return: 0-failure, 1-ok """ li.seek(0) vmlinux = li.read(li.size()) do_get_arch(kallsyms, vmlinux) do_kallsyms(kallsyms, vmlinux) if kallsyms['numsyms'] == 0: print_log('[!]get kallsyms error...') return 0 idaapi.set_processor_type("arm", idaapi.SETPROC_ALL|idaapi.SETPROC_FATAL) if kallsyms['arch'] == 64: idaapi.get_inf_structure().lflags |= idaapi.LFLG_64BIT li.file2base(0, kallsyms['_start'], kallsyms['_start']+li.size(), True) sinittext_addr = 0 max_sym_addr = 0 for i in range(kallsyms['numsyms']): if kallsyms['arch'] == 32: if kallsyms['address'][i] > 0xd0000000: continue if kallsyms['name'][i] == '_sinittext': sinittext_addr = kallsyms['address'][i] if kallsyms['address'][i] > max_sym_addr: max_sym_addr = kallsyms['address'][i] max_sym_addr = max_sym_addr + 1024 print_log("max_sym_addr = ", hex(max_sym_addr)) if (kallsyms['_start']+li.size()) > max_sym_addr: max_sym_addr = kallsyms['_start']+li.size() s = idaapi.segment_t() s.bitness = kallsyms['arch'] // 32 s.startEA = kallsyms['_start'] if sinittext_addr == 0: s.endEA = max_sym_addr else: s.endEA = sinittext_addr s.perm = 5 idaapi.add_segm_ex(s,".text","CODE",idaapi.ADDSEG_OR_DIE) if sinittext_addr > 0: s = idaapi.segment_t() s.bitness = kallsyms['arch'] // 32 s.startEA = sinittext_addr s.endEA = max_sym_addr s.perm = 7 idaapi.add_segm_ex(s,".data","DATA",idaapi.ADDSEG_OR_DIE) for i in range(kallsyms['numsyms']): if kallsyms['type'][i] in ['t','T']: idaapi.add_entry(kallsyms['address'][i], kallsyms['address'][i], kallsyms['name'][i], 1) else: idaapi.add_entry(kallsyms['address'][i], kallsyms['address'][i], kallsyms['name'][i], 0) print_log("Android/Linux vmlinux loaded...") return 1
pass #TODO. urgh. def _translate_reg_32(reg): return reg def _translate_reg_64(reg): return {"edi":"rdi", "esi":"rsi", "eax":"rax", "ebx":"rbx", "ecx":"rcx", "edx":"rdx", "ebp":"rbp", "esp":"rsp"}.get(reg, reg) if idaapi.get_inf_structure().is_64bit(): _signed_from_unsigned = _signed_from_unsigned64 _base_ptr = "rbp" _stack_ptr = "rsp" _trashed_regs = ["rax", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11"] _mark_args = _mark_function_args_sysv64 _translate_reg = _translate_reg_64 elif idaapi.get_inf_structure().is_32bit(): _signed_from_unsigned = _signed_from_unsigned32 _base_ptr = "ebp" _stack_ptr = "esp" _trashed_regs = ["eax", "ecx", "edx"] _mark_args = _mark_function_args_x86 _translate_reg = _translate_reg_32 _base_ptr_format = "[{}+".format(_base_ptr)
def graphview(cls): '''Returns true if the current function is being viewed in graph view mode.''' res = idaapi.get_inf_structure() if idaapi.__version__ < 7.0: return res.graph_view != 0 return res.is_graph_view()
def indexing_mode(self): if idaapi.get_inf_structure().procName != "ARM": return IndexingMode() return IndexingMode(pre=bool(self.insn_t.auxpref & 0x20), post=bool(self.insn_t.auxpref & 0x80))