Beispiel #1
0
    def parse(self):
        pkgpath_off = read_mem(self.uncomm_type_addr, forced_addr_sz=4) & 0xFFFFFFFF
        if pkgpath_off != 0:
            self.pkgpath_addr = self.types_addr + pkgpath_off
            pkg_path_obj = Name(self.pkgpath_addr, self.type_parser.moddata)
            pkg_path_obj.parse(False)
            self.pkg_path = pkg_path_obj.name_str

        self.meth_cnt = read_mem(self.uncomm_type_addr + 4, forced_addr_sz=2) & 0xFFFF
        self.xmeth_cnt = read_mem(self.uncomm_type_addr + 6, forced_addr_sz=2) & 0xFFFF
        self.meth_off = read_mem(self.uncomm_type_addr + 8, forced_addr_sz=4) & 0xFFFFFFFF
        self.unused = read_mem(self.uncomm_type_addr + 12, forced_addr_sz=4) & 0xFFFFFFFF

        # parse methods
        methods_start_addr = (self.uncomm_type_addr + self.meth_off) & 0xFFFFFFFF
        for i in xrange(self.meth_cnt):
            #meth_addr = self.uncomm_type_addr + i * self.size
            meth = MethodType(methods_start_addr, self.type_parser)
            meth.parse()
            self.methods.append(meth)
            methods_start_addr += meth.size

        idc.MakeComm(self.uncomm_type_addr, "pkg path%s" % \
            (("(@ 0x%x): %s" % (self.pkgpath_addr, self.pkg_path)) if (pkgpath_off>0 and len(self.pkg_path)>0) else ""))
        idc.MakeComm(self.uncomm_type_addr + 4, "methods number: %d" % self.meth_cnt)
        idc.MakeComm(self.uncomm_type_addr + 6, "exported methods number: %d" % self.xmeth_cnt)
        if self.meth_cnt > 0:
            idc.MakeComm(self.uncomm_type_addr + 8, "methods addr: 0x%x" % ((self.uncomm_type_addr + self.meth_off) & 0xFFFFFFFF))
        else:
            idc.MakeComm(self.uncomm_type_addr + 8, "methods offset")
        idc.MakeComm(self.uncomm_type_addr + 12, "unused field: 0x%x" % self.unused)
        idaapi.autoWait()
Beispiel #2
0
    def parse(self):
        _debug("Interface @ 0x%x" % self.addr)
        # parse pkg path
        self.pkg_path_addr = read_mem(self.addr + self.rtype.self_size)
        if self.pkg_path_addr > 0 and self.pkg_path_addr != idc.BADADDR:
            self.pkg_path_obj = Name(self.pkg_path_addr, self.type_parser.moddata)
            self.pkg_path_obj.parse(False)
            self.pkg_path = self.pkg_path_obj.name_str

        # parse fields
        methods_start_addr = read_mem(self.addr + self.rtype.self_size + ADDR_SZ)
        methods_cnt = read_mem(self.addr + self.rtype.self_size + 2*ADDR_SZ)
        methods_cap = read_mem(self.addr + self.rtype.self_size + 3*ADDR_SZ)
        for idx in xrange(methods_cnt):
            imeth = IMethodType(methods_start_addr + idx*2*4, self.type_parser)
            imeth.parse()
            self.methods.append(imeth)

        idc.MakeComm(self.addr + self.rtype.self_size, "pkg path%s" % \
            (("(@ 0x%x): %s" % (self.pkg_path_addr, self.pkg_path)) if (self.pkg_path_addr>0 and len(self.pkg_path)>0) else ""))
        idc.MakeComm(self.addr + self.rtype.self_size + 2*ADDR_SZ, "methods count: 0x%x" % methods_cnt)
        idc.MakeComm(self.addr + self.rtype.self_size + 3*ADDR_SZ, "methods capacity: 0x%x" % methods_cap)
        idaapi.autoWait()

        _debug("Interface pkg path%s" % \
            (("(@ 0x%x): %s" % (self.pkg_path_addr, self.pkg_path)) if (self.pkg_path_addr>0 and len(self.pkg_path)>0) else ""))
        _debug("Interface methods count: 0x%x" % methods_cnt)

        if len(self.rtype.name) > 0:
            idc.MakeNameEx(methods_start_addr, "%s_methods" % self.rtype.name, flags=idaapi.SN_FORCE)
            idaapi.autoWait()
Beispiel #3
0
    def parse(self):
        _debug("Struct Type @ 0x%x" % self.addr)
        # parse pkg path
        self.pkg_path_addr = read_mem(self.addr + self.rtype.self_size)
        if self.pkg_path_addr > 0 and self.pkg_path_addr != idc.BADADDR:
            self.pkg_path_obj = Name(self.pkg_path_addr, self.type_parser.moddata)
            self.pkg_path_obj.parse(False)
            self.pkg_path = self.pkg_path_obj.simple_name

        # parse fields
        fields_start_addr = read_mem(self.addr + self.rtype.self_size + ADDR_SZ)
        fields_cnt = read_mem(self.addr + self.rtype.self_size + 2*ADDR_SZ)
        fields_cap = read_mem(self.addr + self.rtype.self_size + 3*ADDR_SZ)
        for idx in xrange(fields_cnt):
            field = StructFiled(fields_start_addr + idx*3*ADDR_SZ, self.type_parser)
            field.parse()
            self.fields.append(field)

        idc.MakeComm(self.addr + self.rtype.self_size, "pkg path%s" % \
            (("(@ 0x%x): %s" % (self.pkg_path_addr, self.pkg_path)) if (self.pkg_path_addr>0 and len(self.pkg_path)>0) else ""))
        idc.MakeComm(self.addr + self.rtype.self_size + 2*ADDR_SZ, "fields count: 0x%x" % fields_cnt)
        idc.MakeComm(self.addr + self.rtype.self_size + 3*ADDR_SZ, "fileds capacity: 0x%x" % fields_cap)
        idaapi.autoWait()
        _debug("Struct pkg path: %s" % (("(@ 0x%x): %s" % (self.pkg_path_addr, self.pkg_path)) \
            if (self.pkg_path_addr>0 and len(self.pkg_path)>0) else ""))
        _debug("Struct fields num: 0x%x" % fields_cnt)

        if len(self.rtype.name) > 0 and fields_cnt > 0:
            idc.MakeComm(self.addr + self.rtype.self_size + ADDR_SZ, "fields start address")
            idc.MakeNameEx(fields_start_addr, "%s_fields" % self.rtype.name, flags=idaapi.SN_FORCE)
            idaapi.autoWait()
            _debug("Struct fields start addr: 0x%x" % fields_start_addr)
