示例#1
0
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)
示例#2
0
    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()
示例#3
0
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)    
示例#4
0
    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(
            "--------------------------------------------------------------------------------------"
        )
示例#5
0
    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()))
示例#6
0
    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