def parse_func_pointer(): renamed = 0 text_seg = common.get_text_seg() if text_seg is None: debug('Failed to get text segment') return for addr in idautils.Functions(text_seg.startEA, text_seg.endEA): name = idc.GetFunctionName(addr) # Look at data xrefs to the function - find the pointer that is located in .rodata data_ref = idaapi.get_first_dref_to(addr) while data_ref != idc.BADADDR: if 'rodata' in idc.get_segm_name(data_ref): # Only rename things that are currently listed as an offset; eg. off_9120B0 if 'off_' in idc.GetTrueName(data_ref): if idc.MakeNameEx(data_ref, ('%s_ptr' % name), flags=idaapi.SN_FORCE): idaapi.autoWait() renamed += 1 else: common._error( 'Failed to name pointer @ 0x%02x for %s' % (data_ref, name)) data_ref = idaapi.get_next_dref_to(addr, data_ref) common._info("Rename %d function pointers.\n" % renamed)
def parse_funcs(self): ''' Parse function struct and rename function ''' self.func_num = common.read_mem(self.start_addr + 8, forced_addr_sz=self.ptr_sz) common._info("Total functions number: %d\n" % self.func_num) self.func_tbl_sz = self.func_num * 2 * self.ptr_sz funcs_entry = self.start_addr + 8 self.func_tbl_addr = funcs_entry + self.ptr_sz idc.MakeNameEx(funcs_entry, "funcs_entry", flags=idaapi.SN_FORCE) idaapi.autoWait() idc.MakeNameEx(self.func_tbl_addr, "pc0", flags=idaapi.SN_FORCE) idaapi.autoWait() for func_idx in xrange(self.func_num): curr_addr = self.func_tbl_addr + func_idx * 2 * self.ptr_sz func_addr = common.read_mem(curr_addr, forced_addr_sz=self.ptr_sz) name_off = common.read_mem(curr_addr + self.ptr_sz, forced_addr_sz=self.ptr_sz) name_addr = self.start_addr + self.ptr_sz + name_off func_st_addr = name_addr - self.ptr_sz func_st = FuncStruct(func_st_addr, self) func_st.parse() # Make comment for name offset idc.MakeComm(curr_addr + self.ptr_sz, "Func Struct: 0x%x" % func_st_addr) idaapi.autoWait()
def parse_itab(moddata, type_parser): common._info("Start to parse Itab") itab_addr = idc.BADADDR itab_end_addr = idc.BADADDR itab_num = 0 # comfirm Itab's start_addr and end_addr if moddata == None: itab_seg = common.get_seg([".itablink", "__itablink"]) if itab_seg: itab_addr = itab_seg.start_ea itab_end_addr = itab_seg.end_ea itab_num = (itab_end_addr - itab_addr) / common.ADDR_SZ else: itab_addr = moddata.itablink_addr itab_num = moddata.itab_num itab_end_addr = itab_addr + itab_num * common.ADDR_SZ curr_addr = itab_addr while curr_addr < itab_end_addr: curr_itabelem_addr = common.read_mem(curr_addr, read_only=True) itab_elem = ItabElem(curr_itabelem_addr, type_parser) itab_elem.parse() itab_num += 1 curr_addr += common.ADDR_SZ common._info("Itab parsing done, total number: %d" % itab_num)
def parse_srcfile(self): ''' Parse and extract source all file names ''' srcfile_tbl_off = common.read_mem( self.func_tbl_addr + self.func_tbl_sz + self.ptr_sz, forced_addr_sz=4) & 0xFFFFFFFF self.srcfile_tbl_addr = self.start_addr + srcfile_tbl_off idc.MakeComm(self.func_tbl_addr + self.func_tbl_sz + self.ptr_sz, \ "Source file table addr: 0x%x" % self.srcfile_tbl_addr) idc.MakeNameEx(self.srcfile_tbl_addr, "runtime_filetab", flags=idaapi.SN_FORCE) idaapi.autoWait() self.srcfile_num = (common.read_mem(self.srcfile_tbl_addr, forced_addr_sz=4) & 0xFFFFFFFF) - 1 common._info( "--------------------------------------------------------------------------------------" ) common._info( "Source File paths(Total number: %d, default print results are user-defind files):\n" % self.srcfile_num) for idx in xrange(self.srcfile_num): srcfile_off = common.read_mem( (idx + 1) * 4 + self.srcfile_tbl_addr, forced_addr_sz=4) & 0xFFFFFFFF srcfile_addr = self.start_addr + srcfile_off srcfile_path = idc.GetString(srcfile_addr) if srcfile_path is None or len(srcfile_path) == 0: common._error("Failed to parse the [%d] src file(off: 0x%x, addr: @ 0x%x)" %\ (idx+1, srcfile_off, srcfile_addr)) continue if len(self.goroot) > 0 and (srcfile_path.startswith(self.goroot) or "/pkg/" in srcfile_path or\ srcfile_path == "<autogenerated>" or srcfile_path.startswith("_cgo_")): # ignore golang std libs and 3rd pkgs common._debug(srcfile_path) else: # User defined function self.srcfiles.append(srcfile_path) common._info(srcfile_path) idc.MakeStr(srcfile_addr, srcfile_addr + len(srcfile_path) + 1) idaapi.autoWait() idc.MakeComm((idx + 1) * 4 + self.srcfile_tbl_addr, "") idaapi.add_dref((idx + 1) * 4 + self.srcfile_tbl_addr, srcfile_addr, idaapi.dr_O) idaapi.autoWait() common._info( "--------------------------------------------------------------------------------------" )
def build_all_types(self, depth=1): _info("Building all types...") for idx in xrange(self.moddata.type_num): type_off = read_mem(self.moddata.typelink_addr + idx*4, forced_addr_sz=4) & 0xFFFFFFFF if type_off == 0: continue type_addr = self.moddata.types_addr + type_off if type_addr in self.parsed_types.keys(): _debug(" "*depth + 'already parsed') continue #print self.parsed_types.keys() #try: self.parse_type(type_addr=type_addr) idc.MakeComm(self.moddata.typelink_addr + idx*4, "type @ 0x%x" % type_addr) idaapi.autoWait() #except Exception as e: # _error("Failed to parse type_off( 0x%x ) @ 0x%x" % (type_off, type_addr)) # raise Exception(e) _info("types building finished. Total types number: %d" % len(self.parsed_types.keys()))
def parse_type(self, type_addr=idc.BADADDR, depth=1): if type_addr == 0 or type_addr == idc.BADADDR: return None if type_addr in self.parsed_types.keys(): _debug(" "*depth + 'already parsed') return self.parsed_types[type_addr].rtype _debug("Parsing type @ 0x%x" % type_addr) rtype = RType(type_addr, self.moddata, self) rtype.parse() _debug("Type name @ 0x%x: %s" % (type_addr, rtype.name)) if rtype.size == 0: _info(" "*depth + "> WARNNING: empty type @ 0x%x" % type_addr) # parse the specific kind of data type if rtype.get_kind() == "Ptr": ptr_type = PtrType(type_addr, self, rtype) self.parsed_types[type_addr] = ptr_type ptr_type.parse() _debug(" "*depth + ptr_type.name) elif rtype.get_kind() == "Struct": st_type = StructType(type_addr, self, rtype) self.parsed_types[type_addr] = st_type st_type.parse() _debug(" "*depth + st_type.name) elif rtype.get_kind() == "Array": arr_type = ArrayType(type_addr, self, rtype) self.parsed_types[type_addr] = arr_type arr_type.parse() _debug(" "*depth + arr_type.name) elif rtype.get_kind() == "Slice": slice_type = SliceType(type_addr, self, rtype) self.parsed_types[type_addr] = slice_type slice_type.parse() _debug(" "*depth + slice_type.name) elif rtype.get_kind() == "Interface": itype = InterfaceType(type_addr, self, rtype) self.parsed_types[type_addr] = itype itype.parse() _debug(" "*depth + itype.name) elif rtype.get_kind() == "Chan": ch_type = ChanType(type_addr, self, rtype) self.parsed_types[type_addr] = ch_type ch_type.parse() _debug(" "*depth + ch_type.name) elif rtype.get_kind() == "Func": func_type = FuncType(type_addr, self, rtype) self.parsed_types[type_addr] = func_type func_type.parse() _debug(" "*depth + func_type.name) elif rtype.get_kind() == "Map": map_type = MapType(type_addr, self, rtype) self.parsed_types[type_addr] = map_type map_type.parse() _debug(" "*depth + map_type.name) elif self.is_raw_type(rtype.get_kind()): self.parsed_types[type_addr] = RawType(type_addr, rtype) _debug(" "*depth + rtype.name) else: raise Exception('Unknown type (kind:%s)' % rtype.get_kind()) # process uncommon type, i.e. types with mothods # if rtype.get_kind() != "Map" and rtype.is_uncomm(): if rtype.is_uncomm(): prim_type = self.parsed_types[type_addr] uncomm_type = UncommonType(prim_type, self) self.parsed_types[type_addr] = uncomm_type uncomm_type.parse() return rtype