Beispiel #4
0
    def parse(self):
        self.name_obj_addr = read_mem(self.addr)
        if self.name_obj_addr == 0 or self.name_obj_addr == idc.BADADDR:
            raise Exception("Invalid name address when parsing struct field @ 0x%x" % self.addr)
        self.name_obj = Name(self.name_obj_addr, self.type_parser.moddata)
        self.name_obj.parse(False)
        self.name = self.name_obj.simple_name

        self.rtype_addr = read_mem(self.addr + ADDR_SZ)
        if self.rtype_addr == 0 or self.rtype_addr == idc.BADADDR:
            raise Exception("Invalid rtype address when parsing struct field @ 0x%x" % self.addr)
        if self.type_parser.has_been_parsed(self.rtype_addr):
            self.rtype = self.type_parser.parsed_types[self.rtype_addr]
        else:
            self.rtype = self.type_parser.parse_type(type_addr=self.rtype_addr)

        off_embeded = read_mem(self.addr + 2*ADDR_SZ)
        self.offset = off_embeded >> 1
        self.is_embeded = (off_embeded & 1) != 0

        idc.MakeComm(self.addr, "field name: %s" % self.name_obj.name_str)
        idaapi.autoWait()
        idc.MakeComm(self.addr + ADDR_SZ, "field rtype: %s" % self.rtype.name)
        idaapi.autoWait()
        _debug("Struct field name: %s" % self.name_obj.name_str)
        _debug("Struct field rtype: %s" % self.rtype.name)
Beispiel #5
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()
Beispiel #6
0
    def parse(self):
        _debug("Imethod Type @ 0x%x" % self.addr)
        name_off = read_mem(self.addr, forced_addr_sz=4) & 0xFFFFFFFF
        name_addr = (self.types_addr + name_off) & 0xFFFFFFFF
        self.name_obj = Name(name_addr, self.type_parser.moddata)
        self.name_obj.parse(False)
        self.name = self.name_obj.simple_name

        type_off = read_mem(self.addr+4, forced_addr_sz=4) & 0xFFFFFFFF
        type_addr = (self.types_addr + type_off) & 0xFFFFFFFF
        if type_off > 0 and type_addr != idc.BADADDR:
            if self.type_parser.has_been_parsed(type_addr):
                self.type = self.type_parser.parsed_types[type_addr].rtype
            else:
                self.type = self.type_parser.parse_type(type_addr=type_addr)

        if name_off > 0 and name_off != idc.BADADDR:
            idc.MakeComm(self.addr, "imethod name(@ 0x%x): %s" % (name_addr, self.name))
            idaapi.autoWait()
            _debug("Interface imethod name(@ 0x%x): %s" % (name_addr, self.name))

        if type_off > 0 and type_addr != idc.BADADDR:
            idc.MakeComm(self.addr + 4, "imethod type(@ 0x%x): %s" % (type_addr, self.type.name_obj.name_str))
            idaapi.autoWait()
            _debug("Interface imethod type(@ 0x%x): %s" % (type_addr, self.type.name_obj.name_str))
Beispiel #7
0
    def parse(self):
        itype_addr = common.read_mem(self.addr) & 0xFFFFFFFFFFFFFFFF
        self.itype = self.type_parser.parse_type(type_addr=itype_addr)

        rtype_addr = common.read_mem(self.addr+common.ADDR_SZ) & 0xFFFFFFFFFFFFFFFF
        self.rtype = self.type_parser.parse_type(type_addr=rtype_addr)

        self.hash = common.read_mem(self.addr + 2*common.ADDR_SZ, forced_addr_sz=4) & 0xFFFFFFFF

        # methods start addr(if has method)
        curr_addr = self.addr + 3*common.ADDR_SZ
        while True:
            if len(idaapi.get_ea_name(curr_addr)) > 0:
                # stop at next itab_elem addr
                # next itab elem is labeled a head name by ida pro
                break

            meth_addr = common.read_mem(curr_addr)
            if idaapi.get_func(meth_addr):
                meth_name = idaapi.get_ea_name(meth_addr)
                self.methods.append(meth_name)
                self.meth_num += 1

            curr_addr += common.ADDR_SZ

        idc.MakeComm(self.addr, "interface: %s" % self.itype.name)
        idc.MakeComm(self.addr+common.ADDR_SZ, "rtype: %s" % self.rtype.name)
        idc.MakeComm(self.addr+2*common.ADDR_SZ, "rtype hash")
        idaapi.autoWait()

        itab_elem_name = "go_itab__%s_%s" % (self.rtype.name_obj.name_str, self.itype.name)
        idc.MakeNameEx(self.addr, itab_elem_name,flags=idaapi.SN_FORCE)
        common._debug("Go itab %s(@ 0x%x) parsed." % (itab_elem_name, self.addr))
        idaapi.autoWait()
Beispiel #8
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(
            "--------------------------------------------------------------------------------------"
        )
