Exemple #1
0
    def parse_hdr(self):
        '''
        Refer: function [go12Init()] in https://golang.org/src/debug/gosym/pclntab.go
        '''
        magic = idc.Dword(self.start_addr) & 0xFFFFFFFF
        if magic != Pclntbl.MAGIC:
            print magic, Pclntbl.MAGIC
            common._error("Invalid pclntbl header magic number!")
            idc.Exit(1)
            #raise Exception("Invalid pclntbl header magic number!")
        idc.MakeDword(self.start_addr)
        idc.MakeComm(self.start_addr, "Magic Number")
        idc.MakeNameEx(self.start_addr,
                       "runtime_symtab",
                       flags=idaapi.SN_FORCE)
        idaapi.autoWait()

        if idc.Word(self.start_addr + 4) & 0xFFFF != 0:
            raise Exception("Invalid pclntbl header")
        idc.MakeWord(self.start_addr + 4)

        self.min_lc = idc.Byte(self.start_addr + 6) & 0xFF
        if (self.min_lc != 1) and (self.min_lc != 2) and (self.min_lc != 4):
            raise Exception("Invalid pclntbl minimum LC!")
        idc.MakeComm(self.start_addr + 6, "instruction size quantum")
        idaapi.autoWait()

        self.ptr_sz = idc.Byte(self.start_addr + 7) & 0xFF
        if (self.ptr_sz != 4) and (self.ptr_sz != 8):
            raise Exception("Invalid pclntbl pointer size!")
        idc.MakeComm(self.start_addr + 7, "ptr size")
        idaapi.autoWait()
Exemple #2
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)
Exemple #3
0
def parse_strings():
    strings_added = 0
    retry = []
    text_seg = common.get_text_seg()
    if text_seg is None:
        common._debug('Failed to get text segment')
        return strings_added

    # This may be inherently flawed as it will only search for defined functions
    # and as of IDA Pro 6.95 it fails to autoanalyze many GO functions, currently
    # this works well since we redefine/find (almost) all the functions prior to
    # this being used. Could be worth a strategy rethink later one or on diff archs
    for addr in idautils.Functions(text_seg.startEA, text_seg.endEA):
        name = idc.GetFunctionName(addr)

        end_addr = idautils.Chunks(addr).next()[1]
        if (end_addr < addr):
            common._error('Unable to find good end for the function %s' % name)
            pass

        common._debug('Found function %s starting/ending @ 0x%x 0x%x' %
                      (name, addr, end_addr))

        while addr <= end_addr:
            if parse_str_ptr(addr):
                strings_added += 1
                addr = idc.FindCode(addr, idaapi.SEARCH_DOWN)
            elif is_string_patt(addr):
                if 'rodata' not in idc.get_segm_name(
                        addr) and 'text' not in idc.get_segm_name(addr):
                    common._debug('Should a string be in the %s section?' %
                                  idc.get_segm_name(addr))
                string_addr = idc.GetOperandValue(addr, 1)
                addr_3 = idc.FindCode(idc.FindCode(addr, idaapi.SEARCH_DOWN),
                                      idaapi.SEARCH_DOWN)
                string_len = idc.GetOperandValue(addr_3, 1)
                if string_len > 1:
                    if create_string(string_addr, string_len):
                        if create_offset(addr):
                            strings_added += 1
                    else:
                        # There appears to be something odd that goes on with IDA making some strings, always works
                        # the second time, so lets just force a retry...
                        retry.append((addr, string_addr, string_len))

                # Skip the extra mov lines since we know it won't be a load on any of them
                addr = idc.FindCode(addr_3, idaapi.SEARCH_DOWN)
            else:
                addr = idc.FindCode(addr, idaapi.SEARCH_DOWN)

    for instr_addr, string_addr, string_len in retry:
        if create_string(string_addr, string_len):
            if create_offset(instr_addr):
                strings_added += 1
        else:
            common._error(
                'Unable to make a string @ 0x%x with length of %d for usage in function @ 0x%x'
                % (string_addr, string_len, instr_addr))

    return strings_added
Exemple #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(
            "--------------------------------------------------------------------------------------"
        )
