def parse_iat(self, file): labeledIatList = open(file, "r").read().splitlines() labeledIatDict = dict() for i in labeledIatList: cur_rva, cur_iat_label = i.split('\t') labeledIatDict[hex(ida_nalt.get_imagebase() + int(cur_rva, 16))] = cur_iat_label return labeledIatDict
def dump_info(self, filepath): self._base = ida_nalt.get_imagebase() output = { 'general' : self.__process_general(), 'segments' : self.__process_segments(), 'functions' : self.__process_functions(), 'names' : self.__process_names() } with open(filepath, "w") as f: json.dump(output, f, indent=4)
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 __init__(self, arch: Arch, os: OS, maybe_base_address: Optional[int] = None): if maybe_base_address is not None: delta = abs(ida_nalt.get_imagebase() - maybe_base_address) if maybe_base_address < ida_nalt.get_imagebase(): delta = delta * -1 if ida_segment.rebase_program(delta, ida_segment.MSF_FIXONCE) != 0: raise RuntimeError("Failed to rebase the program") # Wait until IDA has finished analysis before we proceed, otherwise # we will end up missing code, data and cross references ida_auto.auto_wait() super(IDASpecification, self).__init__(arch, os) try: self._init_func_thunk_ctrl_flow() except: DEBUG( "Failed to initialize the control flow information for functin thunks" )
def slot_import_pickle(self): path = idaapi.ask_file(True, "*.capa", "Choose file") if not path: return if not os.path.exists(path): msg('capa: File does not exists !') return data = None with open(path, "rb") as import_file: self.range_model_proxy.invalidate() self.search_model_proxy.invalidate() self.model_data.reset() self.model_data.clear() self.disable_controls() self.set_view_status_label("Loading...") success = False act = True try: self.doc = pickle.load(import_file) if self.doc["meta"]["analysis"][ "base_address"] != ida_nalt.get_imagebase(): if 0 == idaapi.ask_yn( 1, "Imagebase is not match! Continue to load ?"): act = False except Exception as e: act = False logger.error("Failed to load capa results (error: %s)", e) if act: try: self.model_data.render_capa_doc(self.doc) self.render_capa_doc_mitre_summary() self.enable_controls() success = True except Exception as e: logger.error("Failed to render results (error: %s)", e) self.reset_view_tree() if not success: self.set_view_status_label("Click Analyze to get started...") logger.info("Loading Analysis failed.") else: logger.info("Loading Analysis completed.")
def apply_iat(self, iat): min_ea = ida_ida.inf_get_min_ea() max_ea = ida_ida.inf_get_max_ea() image_base = ida_nalt.get_imagebase() idaapi.msg(f"{hex(min_ea)} - {hex(max_ea)} - {hex(image_base)} \n") for i in range(min_ea, max_ea): mnemonic = idc.print_insn_mnem(i) if mnemonic == "call" and str(idc.print_operand( i, 0)).startswith("dword"): try: idc.set_name( idc.get_operand_value(i, 0), iat[hex(idc.get_operand_value(i, 0))] + str(random.randint(0, 1000)) ) # I added random.randint() because some functions already in the IAT are dynamically resolved again, so renaming them causes a conflict, if you want remove it. (Sample causing the problem: https://bazaar.abuse.ch/sample/49fd52a3f3d1d46dc065217e588d1d29fba4d978cd8fdb2887fd603320540f71/) open("resolved_iat.txt", "a").write(f"{hex(idc.get_operand_value(i, 0))}\n") except: open("unresolved_iat.txt", "a").write(f"{hex(idc.get_operand_value(i, 0))}\n")
def goto_rva(): rva = 0 txt = clip_text() if txt.isdigit(): try: rva = int(txt, 10) except: pass elif txt.isalnum(): try: rva = int(txt, 16) except: pass rva = ida_kernwin.ask_addr(rva, "Enter the RVA to jump to") if rva is None: return 0 base = ida_nalt.get_imagebase() ea = base + rva plg_print("RVA = 0x%X -> EA = 0x%X" % (rva, ea)) idc.jumpto(ea) return 1
def bin_search(bin_str: str) -> List[int]: if not isinstance(bin_str, str): raise ValueError('bin_str must be a string') if bin_str in cached_patterns: return cached_patterns[bin_str] bin_list = bin_str.split() image = bytearray() mask = bytearray() # Create the mask and convert '?' to 'CC'. for i in range(len(bin_list)): byte = bin_list[i] if byte == '?': image.append(int('CC', 16)) mask.append(0) else: image.append(int(byte, 16)) mask.append(1) image = bytes(image) mask = bytes(mask) start = ida_nalt.get_imagebase() end = ida_idaapi.BADADDR addrs: List[int] = [] ea = ida_bytes.bin_search(start, end, image, mask, 0, ida_bytes.BIN_SEARCH_FORWARD) while ea != ida_idaapi.BADADDR: addrs.append(ea) ea = ida_bytes.bin_search(ea + len(image), end, image, mask, 0, ida_bytes.BIN_SEARCH_FORWARD) cached_patterns[bin_str] = addrs return cached_patterns[bin_str]
self.when = when self.testcase = testcase filename = idaapi.ask_file(False, '*.csv', 'Please select csv') blocks = [] with open(filename) as csvfile: readCSV = csv.reader(csvfile, delimiter=";", quotechar='"') next(readCSV) for row in readCSV: print row blocks.append(int(row[4])) for bb in blocks: absPos = bb + ida_nalt.get_imagebase() f = idaapi.get_func(absPos) if f is None: continue fc = idaapi.FlowChart(f) # Highlight the complete function idc.SetColor(absPos, idc.CIC_FUNC, 0xFFF000) for block in fc: if block.startEA <= absPos and block.endEA > absPos: #print "Setting colour for %x" % absPos for i in Heads(block.startEA, block.endEA): idc.set_color(i, CIC_ITEM, 0xFFAA00)
def copy_rva(): ea = idc.get_screen_ea() base = ida_nalt.get_imagebase() rva = ea - base plg_print("EA = %X - RVA = %X copied to clipboard" % (ea, rva)) copy_to_clip("0x%X" % rva)
def image_rebase(): if get_imagebase() == 0: rebase_program(DEFAULT_IMAGE_BASE, MSF_FIXONCE)
def main(): rva = ida_kernwin.ask_addr(0x0, "RVA") if not rva: return ida_kernwin.jumpto(ida_nalt.get_imagebase() + rva)
# Step Nr. 5: Let user change offset (optional) offset = ida_kernwin.ask_long(0, "Add offset (if it's hex prepend a 0x)") # Step Nr. 6: Retrieve covered blocks engine = create_engine(database_string) with engine.connect() as con: #blocksDB = con.execute('SELECT Offset FROM covered_blocks WHERE ModuleID = %d' % selected_module) blocksDistinctDB = con.execute( 'SELECT DISTINCT Offset FROM covered_blocks WHERE ModuleID = %d ORDER BY Offset ASC' % selected_module[0]) print "Found ? block(s) (%d distinct)" % (blocksDistinctDB.rowcount) # Step Nr. 7: Color the currently loaded binary for (bb, ) in blocksDistinctDB: absPos = bb + offset if not rawModule: absPos += ida_nalt.get_imagebase() print absPos f = ida_funcs.get_func(absPos) if f is None: continue fc = ida_gdl.FlowChart(f) # Highlight the complete function idc.set_color(absPos, idc.CIC_FUNC, 0xFFF000) for block in fc: if block.start_ea <= absPos and block.end_ea > absPos: #print "Setting colour for %x" % absPos for i in Heads(block.start_ea, block.end_ea): idc.set_color(i, CIC_ITEM, 0xFFAA00)
def get_imagebase(self): return ida_nalt.get_imagebase()