Beispiel #9
0
    def parse(self):
        name_off = read_mem(self.addr, forced_addr_sz=4) & 0xFFFFFFFF
        if name_off > 0:
            self.name_addr = self.types_addr + name_off
            self.name_obj = Name(self.name_addr, self.type_parser.moddata)
            self.name_obj.parse(False)
            self.name = self.name_obj.simple_name

        # note: some methods are actually not present in the binary
        # for those, typeOff, ifn, tfn are 0
        type_off = read_mem(self.addr + 4, forced_addr_sz=4) & 0xFFFFFFFF
        if type_off > 0:
            self.mtype_addr = self.types_addr + type_off
            if self.type_parser.has_been_parsed(self.mtype_addr):
                self.mtype = self.type_parser.parsed_types[self.mtype_addr].rtype
            else:
                self.mtype = self.type_parser.parse_type(type_addr=self.mtype_addr)

        self.ifn_off = read_mem(self.addr + 8, forced_addr_sz=4) & 0xFFFFFFFF
        self.tfn_off = read_mem(self.addr + 12, forced_addr_sz=4) & 0xFFFFFFFF

        idc.MakeComm(self.addr, "Method Name%s" % \
            (("(@ 0x%x): %s" % (self.name_addr, self.name)) if (name_off>0 and len(self.name)>0) else ""))
        _debug("Ucommon type Method Name%s" % \
            (("(@ 0x%x): %s" % (self.name_addr, self.name)) if (name_off>0 and len(self.name)>0) else ""))

        idc.MakeComm(self.addr + 4, "Method Type%s" % \
            (("(@ 0x%x): %s" % (self.mtype_addr, self.mtype.name_obj.name_str)) if (type_off>0 and self.mtype is not None) else ""))
        _debug("Uncommon type Method Type%s" % \
            (("(@ 0x%x): %s" % (self.mtype_addr, self.mtype.name_obj.name_str)) if (type_off>0 and self.mtype is not None) else ""))

        self.ifn_addr = (self.text_addr + self.ifn_off) & 0xFFFFFFFF
        ifn_name = idc.get_func_name(self.ifn_addr)
        if ifn_name is None or len(ifn_name) == 0:
            if self.mtype is not None:
                ifn_name = self.mtype.name
            else:
                ifn_name == "_func_"
        idc.MakeComm(self.addr + 8, "ifn%s" % \
            (("(@ 0x%x): %s" % (self.ifn_addr, ifn_name)) if self.ifn_off>0 else ""))

        self.tfn_addr = (self.text_addr + self.tfn_off) & 0xFFFFFFFF
        tfn_name = idc.get_func_name(self.tfn_addr)
        if tfn_name is None or len(tfn_name) == 0:
            if self.mtype is not None:
                tfn_name = self.mtype.name
            else:
                tfn_name = "_func_"
        idc.MakeComm(self.addr + 12, "tfn%s" % \
            (("(@ 0x%x): %s" % (self.tfn_addr, tfn_name)) if self.tfn_off>0 else ""))

        idaapi.autoWait()
Beispiel #10
0
    def parse(self):
        self.para_cnt = read_mem(self.addr + self.rtype.self_size,
                                 forced_addr_sz=2) & 0xFFFF
        self.ret_cnt = read_mem(self.addr + self.rtype.self_size + 2,
                                forced_addr_sz=2) & 0xFFFF
        if self.ret_cnt & FuncType.VARIADIC_FLAG:
            self.is_variadic = True
            self.ret_cnt = self.ret_cnt & 0x7FFF
        self.padding = read_mem(self.addr + self.rtype.self_size + 4,
                                forced_addr_sz=4) & 0xFFFFFFFF
        if self.padding == 0:  # skip padding if present
            self.size += 4
        curr_addr = self.addr + self.size
        if self.rtype.is_uncomm():
            curr_addr += UncommonType.SIZE

        for in_idx in xrange(self.para_cnt):
            curr_para_type = None
            curr_para_type_off = curr_addr + in_idx * ADDR_SZ
            para_type_addr = read_mem(curr_para_type_off)
            self.para_type_addrs.append(para_type_addr)
            if self.type_parser.has_been_parsed(para_type_addr):
                curr_para_type = self.type_parser.parsed_types[para_type_addr]
            else:
                curr_para_type = self.type_parser.parse_type(
                    type_addr=para_type_addr)
            self.para_types.append(curr_para_type)
            idaapi.autoWait()

        curr_addr += self.para_cnt * ADDR_SZ
        for out_idx in xrange(self.ret_cnt):
            curr_ret_type = None
            curr_ret_type_off = curr_addr + out_idx * ADDR_SZ
            ret_type_addr = read_mem(curr_ret_type_off)
            self.ret_type_addrs.append(ret_type_addr)
            if self.type_parser.has_been_parsed(ret_type_addr):
                curr_ret_type = self.type_parser.parsed_types[ret_type_addr]
            else:
                curr_ret_type = self.type_parser.parse_type(
                    type_addr=ret_type_addr)
            self.ret_types.append(curr_ret_type)
            idaapi.autoWait()

        idc.MakeComm(self.addr + self.rtype.self_size,
                     "Parameter count: %d" % self.para_cnt)
        idc.MakeComm(self.addr + self.rtype.self_size + 2, "%s%s" % ("Flag: Varidic;" \
            if self.ret_cnt & FuncType.VARIADIC_FLAG else "", "Return value count: %d" % self.ret_cnt))
        idaapi.autoWait()
Beispiel #11
0
    def parse(self):
        elem_type_addr = read_mem(self.addr + self.rtype.self_size)
        if self.type_parser.has_been_parsed(elem_type_addr):
            self.elem_type = self.type_parser.parsed_types[elem_type_addr]
        else:
            self.elem_type = self.type_parser.parse_type(type_addr=elem_type_addr)
        self.elem_type.parse()

        dir_code = read_mem(self.addr + self.rtype.self_size + ADDR_SZ)
        self.direction = self.get_direction(dir_code)

        self.name = "channel %s (direction: %s)" % (self.rtype.name, self.direction)

        idc.MakeComm(self.addr + self.rtype.self_size, "elem type: %s" % self.elem_type.name)
        idc.MakeComm(self.addr + self.rtype.self_size + ADDR_SZ, "chan direction: %s" % self.direction)
        idaapi.autoWait()
Beispiel #12
0
def find_first_moduledata_addr():
    first_moduledata_addr = idc.BADADDR

    if not is_stripped(): # not stripped, find firstmoduledata by symbol name
        common._debug("Binary file is not stripped")
        for addr, name in idautils.Names():
            if name == "runtime.firstmoduledata":
                first_moduledata_addr = addr
                break
    else: # is stripped, find firstmodule data by bruteforce searching
        common._debug("Binary file is stripped")
        magic_num = pclntbl.Pclntbl.MAGIC
        # firstmoduledata is contained in segment [.noptrdata]
        mdata_seg_addr = get_mdata_seg_addr()
        if mdata_seg_addr == None:
            raise Exception("Invalid address of segment [.noptrdata]")
        if mdata_seg_addr == 0:
            common._error("Failed to find valid segment [.noptrdata]")

        curr_addr = mdata_seg_addr
        while curr_addr <= idc.BADADDR:
            if idc.Dword(read_mem(curr_addr, read_only=True)) & 0xFFFFFFFF == magic_num: # possible firstmoduledata
                if test_firstmoduledata(curr_addr):
                    break
            curr_addr += ADDR_SZ
        
        if curr_addr >= idc.BADADDR:
            raise Exception("Failed to find firstmoduledata address!")
        first_moduledata_addr = curr_addr

    return first_moduledata_addr