Exemple #5
0
    def parse_hdr(self):
        '''
        Refer: function [go12Init()] in https://golang.org/src/debug/gosym/pclntab.go
        '''
        magic = idc.Dword(self.start_addr) & 0xFFFFFFFF
        if magic != Pclntbl.MAGIC:
            print magic, Pclntbl.MAGIC
            common._error("Invalid pclntbl header magic number!")
            idc.Exit(1)
            #raise Exception("Invalid pclntbl header magic number!")

        if idc.Word(self.start_addr + 4) & 0xFFFF != 0:
            raise Exception("Invalid pclntbl header")

        self.min_lc = idc.Byte(self.start_addr + 6) & 0xFF
        if (self.min_lc != 1) and (self.min_lc != 2) and (self.min_lc != 4):
            raise Exception("Invalid pclntbl minimum LC!")

        self.ptr_sz = idc.Byte(self.start_addr + 7) & 0xFF
        if (self.ptr_sz != 4) and (self.ptr_sz != 8):
            raise Exception("Invalid pclntbl pointer size!")
Exemple #6
0
    def parse(self, is_test=False):
        func_addr = common.read_mem(self.addr,
                                    forced_addr_sz=self.pclntbl.ptr_sz,
                                    read_only=is_test)

        name_addr = common.read_mem(self.addr + self.pclntbl.ptr_sz, forced_addr_sz=4, read_only=is_test) \
            + self.pclntbl.start_addr
        raw_name_str = idc.GetString(name_addr)
        if raw_name_str and len(raw_name_str) > 0:
            self.name = common.clean_function_name(raw_name_str)

        if not is_test:
            idc.MakeComm(self.addr, "Func Entry")
            idaapi.autoWait()
            # make comment for func name offset
            idc.MakeComm(
                self.addr + self.pclntbl.ptr_sz,
                "Func name offset(Addr @ 0x%x), name string: %s" %
                (name_addr, raw_name_str))
            idaapi.autoWait()

            # Make name string
            if len(self.name) > 0:
                if idc.MakeStr(name_addr, name_addr + len(raw_name_str) + 1):
                    idaapi.autoWait()
                    common._debug("Match func_name: %s" % self.name)
                else:
                    common._error("Make func_name_str [%s] failed @0x%x" %
                                  (self.name, name_addr))

            # Rename function
            real_func_addr = idaapi.get_func(func_addr)
            if len(self.name) > 0 and real_func_addr is not None:
                if idc.MakeNameEx(real_func_addr.startEA,
                                  self.name,
                                  flags=idaapi.SN_FORCE):
                    idaapi.autoWait()
                    common._debug("Rename function 0x%x: %s" %
                                  (real_func_addr.startEA, self.name))
                else:
                    common._error('Failed to rename function @ 0x%x' %
                                  real_func_addr.startEA)

        self.args = common.read_mem(self.addr + self.pclntbl.ptr_sz + 4,
                                    forced_addr_sz=4,
                                    read_only=is_test)
        self.frame = common.read_mem(self.addr + self.pclntbl.ptr_sz + 2 * 4,
                                     forced_addr_sz=4,
                                     read_only=is_test)
        self.pcsp = common.read_mem(self.addr + self.pclntbl.ptr_sz + 3 * 4,
                                    forced_addr_sz=4,
                                    read_only=is_test)
        self.pcfile = common.read_mem(self.addr + self.pclntbl.ptr_sz + 4 * 4,
                                      forced_addr_sz=4,
                                      read_only=is_test)
        self.pcln = common.read_mem(self.addr + self.pclntbl.ptr_sz + 5 * 4,
                                    forced_addr_sz=4,
                                    read_only=is_test)
        self.nfuncdata = common.read_mem(self.addr + self.pclntbl.ptr_sz +
                                         6 * 4,
                                         forced_addr_sz=4,
                                         read_only=is_test)
        self.npcdata = common.read_mem(self.addr + self.pclntbl.ptr_sz + 7 * 4,
                                       forced_addr_sz=4,
                                       read_only=is_test)

        if not is_test:
            idc.MakeComm(self.addr + self.pclntbl.ptr_sz + 4, "args")
            idc.MakeComm(self.addr + self.pclntbl.ptr_sz + 2 * 4, "frame")
            idc.MakeComm(self.addr + self.pclntbl.ptr_sz + 3 * 4, "pcsp")
            idc.MakeComm(self.addr + self.pclntbl.ptr_sz + 4 * 4, "pcfile")
            idc.MakeComm(self.addr + self.pclntbl.ptr_sz + 5 * 4, "pcln")
            idc.MakeComm(self.addr + self.pclntbl.ptr_sz + 6 * 4, "nfuncdata")
            idc.MakeComm(self.addr + self.pclntbl.ptr_sz + 7 * 4, "npcdata")
            idaapi.autoWait()