def decode_angr(): """Attempts to locate all the IOCTLs in a function and decode them all using symbolic execution""" path = ida_nalt.get_input_file_path() addr = idc.get_screen_ea() ioctls = angr_analysis.angr_find_ioctls(path, addr) track_ioctls(ioctls)
def __init__(self, *args): super(IDAProgram, self).__init__(_get_arch(), _get_os()) self._functions = weakref.WeakValueDictionary() try: self._dwarf = DWARFCore(ida_nalt.get_input_file_path()) except: self._dwarf = None self._variables = weakref.WeakValueDictionary()
def get_input_name(): """Get the name of the input file :retrun: Name of the input file """ input_filepath = ida_nalt.get_input_file_path() return Path(input_filepath).name
def __init__(self): Form.__init__(self, r"""syms2elf {formChangeCb} <#Output file#Output ~f~ile:{txtFile}> """, { 'formChangeCb' : Form.FormChangeCb(self.OnFormChange), 'txtFile' : Form.FileInput(save=True, swidth=50) }) self.input_elf = ida_nalt.get_input_file_path()
def activate(self, ctx): if ".collare_projects" in ida_nalt.get_input_file_path(): with open( os.path.join( os.path.dirname(ida_nalt.get_input_file_path()), "changes.json"), "r") as changes_file: changes = json.load(changes_file) base = changes["base"] if base != int(idaapi.get_imagebase()): base = int(idaapi.get_imagebase()) - base else: base = 0 for function in changes["function_names"]: # Set function names function_address = int(function) + base idaapi.set_name( function_address, str(changes["function_names"][function]["name"]), idaapi.SN_FORCE) for comment in changes["comments"]: comment_address = int(comment, 10) + base currentComment = get_comment(comment_address) clear_comments(comment_address) if currentComment: if currentComment in changes["comments"][comment]: set_cmt(comment_address, changes["comments"][comment], False) elif changes["comments"][comment] in currentComment: set_cmt(comment_address, currentComment, False) else: set_cmt( comment_address, currentComment + "; " + changes["comments"][comment], False) else: set_cmt(comment_address, changes["comments"][comment], False) print("[*] Import completed!") idaapi.info("CollaRE Import completed!") else: print("[!] This is not a CollaRE project!") idaapi.warning("This is not a CollaRE project!") return 1
def _init_func_thunk_ctrl_flow(self): """Initializes the control flow redirections and targets using function thunks""" # We only support the ELF format for now inf = ida_idaapi.get_inf_structure() if inf.filetype != ida_ida.f_ELF: return # List the function thunks first input_file_path = ida_nalt.get_input_file_path() image_parser = create_elf_image_parser(input_file_path) function_thunk_list = image_parser.get_function_thunk_list() # Go through each function thunk, and look at its cross references; there # should always be only one user, which is the wrapper around the imported # function is_32_bit = image_parser.get_image_bitness() == 32 for function_thunk in function_thunk_list: thunk_va = function_thunk.start redirection_dest = (ida_bytes.get_wide_dword(thunk_va) if is_32_bit else ida_bytes.get_qword(thunk_va)) caller_address = ida_xref.get_first_cref_to(redirection_dest) if caller_address == ida_idaapi.BADADDR: continue redirection_source = idc.get_func_attr(caller_address, idc.FUNCATTR_START) caller_function_name = ida_funcs.get_func_name(redirection_source) if function_thunk.name in caller_function_name: print( "anvill: Redirecting the user {:x} of thunk {} at rva {:x} to {:x}" .format( redirection_source, function_thunk.name, function_thunk.start, redirection_dest, )) self.add_control_flow_redirection(redirection_source, redirection_dest) print( "anvill: Adding target list {:x} -> [{:x}, complete=True] for {}" .format(caller_address, redirection_dest, function_thunk.name)) self.set_control_flow_targets(caller_address, [redirection_dest], True)
def _init_ctrl_flow_redirections(self): """Initializes the control flow redirections using function thunks""" # We only support the ELF format for now inf = ida_idaapi.get_inf_structure() if inf.filetype != ida_ida.f_ELF: return # List the function thunks first input_file_path = ida_nalt.get_input_file_path() image_parser = create_elf_image_parser(input_file_path) function_thunk_list = image_parser.get_function_thunk_list() # Go through each function thunk, and look at its cross references; there # should always be only one user, which is the wrapper around the imported # function # # Note that the __libc_start_main # thunk does not need redirection since # it's called directly without any wrapper function from the module entry # point is_32_bit = image_parser.get_image_bitness() == 32 for function_thunk in function_thunk_list: if function_thunk.name == "__libc_start_main": continue thunk_va = ida_nalt.get_imagebase() + function_thunk.start redirection_dest = ( ida_bytes.get_wide_dword(thunk_va) if is_32_bit else ida_bytes.get_qword(thunk_va) ) caller_address = ida_xref.get_first_cref_to(redirection_dest) if caller_address == ida_idaapi.BADADDR: continue redirection_source = idc.get_func_attr(caller_address, idc.FUNCATTR_START) print( "anvill: Redirecting the user {:x} of thunk {} at rva {:x} to {:x}".format( redirection_source, function_thunk.name, function_thunk.start, redirection_dest, ) ) self.add_control_flow_redirection(redirection_source, redirection_dest)
def main(): print("Usage:\n\ save_x(\"unique_name\", start_addr, size) - save names, comments, breakpoints\n\ restore_x(\"unique_name\", start_addr) - restore names, comments, breakpoints\n\ Example:\n\t\ save_x(\"first_shellcode\", 0x12340000, 0x1000)\n\t\ restore_x(\"first_shellcode\", 0x12340000)\ ") global MD5_hash_data_file input_filepath = ida_nalt.get_input_file_path() hasher = hashlib.md5() with open(input_filepath, 'rb') as afile: buf = afile.read() hasher.update(buf) MD5_hash = hasher.hexdigest() # str MD5_hash_data_file = input_filepath + "___rstr___" + MD5_hash
def printf(self, value, current_ea, operand_num, dtid): # Is it already cached? val = self.cache_node.supval(current_ea) # Not cached? if val == None: # Retrieve it num = ida_idaapi.struct_unpack(value) val = self.get_rsrc_string(ida_nalt.get_input_file_path(), num) # Cache it self.cache_node.supset(current_ea, val) # Failed to retrieve? if val == "" or val == "\x00": return None # Return the format return "RSRC_STR(\"%s\")" % ida_lines.COLSTR(val, ida_lines.SCOLOR_IMPNAME)
def read_rsds_codeview(): guid = None penode = idaapi.netnode() penode.create(idautils.peutils_t.PE_NODE) fpos = penode.altval(idautils.peutils_t.PE_ALT_DBG_FPOS) if (fpos == 0): print('[*] No debug directory') return guid input_file = ida_nalt.get_input_file_path() if not os.path.exists(input_file): print('[*] input file not available') else: with open(input_file, 'rb') as fd: fd.seek(fpos) raw = fd.read(0x1C) """ typedef struct _IMAGE_DEBUG_DIRECTORY { DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; DWORD Type; DWORD SizeOfData; DWORD AddressOfRawData; DWORD PointerToRawData; } IMAGE_DEBUG_DIRECTORY, *PIMAGE_DEBUG_DIRECTORY; """ dbgdir = struct.unpack('LLHHLLLL', raw) # 2, IMAGE_DEBUG_TYPE_CODEVIEW if not (dbgdir[4] == 2): print('[*] not CODEVIEW data') else: fd.seek(dbgdir[7]) if not (fd.read(4).decode('ascii') == 'RSDS'): print("[*] unsupported CODEVIEW information format (%s)" % sig) else: d1, d2, d3 = struct.unpack('LHH', fd.read(0x8)) d4 = struct.unpack('>H', fd.read(0x2))[0] d5 = binascii.hexlify(fd.read(0x6)).upper() guid = "%08X-%04X-%04X-%04X-%s" % (d1, d2, d3, d4, d5) return guid
def start(): file_path = ida_nalt.get_input_file_path() with open(file_path, 'rb') as f: elf = ELFFile(f) log("ELF file %s loaded." % file_path) plt_sec = get_plt_sec() if not plt_sec: log("No CET found, this elf does not need to recover.") return rela_plt = load_section(elf, ".rela.plt") dynsym = load_section(elf, '.dynsym') for funcea in idautils.Functions(plt_sec, idc.SegEnd(plt_sec)): real_name = resolve_func_name(funcea, rela_plt, dynsym) origin_name = idc.GetFunctionName(funcea) idc.MakeName(funcea, real_name) log("Function %s renamed to %s." % (origin_name, real_name))
def btn_checksec(self, code=0): """ ELF Checksec """ elfpath = ida_nalt.get_input_file_path() if os.path.exists(elfpath): result = Checksec(elfpath) FELogger.info("-" * 10 + "Checksec" + "-" * 10 + elfpath + "-" * 10) FELogger.info(result.sec) else: input_path = ida_kernwin.ask_str(elfpath, 0, "请输入原始Binary路径") if input_path and input_path != "": if os.path.exists(input_path): result = Checksec(input_path) FELogger.info("-" * 10 + "Checksec" + "-" * 10 + input_path + "-" * 10) FELogger.info(result.sec) else: FELogger.info("原始Binary不存在:%s" % input_path) else: FELogger.info("原始Binary不存在:%s" % elfpath)
def activate(self, ctx): # get active filename pe_filename_ext = ida_nalt.get_root_filename() if not pe_filename_ext: print('FakePDB/generate lib: file not loaded') return 1 ida_auto.set_ida_state(ida_auto.st_Work) if self.with_labels: print('FakePDB/generate pdb (with function labels):') else: print('FakePDB/generate pdb:') dumper = DumpInfo() native = Native() #calculate locations idb_dir = os.path.dirname(ida_loader.get_path( ida_loader.PATH_TYPE_IDB)) pe_filename, _ = os.path.splitext(ida_nalt.get_root_filename()) filepath_exe = ida_nalt.get_input_file_path() filepath_json = os.path.join(idb_dir, pe_filename_ext + ".json") filepath_pdb = os.path.join(idb_dir, pe_filename + ".pdb") #generate json print(' * generating JSON: %s' % filepath_json) dumper.dump_info(filepath_json) print(' * generating PDB: %s' % filepath_pdb) native.pdb_generate(filepath_json, filepath_pdb, self.with_labels) print(' * symserv EXE id: %s' % native.pe_timestamp(filepath_exe)) print(' * symserv PDB id: %s' % native.pe_guidage(filepath_exe)) print(' * done') ida_auto.set_ida_state(ida_auto.st_Ready) return 1
def activate(self, ctx): ida_auto.set_ida_state(ida_auto.st_Work) if self.with_labels: print('FakePDB/generate pdb (with function labels):') else: print('FakePDB/generate pdb:') dumper = InformationDumper() generator = PdbGenerator() #get exe location filepath_ida = ida_loader.get_path(ida_loader.PATH_TYPE_IDB) filepath_input = ida_nalt.get_input_file_path() filename = os.path.basename(filepath_input) # app.exe / app.dll pre, _ = os.path.splitext(filepath_ida) pre, _ = os.path.splitext(pre) filepath_exe = filepath_input filepath_json = pre + ".json" filepath_pdb = pre + ".pdb" #generate json print(' * generating JSON: %s' % filepath_json) dumper.dump_info(filepath_json) print(' * generating PDB: %s' % filepath_pdb) generator.generate(filepath_exe, filepath_json, filepath_pdb, self.with_labels) print(' * symserv EXE id: %s' % generator.get_symserv_exe(filepath_exe)) print(' * symserv PDB id: %s' % generator.get_symserv_pdb(filepath_exe)) print(' * done') ida_auto.set_ida_state(ida_auto.st_Ready) return 1
def patchFile(ea, offset): filename = ida_nalt.get_input_file_path() print "Patching file %s" % filename with open(filename, "r+b") as f: f.seek(offset) f.write("\x90" * 6)
def get_input_file_path(): if idaapi.IDA_SDK_VERSION <= 699: retval = idc.GetInputFilePath() else: retval = ida_nalt.get_input_file_path() return retval
def get_filepath(self) -> str: return ida_nalt.get_input_file_path()
def analysis(): for ea in idautils.Functions(): flags = idc.get_func_flags(ea) # 筛选 THUNK (跳转) or 典型库函数 if flags & idc.FUNC_LIB or flags & idc.FUNC_THUNK: continue features['EA'].append(f"{ea:X}") def main(): analysis() if __name__ == "__main__": # 运行脚本逻辑前等待自动分析完成 ida_auto.auto_wait() binary_name = ida_nalt.get_root_filename().split('.')[0] path = ida_nalt.get_input_file_path()[:-len(ida_nalt.get_root_filename())] outputPath = os.path.join(path, '_code.json') try: main() # 输出特征为json with open(outputPath, "w") as f: f.write(json.dumps(features)) # , indent=2 except Exception as e: # 发生异常 traceback.print_exc(file=open(outputPath, "a")) idc.qexit(0)
def getSoPathAndName(): fullpath = ida_nalt.get_input_file_path() filepath,filename = os.path.split(fullpath) return filepath,filename
nimps = idaapi.get_import_module_qty() nt_power_information = None for i in range(0, nimps): name = idaapi.get_import_module_name(i) if not name: continue if "ntdll" in name: idaapi.enum_import_names(i, imp_cb) if nt_power_information is not None: break output_filename = basename(ida_nalt.get_input_file_path()) \ + ida_nalt.get_root_filename() + ".dec" if nt_power_information: ida_auto.auto_wait() if ida_loader.load_plugin("hexx64") and ida_hexrays.init_hexrays_plugin(): code_xrefs = idautils.CodeRefsTo(nt_power_information, 1) for cx in code_xrefs: cf = ida_hexrays.decompile(cx) if cf: with open(output_filename, "a") as fd: fd.write(str(cf) + '\n') else: with open(output_filename, "a") as fd: fd.write("[!] Decompilation failed\n") else:
def __init__(self, *args, **kargs): super(IDAProgram, self).__init__(kargs['arch'], kargs['os']) try: self._dwarf = DWARFCore(ida_nalt.get_input_file_path()) except: self._dwarf = None
def main(): print("\nUsage:\n\ save_x(\"unique_name\", start_addr, size) - save names, comments, breakpoints, functions\n\ restore_x(\"unique_name\", start_addr) - restore names, comments, breakpoints, functions\n\ Example:\n\t\ save_x(\"first_shellcode\", 0x12340000, 0x1000)\n\t\ restore_x(\"first_shellcode\", 0x12340000)\n\t\ save_x(\"f1\", here(), 0x1000)\n\t\ restore_x(\"f1\", here())\n\ \nBONUS: useful if a process allocated a new segment (e.g. VirtualAlloc) otherwise (HeapAlloc, new, etc.) use the first way\n\t\ save_x() == save_x(FIRST_0x10_BYTES_HASH_FROM_EA_SEGMENT, START_OF_EA_SEGMENT, SIZEOF_EA_SEGMENT)\n\t\ restore_x() == restore(FIRST_0x10_BYTES_HASH_FROM_EA_SEGMENT, START_OF_EA_SEGMENT)\n\ ") icon_data_save = "".join([ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x04\x03\x00" "\x00\x00\xED\xDD\xE2\x52\x00\x00\x00\x1E\x50\x4C\x54\x45\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xB7\x28\x6F\x6A\x00\x00\x00\x09\x74\x52" "\x4E\x53\x00\xE0\x08\xB8\xD0\x58\x98\x85\x25\x4C\x7E\x68\xAA\x00\x00\x00\x49\x49\x44\x41\x54\x08\xD7\x63\x60" "\x60\x60\x99\x39\xD3\x01\x48\x11\xC3\xE0\x08\x0D\x9C\x39\x53\x34\xB4\x81\x81\xC9\x72\x26\x10\x4C\x56\x60\x60" "\x50\x06\x31\x8C\x80\x72\x40\x21\xB0\x00\x50\x08\x2C\x00\x16\x02\x09\x80\x85\x80\x02\x10\x21\x90\x00\x02\xB0" "\x0B\x82\x41\x01\x03\xDB\x4C\x30\x48\x00\x00\xA9\xC1\x1A\x09\x2E\x8B\x71\x91\x00\x00\x00\x00\x49\x45\x4E\x44" "\xAE\x42\x60\x82 " ]) icon_data_restore = "".join([ "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x04\x03\x00" "\x00\x00\xED\xDD\xE2\x52\x00\x00\x00\x1E\x50\x4C\x54\x45\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xB7\x28\x6F\x6A\x00\x00\x00\x09\x74\x52" "\x4E\x53\x00\x81\xE0\xD0\x98\x40\xEC\x34\x2D\xD9\x04\x16\x77\x00\x00\x00\x46\x49\x44\x41\x54\x08\xD7\x63\x00" "\x02\x46\x01\x06\x08\x90\x9C\x08\xA1\x19\x67\xCE\x14\x80\x08\xCC\x9C\x39\x11\x2A\x00\x14\x82\x08\x80\x85\x38" "\x5C\xDC\x66\xCE\x4C\x71\x69\x00\x0A\x31\xCF\x9C\x69\x00\xA4\x88\x63\xB0\x87\x86\x16\x30\x20\x01\x46\x25\x30" "\x10\x60\x60\x99\x09\x06\x0E\x00\xB5\x68\x19\x1B\xBF\xF3\x8F\x71\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60" "\x82 " ]) act_icon_save = idaapi.load_custom_icon(data=icon_data_save, format="png") act_icon_restore = idaapi.load_custom_icon(data=icon_data_restore, format="png") act_name_save = "dumpDyn_save:action" act_name_restore = "dumpDyn_restore:action" if idaapi.register_action( idaapi.action_desc_t(act_name_save, "save_x", save_class(), None, "save_x", act_icon_save)): # Insert the action in a toolbar idaapi.attach_action_to_toolbar("DebugToolBar", act_name_save) if idaapi.register_action( idaapi.action_desc_t(act_name_restore, "restore_x", restore_class(), None, "restore_x", act_icon_restore)): # Insert the action in a toolbar idaapi.attach_action_to_toolbar("DebugToolBar", act_name_restore) else: idaapi.unregister_action(act_name_save) idaapi.unregister_action(act_name_restore) global MD5_hash_data_file input_filepath = ida_nalt.get_input_file_path() hasher = hashlib.md5() with open(input_filepath, 'rb') as afile: buf = afile.read() hasher.update(buf) MD5_hash = hasher.hexdigest() # str MD5_hash_data_file = input_filepath + "____dumpDyn___" + MD5_hash
def main(): # Get IDA default information bin_path = ida_nalt.get_input_file_path() with open(bin_path, "rb") as f: bin_hash = sha1(f.read()).hexdigest() img_base = idaapi.get_imagebase() info = idaapi.get_inf_structure() if info.is_64bit(): bits = 64 elif info.is_32bit(): bits = 32 else: bits = 16 endian = "little" if info.is_be(): endian = "big" arch = "_".join([info.procName, str(bits), endian]) arch = get_arch(arch) # Parse option information package, compiler, arch, opti, bin_name = parse_fname(bin_path) if "_noinline" in bin_path: other_option = "noinline" elif "_pie" in bin_path: other_option = "pie" elif "_lto" in bin_path: other_option = "lto" else: other_option = "normal" # Prepare default information for processing caller_map, callee_map = get_call_graph() edge_map, bb_callee_map = get_bb_graph(caller_map, callee_map) # Now extract function information func_data = [] for idx, addr in enumerate(list(idautils.Functions())): function = idaapi.get_func(addr) if (not function or function.start_ea == idaapi.BADADDR or function.end_ea == idaapi.BADADDR): continue # IDA's default function information func_name = get_func_name(addr).strip() demangled_name, demangled_full_name = demangle(func_name) graph = idaapi.FlowChart(function, flags=idaapi.FC_PREDS) data = idc.get_bytes(addr, function.size()) or "" data_hash = sha1(data).hexdigest() stack_size = get_frame_size(addr) # Get imported callees. Note that the segment name is used because # idaapi.get_import_module_name() sometimes returns bad results ... imported_callees = [] if func_name in callee_map: imported_callees = list( filter(lambda x: get_segm_name(x[1]) != get_segm_name(addr), callee_map[func_name])) # Get type information from IDA func_type, ret_type, args = get_type(addr) # Prepare basic block information for feature extraction func_strings = [] func_consts = [] bb_data = [] for bb in graph: if bb.start_ea == idaapi.BADADDR or bb.end_ea == idaapi.BADADDR: continue bb_size = bb.end_ea - bb.start_ea block_data = idc.get_bytes(bb.start_ea, bb_size) or b"" block_data_hash = sha1(block_data).hexdigest() bb_strings = get_strings(bb.start_ea, bb.end_ea) bb_consts = get_consts(bb.start_ea, bb.end_ea) bb_callees = list( filter(lambda x: x[0] == bb.id, bb_callee_map[func_name])) bb_data.append({ "size": bb_size, "block_id": bb.id, "startEA": bb.start_ea, "endEA": bb.end_ea, "type": bb.type, "is_ret": idaapi.is_ret_block(bb.type), "hash": block_data_hash, "callees": bb_callees, "strings": bb_strings, "consts": bb_consts, }) func_strings.extend(bb_strings) func_consts.extend(bb_consts) func_data.append({ "ida_idx": idx, "seg_name": get_segm_name(addr), "name": func_name, "demangled_name": demangled_name, "demangled_full_name": demangled_full_name, "hash": data_hash, "size": function.size(), "startEA": function.start_ea, "endEA": function.end_ea, "cfg_size": graph.size, "img_base": img_base, "bin_path": bin_path, "bin_hash": bin_hash, "bin_offset": addr - img_base, "stack_size": stack_size, "package": package, "compiler": compiler, "arch": arch, "opti": opti, "others": other_option, "bin_name": bin_name, "func_type": func_type, "ret_type": ret_type, "args": args, "callers": caller_map[func_name], "callees": callee_map[func_name], "imported_callees": imported_callees, "cfg": edge_map[func_name], "strings": func_strings, "consts": func_consts, "bb_data": bb_data, }) return func_data
"arch": arch, "opti": opti, "others": other_option, "bin_name": bin_name, "func_type": func_type, "ret_type": ret_type, "args": args, "callers": caller_map[func_name], "callees": callee_map[func_name], "imported_callees": imported_callees, "cfg": edge_map[func_name], "strings": func_strings, "consts": func_consts, "bb_data": bb_data, }) return func_data init_idc() try: func_data = main() except: import traceback traceback.print_exc() ida_pro.qexit(1) else: bin_path = ida_nalt.get_input_file_path() store_func_data(bin_path, func_data) ida_pro.qexit(0)