Beispiel #13
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)    
Beispiel #14
0
    def parse(self):
        _debug("Map Type @ 0x%x" % self.addr)
        map_attr_addr = self.addr + self.rtype.self_size

        key_type_addr = read_mem(map_attr_addr)
        if self.type_parser.has_been_parsed(key_type_addr):
            self.key_type = self.type_parser.parsed_types[key_type_addr]
        else:
            self.key_type = self.type_parser.parse_type(type_addr=key_type_addr)

        elem_type_addr = read_mem(map_attr_addr + ADDR_SZ)
        if self.type_parser.has_been_parsed(elem_type_addr):
            self.elem_type = self.type_parser.parsed_types[elem_type_addr]
        else:
            self.elem_type = self.type_parser.parse_type(type_addr=elem_type_addr)

        buck_type_addr = read_mem(map_attr_addr + 2*ADDR_SZ)
        if self.type_parser.has_been_parsed(buck_type_addr):
            self.buck_type = self.type_parser.parsed_types[buck_type_addr]
        else:
            self.buck_type = self.type_parser.parse_type(type_addr=buck_type_addr)

        if self.go_subver < 14:
            self.key_size = idc.Byte(map_attr_addr + 3*ADDR_SZ) & 0xFF
            self.val_size = idc.Byte(map_attr_addr + 3*ADDR_SZ + 1) & 0xFF
            self.buck_size = read_mem(map_attr_addr + 3*ADDR_SZ + 2, forced_addr_sz=2) & 0xFFFF
            self.flags = read_mem(map_attr_addr + 3*ADDR_SZ + 4, forced_addr_sz=4) & 0xFFFFFFFF
        else:
            self.hasher_func_addr = read_mem(map_attr_addr + 3*ADDR_SZ)
            self.key_size = idc.Byte(map_attr_addr + 4*ADDR_SZ) & 0xFF
            self.val_size = idc.Byte(map_attr_addr + 4*ADDR_SZ + 1) & 0xFF
            self.buck_size = read_mem(map_attr_addr + 4*ADDR_SZ + 2, forced_addr_sz=2) & 0xFFFF
            self.flags = read_mem(map_attr_addr + 4*ADDR_SZ + 4, forced_addr_sz=4) & 0xFFFFFFFF

        self.name = "map [%s]%s" % (self.key_type.name, self.elem_type.name)

        idc.MakeComm(map_attr_addr, "Key type: %s" % self.key_type.name)
        idc.MakeComm(map_attr_addr + ADDR_SZ, "Elem type: %s " % self.elem_type.name)
        idc.MakeComm(map_attr_addr + 2*ADDR_SZ, "Bucket type: %s" % self.buck_type.name)
        if self.go_subver < 14:
            idc.MakeComm(map_attr_addr + 3*ADDR_SZ, "Key size: 0x%x" % self.key_size)
            idc.MakeComm(map_attr_addr + 3*ADDR_SZ + 1, "Value size: 0x%x" % self.val_size)
            idc.MakeComm(map_attr_addr + 3*ADDR_SZ + 2, "Bucket size: 0x%x" % self.buck_size)
            idc.MakeComm(map_attr_addr + 3*ADDR_SZ + 4, "Flags: 0x%x" % self.flags)
        else:
            idc.MakeComm(map_attr_addr + 3*ADDR_SZ, "hash function for hashing keys (ptr to key, seed) -> hash")
            idc.MakeComm(map_attr_addr + 4*ADDR_SZ, "Key size: 0x%x" % self.key_size)
            idc.MakeComm(map_attr_addr + 4*ADDR_SZ + 1, "Value size: 0x%x" % self.val_size)
            idc.MakeComm(map_attr_addr + 4*ADDR_SZ + 2, "Bucket size: 0x%x" % self.buck_size)
            idc.MakeComm(map_attr_addr + 4*ADDR_SZ + 4, "Flags: 0x%x" % self.flags)
        idaapi.autoWait()

        _debug("Map Key type: %s" % self.key_type.name)
        _debug("Map Elem type: %s " % self.elem_type.name)
Beispiel #15
0
    def parse(self):
        self.elem_type_addr = read_mem(self.addr + self.rtype.self_size)
        if self.type_parser.has_been_parsed(self.elem_type_addr):
            self.elem_rtype = self.type_parser.parsed_types[self.elem_type_addr]
        else:
            self.elem_rtype = self.type_parser.parse_type(type_addr=self.elem_type_addr)

        idc.MakeComm(self.addr + self.rtype.self_size, "elem rtype: %s" % self.elem_rtype.name)
        idc.MakeNameEx(self.addr, "%s_slice" % self.elem_rtype.name, flags=idaapi.SN_FORCE)
        idaapi.autoWait()
Beispiel #16
0
    def parse(self):
        elem_type_addr = read_mem(self.addr + self.rtype.self_size)
        if self.type_parser.has_been_parsed(elem_type_addr):
            self.elem_type = self.type_parser.parsed_types[elem_type_addr]
        else:
            self.elem_type = self.type_parser.parse_type(type_addr=elem_type_addr)

        slice_type_addr = read_mem(self.addr + self.rtype.self_size + ADDR_SZ)
        if self.type_parser.has_been_parsed(slice_type_addr):
            self.slice_type = self.type_parser.parsed_types[slice_type_addr]
        else:
            self.slice_type = self.type_parser.parse_type(type_addr=slice_type_addr)

        self.len = read_mem(self.addr + self.rtype.self_size + 2 * ADDR_SZ)

        idc.MakeComm(self.addr + self.rtype.self_size, "elem type: %s" % self.elem_type.name)
        idc.MakeComm(self.addr + self.rtype.self_size + ADDR_SZ, "slice type: %s" % self.slice_type.name)
        idc.MakeNameEx(self.addr, "%s_array" % self.elem_type.name, flags=idaapi.SN_FORCE)
        idaapi.autoWait()
Beispiel #17
0
def test_firstmoduledata(possible_addr):
    '''
    Check if current addr is first module data
    '''
    mod_data = ModuleData(possible_addr)
    mod_data.parse(is_test=True)

    if read_mem(mod_data.pclntbl_addr + 8 + ADDR_SZ, read_only=True) == mod_data.text_addr:
        print("Find firstmoduledata @ 0x%x" % possible_addr)
        return True
    return False
Beispiel #18
0
    def parse(self):
        self.target_type_addr = read_mem(self.addr + self.rtype.self_size)
        if self.type_parser.has_been_parsed(self.target_type_addr):
            self.target_rtype = self.type_parser.parsed_types[self.target_type_addr]
        else:
            self.target_rtype = self.type_parser.parse_type(type_addr=self.target_type_addr)
        if self.target_rtype:
            self.name = self.target_rtype.name + "_ptr"

        idc.MakeComm(self.addr + self.rtype.self_size, "target rtype: %s" % self.target_rtype.name)
        idaapi.autoWait()
Beispiel #19
0
    def parse(self):
        name_off = read_mem(self.addr, forced_addr_sz=4)
        name_addr = (self.types_addr + name_off) & 0xFFFFFFFF
        self.name_obj = Name(name_addr, self.type_parser.moddata)
        self.name_obj.parse(False)
        self.name = self.name_obj.simple_name

        type_off = read_mem(self.addr+4, forced_addr_sz=4)
        type_addr = (self.types_addr + type_off) & 0xFFFFFFFF
        if type_off > 0 and type_addr != idc.BADADDR:
            if self.type_parser.has_been_parsed(type_addr):
                self.type = self.type_parser.parsed_types[type_addr].rtype
            else:
                self.type = self.type_parser.parse_type(type_addr=type_addr)

        if name_off > 0 and name_off != idc.BADADDR:
            idc.MakeComm(self.addr, "imethod name: %s (@ 0x%x)" % (self.name, name_addr))
            idaapi.autoWait()

        if type_off > 0 and type_addr != idc.BADADDR:
            idc.MakeComm(self.addr + 4, "imethod type: %s (@ 0x%x)" % (self.type.name_obj.name_str, type_addr))
Beispiel #20
0
    def parse(self):
        _debug("PtrType @ 0x%x" % self.addr)
        self.target_type_addr = read_mem(self.addr + self.rtype.self_size)
        if self.type_parser.has_been_parsed(self.target_type_addr):
            self.target_rtype = self.type_parser.parsed_types[self.target_type_addr]
            self.target_rtype_origname = self.target_rtype.rtype.name_obj.orig_name_str
        else:
            self.target_rtype = self.type_parser.parse_type(type_addr=self.target_type_addr)
            self.target_rtype_origname = self.target_rtype.name_obj.orig_name_str
        if self.target_rtype:
            self.name = self.target_rtype.name + "_ptr"

        idc.MakeComm(self.addr + self.rtype.self_size, "target rtype: %s" % self.target_rtype_origname)
        idaapi.autoWait()
        _debug("target rtype: %s" % self.target_rtype_origname)
Beispiel #21
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()))
Beispiel #22
0
def find_first_moduledata_addr_by_brute():
    magic_num = pclntbl.Pclntbl.MAGIC
    first_moduledata_addr = idc.BADADDR

    segn = ida_segment.get_segm_qty()
    for idx in range(segn):
        curr_seg = ida_segment.getnseg(idx)
        curr_addr = curr_seg.start_ea
        while curr_addr <= curr_seg.end_ea:
            if idc.Dword(
                    read_mem(curr_addr, read_only=True)
            ) & 0xFFFFFFFF == magic_num:  # possible firstmoduledata
                if test_firstmoduledata(curr_addr):
                    break
            curr_addr += ADDR_SZ

        if curr_addr >= curr_seg.end_ea:
            continue

        first_moduledata_addr = curr_addr
        break

    return first_moduledata_addr
Beispiel #23
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()
Beispiel #24
0
    def parse(self, is_test=False):
        if is_test:
            common._info("Test firstmoduledata addr: 0x%x" % self.start_addr)

        self.pclntbl_addr = read_mem(self.start_addr, read_only=is_test)
        self.pclntbl_sz = read_mem(self.start_addr + ADDR_SZ,
                                   read_only=is_test)
        self.pclntbl_cap = read_mem(self.start_addr + 2 * ADDR_SZ,
                                    read_only=is_test)
        self.ftab_addr = read_mem(self.start_addr + 3 * ADDR_SZ,
                                  read_only=is_test)
        self.func_num = read_mem(self.start_addr + 4 * ADDR_SZ,
                                 read_only=is_test)
        self.ftab_cap = read_mem(self.start_addr + 5 * ADDR_SZ,
                                 read_only=is_test)
        self.filetab_addr = read_mem(self.start_addr + 6 * ADDR_SZ,
                                     read_only=is_test)
        self.srcfile_num = read_mem(self.start_addr + 7 * ADDR_SZ,
                                    read_only=is_test)
        self.srcfile_tab_cap = read_mem(self.start_addr + 8 * ADDR_SZ,
                                        read_only=is_test)
        self.findfunctab = read_mem(self.start_addr + 9 * ADDR_SZ,
                                    read_only=is_test)
        self.min_pc = read_mem(self.start_addr + 10 * ADDR_SZ,
                               read_only=is_test)
        self.max_pc = read_mem(self.start_addr + 11 * ADDR_SZ,
                               read_only=is_test)
        self.text_addr = read_mem(self.start_addr + 12 * ADDR_SZ,
                                  read_only=is_test)
        self.etext_addr = read_mem(self.start_addr + 13 * ADDR_SZ,
                                   read_only=is_test)
        if is_test:
            return
        self.noptrdata_addr = read_mem(self.start_addr + 14 * ADDR_SZ,
                                       read_only=is_test)
        self.enoptrdata_addr = read_mem(self.start_addr + 15 * ADDR_SZ,
                                        read_only=is_test)
        self.data_addr = read_mem(self.start_addr + 16 * ADDR_SZ,
                                  read_only=is_test)
        self.edata_addr = read_mem(self.start_addr + 17 * ADDR_SZ,
                                   read_only=is_test)
        self.bss_addr = read_mem(self.start_addr + 18 * ADDR_SZ,
                                 read_only=is_test)
        self.ebss_addr = read_mem(self.start_addr + 19 * ADDR_SZ,
                                  read_only=is_test)
        self.noptrbss_addr = read_mem(self.start_addr + 20 * ADDR_SZ,
                                      read_only=is_test)
        self.enoptrbss_addr = read_mem(self.start_addr + 21 * ADDR_SZ,
                                       read_only=is_test)
        self.end_addr = read_mem(self.start_addr + 22 * ADDR_SZ,
                                 read_only=is_test)
        self.gcdata_addr = read_mem(self.start_addr + 23 * ADDR_SZ,
                                    read_only=is_test)
        self.gcbss_addr = read_mem(self.start_addr + 24 * ADDR_SZ,
                                   read_only=is_test)
        self.types_addr = read_mem(self.start_addr + 25 * ADDR_SZ,
                                   read_only=is_test)
        self.etypes_addr = read_mem(self.start_addr + 26 * ADDR_SZ,
                                    read_only=is_test)
        self.textsecmap_addr = read_mem(self.start_addr + 27 * ADDR_SZ,
                                        read_only=is_test)
        self.textsecmap_len = read_mem(self.start_addr + 28 * ADDR_SZ,
                                       read_only=is_test)
        self.textsecmap_cap = read_mem(self.start_addr + 29 * ADDR_SZ,
                                       read_only=is_test)
        self.typelink_addr = read_mem(self.start_addr + 30 * ADDR_SZ,
                                      read_only=is_test)
        self.type_num = read_mem(self.start_addr + 31 * ADDR_SZ,
                                 read_only=is_test)
        self.type_cap = read_mem(self.start_addr + 32 * ADDR_SZ,
                                 read_only=is_test)
        self.itablink_addr = read_mem(self.start_addr + 33 * ADDR_SZ,
                                      read_only=is_test)
        self.itab_num = read_mem(self.start_addr + 34 * ADDR_SZ,
                                 read_only=is_test)
        self.itab_cap = read_mem(self.start_addr + 35 * ADDR_SZ,
                                 read_only=is_test)
        self.ptab_addr = read_mem(self.start_addr + 36 * ADDR_SZ,
                                  read_only=is_test)
        self.ptab_num = read_mem(self.start_addr + 37 * ADDR_SZ,
                                 read_only=is_test)
        self.ptab_cap = read_mem(self.start_addr + 38 * ADDR_SZ,
                                 read_only=is_test)

        pluginpath_addr = read_mem(self.start_addr + 39 * ADDR_SZ,
                                   read_only=is_test)
        pluginpath_len = read_mem(self.start_addr + 40 * ADDR_SZ,
                                  read_only=is_test)
        self.pluginpath = str(idc.GetManyBytes(pluginpath_addr,
                                               pluginpath_len))

        modulename_addr = read_mem(self.start_addr + 44 * ADDR_SZ,
                                   read_only=is_test)
        modulename_len = read_mem(self.start_addr + 45 * ADDR_SZ,
                                  read_only=is_test)
        self.modulename = str(idc.GetManyBytes(modulename_addr,
                                               modulename_len))

        self.hasmain = idc.Byte(self.start_addr + 49 * ADDR_SZ)
        self.next = read_mem(self.start_addr + 54 * ADDR_SZ + 1,
                             read_only=is_test)

        if not is_test:
            idc.MakeNameEx(self.start_addr,
                           "runtime.firstmoduledata",
                           flags=idaapi.SN_FORCE)
            idaapi.autoWait()

            idc.MakeComm(self.start_addr, "pclntbl addr")
            idc.MakeComm(self.start_addr + ADDR_SZ, "pclntbl size")
            idc.MakeComm(self.start_addr + 2 * ADDR_SZ, "pclntbl capacity")
            idc.MakeComm(self.start_addr + 3 * ADDR_SZ, "funcs table addr")
            idc.MakeComm(self.start_addr + 4 * ADDR_SZ, "funcs number")
            idc.MakeComm(self.start_addr + 5 * ADDR_SZ, "funcs table capacity")
            idc.MakeComm(self.start_addr + 6 * ADDR_SZ,
                         "source files table addr")
            idc.MakeComm(self.start_addr + 7 * ADDR_SZ, "source files number")
            idc.MakeComm(self.start_addr + 7 * ADDR_SZ,
                         "source files table capacity")
            idc.MakeComm(self.start_addr + 9 * ADDR_SZ, "findfunctable addr")
            idc.MakeComm(self.start_addr + 10 * ADDR_SZ, "min pc")
            idc.MakeComm(self.start_addr + 11 * ADDR_SZ, "max pc")
            idc.MakeComm(self.start_addr + 12 * ADDR_SZ, "text start addr")
            idc.MakeComm(self.start_addr + 13 * ADDR_SZ, "text end addr")
            idc.MakeComm(self.start_addr + 14 * ADDR_SZ,
                         "noptrdata start addr")
            idc.MakeComm(self.start_addr + 15 * ADDR_SZ, "noptrdata end addr")
            idc.MakeComm(self.start_addr + 16 * ADDR_SZ,
                         "data section start addr")
            idc.MakeComm(self.start_addr + 17 * ADDR_SZ,
                         "data section end addr")
            idc.MakeComm(self.start_addr + 18 * ADDR_SZ, "bss start addr")
            idc.MakeComm(self.start_addr + 19 * ADDR_SZ, "bss end addr")
            idc.MakeComm(self.start_addr + 20 * ADDR_SZ, "noptrbss start addr")
            idc.MakeComm(self.start_addr + 21 * ADDR_SZ, "noptrbss end addr")
            idc.MakeComm(self.start_addr + 22 * ADDR_SZ,
                         "end addr of whole image")
            idc.MakeComm(self.start_addr + 23 * ADDR_SZ, "gcdata addr")
            idc.MakeComm(self.start_addr + 24 * ADDR_SZ, "gcbss addr")
            idc.MakeComm(self.start_addr + 25 * ADDR_SZ, "types start addr")
            idc.MakeComm(self.start_addr + 26 * ADDR_SZ, "types end addr")
            idc.MakeComm(self.start_addr + 27 * ADDR_SZ,
                         "test section map addr")
            idc.MakeComm(self.start_addr + 28 * ADDR_SZ,
                         "test section map length")
            idc.MakeComm(self.start_addr + 29 * ADDR_SZ,
                         "test section map capacity")
            idc.MakeComm(self.start_addr + 30 * ADDR_SZ, "typelink addr")
            idc.MakeComm(self.start_addr + 31 * ADDR_SZ, "types number")
            idc.MakeComm(self.start_addr + 32 * ADDR_SZ,
                         "types table capacity")
            idc.MakeComm(self.start_addr + 33 * ADDR_SZ, "itabslink addr")
            idc.MakeComm(self.start_addr + 34 * ADDR_SZ, "itabs number")
            idc.MakeComm(self.start_addr + 35 * ADDR_SZ, "itabs caapacity")
            idc.MakeComm(self.start_addr + 36 * ADDR_SZ, "ptab addr")
            idc.MakeComm(self.start_addr + 37 * ADDR_SZ, "ptab num")
            idc.MakeComm(self.start_addr + 38 * ADDR_SZ, "ptab capacity")
            idc.MakeComm(self.start_addr + 39 * ADDR_SZ, "plugin path addr")
            idc.MakeComm(self.start_addr + 40 * ADDR_SZ, "plugin path length")
            idc.MakeComm(self.start_addr + 44 * ADDR_SZ, "module name addr")
            idc.MakeComm(self.start_addr + 45 * ADDR_SZ, "module name length")
            idc.MakeComm(self.start_addr + 49 * ADDR_SZ, "hasmain flag")
            idc.MakeComm(self.start_addr + 54 * ADDR_SZ + 1,
                         "next moduledata addr")
            idaapi.autoWait()

            idc.MakeStr(modulename_addr, modulename_addr + modulename_len)
            idaapi.autoWait()
            idc.MakeStr(pluginpath_addr, pluginpath_addr + pluginpath_len)
            idaapi.autoWait()
Beispiel #25
0
    def parse(self, has_star_prefix):
        flag_byte = idc.Byte(self.addr) & 0xFF
        self.is_exported = flag_byte & self.EXPORTED != 0
        self.is_followed_by_tag = flag_byte & self.FOLLOWED_BY_TAG != 0
        self.is_followed_by_pkgpath = flag_byte & self.FOLLOWED_BY_PKGPATH != 0

        self.len = ((idc.Byte(self.addr + 1) & 0xFF << 8) | (idc.Byte(self.addr + 2) & 0xFF)) & 0xFFFF
        self.orig_name_str = str(idc.GetManyBytes(self.addr + 3, self.len))
        self.name_str = self.orig_name_str
        # delete star_prefix:
        while True:
            if self.name_str[0] == '*':
                self.name_str = self.name_str[1:]
            else:
                break

        if self.is_followed_by_tag:
            self.tag_len = (idc.Byte(self.addr+ 3 + self.len) & 0xFF << 8) \
                | (idc.Byte(self.addr + 3 + self.len + 1) & 0xFF)
            self.tag = str(idc.GetManyBytes(self.addr + 3 + self.len + 2, self.tag_len))

        # if name was reased, the replace name string with tag string
        if (not self.name_str or len(self.name_str) == 0) and self.tag and self.tag_len > 0:
            self.name_str = self.tag
            self.len = self.tag_len

        if self.is_followed_by_pkgpath:
            pkgpath_off_addr = self.addr + 3 + self.len
            if self.is_followed_by_tag:
                pkgpath_off_addr += (self.tag_len + 2)
            pkgpath_off = read_mem(pkgpath_off_addr, forced_addr_sz=4) & 0xFFFFFFFF
            if pkgpath_off > 0:
                pkgpath_addr = self.moddata.types_addr + pkgpath_off
                pkgpath_name_obj = Name(pkgpath_addr, self.moddata)
                pkgpath_name_obj.parse(False)
                self.pkg = pkgpath_name_obj.name_str
                self.pkg_len = len(self.pkg)

                if self.pkg_len:
                    idc.MakeComm(pkgpath_off_addr, "pkgpath(@ 0x%x): %s" % (pkgpath_addr, self.pkg))
                    idaapi.autoWait()

        self.full_name = "%s%s%s" % (self.pkg if self.pkg else "", ("_%s" % self.name_str) \
            if self.pkg else self.name_str, ('_%s' % self.tag) if self.tag else "")
        self.simple_name = "%s%s" % (self.pkg if self.pkg else "", ("_%s" % self.name_str) \
            if self.pkg else self.name_str)

        flag_comm_str = "flag: "
        if self.is_exported:
            flag_comm_str += "exported"
        if self.is_followed_by_tag:
            if self.is_exported:
                flag_comm_str += ", followed by tag"
            else:
                flag_comm_str += "followed by tag"
        if self.is_followed_by_pkgpath:
            if self.is_exported or self.is_followed_by_tag:
                flag_comm_str += ", followed by pkgpath"
            else:
                flag_comm_str += "followed by pkgpath"
        if len(flag_comm_str) > 6: # has valid flag
            idc.MakeComm(self.addr, flag_comm_str)
            idaapi.autoWait()

        idc.MakeStr(self.addr + 3, self.addr + 3 + self.len)
        idaapi.autoWait()
        if self.is_followed_by_tag:
            idc.MakeStr(self.addr + 3 + self.len + 2, self.addr + 3 + self.len + 2 + self.tag_len)
            idc.MakeComm(self.addr + 3 + self.len + 2, "tag of @ 0x%x" % self.addr)
            idaapi.autoWait()
Beispiel #26
0
    def parse(self):
        _debug("RType @ 0x%x" % self.addr)
        self.size = read_mem(self.addr)
        self.ptrdata = read_mem(self.addr + ADDR_SZ)
        self.hash = read_mem(self.addr + 2*ADDR_SZ, forced_addr_sz=4) & 0xFFFFFFFF
        self.tflag = idc.Byte(self.addr + 2*ADDR_SZ + 4) & 0xFF
        self.align = idc.Byte(self.addr + 2*ADDR_SZ + 5) & 0xFF
        self.field_align = idc.Byte(self.addr + 2*ADDR_SZ + 6) & 0xFF
        self.kind = idc.Byte(self.addr + 2*ADDR_SZ + 7) & 0xFF & RType.KIND_MASK
        self.alg = read_mem(self.addr + 2*ADDR_SZ + 8)
        self.gcdata = read_mem(self.addr + 3*ADDR_SZ + 8)

        self.name_off = read_mem(self.addr + 4*ADDR_SZ + 8, forced_addr_sz=4) & 0xFFFFFFFF
        self.name_addr = (self.moddata.types_addr + self.name_off) & 0xFFFFFFFF

        self.ptrtothis_off = read_mem(self.addr + 4*ADDR_SZ + 12, forced_addr_sz=4) & 0xFFFFFFFF
        if self.ptrtothis_off > 0:
            self.ptrtothis_addr = (self.moddata.types_addr + self.ptrtothis_off) & 0xFFFFFFFF

        idc.MakeComm(self.addr, "type size")
        idc.MakeComm(self.addr + ADDR_SZ, "type ptrdata")
        idc.MakeComm(self.addr + 2*ADDR_SZ, "type hash")

        tflag_comm = "tflag:"
        if self.has_star_prefix():
            tflag_comm += " Star Prefix;"
        if self.is_named():
            tflag_comm += " Named;"
        if self.is_uncomm():
            tflag_comm += " Uncommon"
        idc.MakeComm(self.addr + 2*ADDR_SZ + 4, tflag_comm)
        _debug(tflag_comm)

        idc.MakeComm(self.addr + 2*ADDR_SZ + 5, "align")
        idc.MakeComm(self.addr + 2*ADDR_SZ + 6, "field align")
        idc.MakeComm(self.addr + 2*ADDR_SZ + 7, "kind: %s" % self.get_kind())
        idc.MakeComm(self.addr + 2*ADDR_SZ + 8, "alg")
        idc.MakeComm(self.addr + 3*ADDR_SZ + 8, "gcdata")
        _debug("kind: %s" % self.get_kind())

        if self.ptrtothis_off > 0:
            idc.MakeComm(self.addr + 4*ADDR_SZ + 12, "ptrtothis addr: 0x%x" % self.ptrtothis_addr)
            _debug("ptrtothis addr: 0x%x" % self.ptrtothis_addr)
        else:
            idc.MakeComm(self.addr + 4*ADDR_SZ + 12, "ptrtothis addr")
        idaapi.autoWait()

        self.name_obj = Name(self.name_addr, self.moddata)
        self.name_obj.parse(self.has_star_prefix())
        self.name = self.name_obj.simple_name

        idc.MakeComm(self.addr + 4*ADDR_SZ + 8, "name(@ 0x%x ): %s" % (self.name_addr, self.name_obj.orig_name_str))
        _debug("name(@ 0x%x ): %s" % (self.name_addr, self.name_obj.orig_name_str))

        # if a raw type is un-named, and name string is erased, the name it as it's kind string
        if len(self.name) == 0 and self.type_parser.is_raw_type(self.get_kind()) and not self.is_named():
            self.name = self.get_kind()

        # if an un-raw type is named, then concat a kind string as suffix with it's name
        if len(self.name) > 0 and self.is_named() and not self.type_parser.is_raw_type(self.get_kind()):
            self.name += ("_%s" % self.get_kind().lower())

        if self.get_kind() == "Struct" and not self.is_named(): # un-named struct type
            self.name = "_struct_"

        if self.get_kind() == "Func" and not self.is_named(): # un-named func type
            self.name = "_func_"

        if self.get_kind() == "Ptr":
            self.name += "_ptr"

        if len(self.name) > 0:
            idc.MakeNameEx(self.addr, self.name, flags=idaapi.SN_FORCE)
            idaapi.autoWait()

        # parse type pointer
        if self.ptrtothis_off > 0 and self.ptrtothis_addr != idc.BADADDR:
            if self.type_parser.has_been_parsed(self.ptrtothis_addr):
                self.ptrtothis = self.type_parser.parsed_types[self.ptrtothis_addr]
            else:
                self.ptrtothis = self.type_parser.parse_type(type_addr=self.ptrtothis_addr)
            idaapi.autoWait()
Beispiel #27
0
def parse_str_ptr(addr):
    if idc.GetMnem(addr) != 'mov':
        return False

    # Validate that the string offset actually exists inside the binary
    if idc.get_segm_name(idc.GetOperandValue(addr, 1)) is None:
        return False

    # Check the operands' type:
    # - first one must be a register;
    # - second one must be a memory address
    if idc.GetOpType(addr, 0) != 1 or idc.GetOpType(addr, 1) != 2:
        return False

    addr_2 = idc.FindCode(addr, idaapi.SEARCH_DOWN)
    # same operands' type for addr_2
    if idc.GetMnem(addr_2) != 'mov' or idc.GetOpType(
            addr_2, 0) != 1 or idc.GetOpType(addr_2, 1) != 2:
        return False

    opnd_val_1 = idc.GetOperandValue(addr, 1)
    opnd_val_2 = idc.GetOperandValue(addr_2, 1)
    opnd_diff = opnd_val_1 - opnd_val_2
    # The 2 operands, one of addr of string length, another one is the addr of string pointer
    # and they must be side by side
    if opnd_diff != common.ADDR_SZ and opnd_diff != -common.ADDR_SZ:
        return False

    if opnd_diff > 0:
        str_len_addr, str_ptr_addr = opnd_val_1, opnd_val_2
    else:
        str_len_addr, str_ptr_addr = opnd_val_2, opnd_val_1

    str_len = common.read_mem(str_len_addr)
    str_ptr = common.read_mem(str_ptr_addr)
    str_addr = common.read_mem(str_ptr)

    # set max str len
    if str_len > 64:
        return False

    if 'rodata' not in idc.get_segm_name(
            str_ptr) and 'text' not in idc.get_segm_name(str_ptr):
        return False

    common._debug("------------------------------")
    common._debug("Possible str ptr:")
    common._debug("Code addr: 0x%x , str_ptr_addr: 0x%x , str_len_addr: 0x%x" %
                  (addr, str_ptr_addr, str_len_addr))
    common._debug("str_addr: 0x%x , str_len: 0x%x" % (str_ptr, str_len))
    #if create_string(str_addr, str_len):
    if str_len > 1:
        if idc.MakeStr(str_ptr, str_ptr + str_len):
            idaapi.autoWait()
            if opnd_diff > 0:
                idc.MakeComm(addr, "length: %d" % str_len)
                idaapi.add_dref(addr_2, str_ptr, idaapi.dr_O)
            else:
                idc.MakeComm(addr_2, "length: %d" % str_len)
                idaapi.add_dref(addr, str_ptr, idaapi.dr_O)
            idaapi.autoWait()
            return True

    return False