Exemple #1
0
def create_string(addr, string_len):
    # if idaapi.get_segm_name(addr) is None:
    if idc.get_segm_name(addr) is None:
        common._debug(
            'Cannot load a string which has no segment - not creating string @ 0x%02x'
            % addr)
        return False

    common._debug('Found string load @ 0x%x with length of %d' %
                  (addr, string_len))
    # This may be overly aggressive if we found the wrong area...
    if idc.GetStringType(addr) is not None and idc.GetString(
            addr) is not None and len(idc.GetString(addr)) != string_len:
        common._debug(
            'It appears that there is already a string present @ 0x%x' % addr)
        idc.MakeUnknown(addr, string_len, idc.DOUNK_SIMPLE)
        idaapi.autoWait()

    if idc.GetString(addr) is None and idc.MakeStr(addr, addr + string_len):
        idaapi.autoWait()
        return True
    else:
        # If something is already partially analyzed (incorrectly) we need to MakeUnknown it
        idc.MakeUnknown(addr, string_len, idc.DOUNK_SIMPLE)
        idaapi.autoWait()
        if idc.MakeStr(addr, addr + string_len):
            idaapi.autoWait()
            return True
        common._debug('Unable to make a string @ 0x%x with length of %d' %
                      (addr, string_len))

    return False
Exemple #2
0
    def _try_all_type_string(cls, addr_to_stringify):
        import string
        string.printable
        if idc.MakeStr(addr_to_stringify, idc.BADADDR):
            return True
        # Try bytes by bytes:
        if idc.MakeStr(addr_to_stringify, addr_to_stringify + 0):
            return True
        if not idc.MakeStr(addr_to_stringify, addr_to_stringify + 1):
            return False
        # String created : try to create the biggest string possible with only ascci
        for i in itertools.count(1):
            if not chr(
                    ByteData(addr_to_stringify + i).value) in string.printable:
                return True
            if not idc.MakeStr(addr_to_stringify, addr_to_stringify + i):
                return True

        #old_INF_STRTYPE = idc.GetLongPrm(idc.INF_STRTYPE)
        #for i in range(len(cls.type_value)):
        #    idc.SetLongPrm(idc.INF_STRTYPE, i)
        #    if idc.MakeStr(addr_to_stringify, idc.BADADDR):
        #        idc.SetLongPrm(idc.INF_STRTYPE, old_INF_STRTYPE)
        #        return True
        #idc.SetLongPrm(idc.INF_STRTYPE, old_INF_STRTYPE)
        return False
Exemple #3
0
    def parse_impexp(self, top, end, cls, callback):
        arr = []
        cur = top
        while cur < end:
            impexp_foffset = self.phdr_modinfo.p_offset + cur
            impexp_addr = idaapi.get_fileregion_ea(impexp_foffset)

            self.fin.seek(impexp_foffset)
            impexp = cls(self.fin.read(cls.SIZE))
            if impexp.library_name_ptr:
                library_name_foffset = self.phdr_modinfo.p_offset + impexp.library_name_ptr - self.phdr_modinfo.p_vaddr
                self.fin.seek(library_name_foffset)
                
                # create a library name string
                idc.MakeStr(idaapi.get_fileregion_ea(library_name_foffset), idc.BADADDR)

                data = self.fin.read(256)
                impexp.library_name = c_str(data)

            # apply struct
            apply_struct(impexp_addr, cls._find_or_create_struct())
            #idc.MakeComm(impexp_addr, "{}".format(impexp.library_name))

            arr.append(impexp)
            cur += impexp.size

        for impexp in arr:
            for x in xrange(impexp.num_syms_funcs):
                self.fin.seek(self.phdr_modinfo.p_offset + impexp.nid_table - self.phdr_modinfo.p_vaddr + x * 4)
                nid = u32(self.fin.read(4))
                self.fin.seek(self.phdr_modinfo.p_offset + impexp.entry_table - self.phdr_modinfo.p_vaddr + x * 4)
                func = u32(self.fin.read(4))

                callback(impexp, func, nid)
Exemple #4
0
def get_goroot():
    goroot_path_str = ""
    '''
    Get GOROOT path string
    '''
    func_goroot = find_func_by_name("runtime_GOROOT")
    if func_goroot is None:
        _error("Failed to find func contains goroot")
        return goroot_path_str

    goroot_flowchart = idaapi.FlowChart(f=func_goroot)
    ret_cbs = find_ret_cb(goroot_flowchart)
    '''
    runtime.GOROOT() normally has 2 return code blocks:
    1. False return
        mov     [rsp+28h+arg_0], rax
        mov     [rsp+28h+arg_8], rcx
        mov     rbp, [rsp+28h+var_8]
        add     rsp, 28h
        retn

    2. True return(Which we needed):
        mov     rax, cs:runtime_internal_sys_DefaultGoroot
        mov     rcx, cs:qword_D9AB58
        mov     [rsp+28h+arg_0], rax
        mov     [rsp+28h+arg_8], rcx
        mov     rbp, [rsp+28h+var_8]
        add     rsp, 28h
        retn
    '''
    for cb_idx in ret_cbs:
        if idc.GetOpType(goroot_flowchart[cb_idx].startEA, 0) == 1:
            # e.g.: mov     rax, cs:runtime_internal_sys_DefaultGoroot
            '''
            Op Types refer: https://www.hex-rays.com/products/ida/support/sdkdoc/ua_8hpp.html#aaf9da6ae7e8b201108fc225adf13b4d9
                o_void  =      0  # No Operand               
                o_reg  =       1  # General Register (al,ax,es,ds...)    reg
                o_mem  =       2  # Direct Memory Reference  (DATA)      addr
                o_phrase  =    3  # Memory Ref [Base Reg + Index Reg]    phrase
                o_displ  =     4  # Memory Reg [Base Reg + Index Reg + Displacement] phrase+addr
                o_imm  =       5  # Immediate Value                      value
                o_far  =       6  # Immediate Far Address  (CODE)        addr
                o_near  =      7  # Immediate Near Address (CODE)        addr
                ......
            '''
            goroot_path_str_addr = read_mem(
                idc.GetOperandValue(goroot_flowchart[cb_idx].startEA, 1))
            goroot_path_str = idc.GetString(goroot_path_str_addr)
            if goroot_path_str is None or len(goroot_path_str) == 0:
                raise Exception("Invalid GOROOT")
            idc.MakeStr(goroot_path_str_addr,
                        goroot_path_str_addr + len(goroot_path_str) + 1)
            idaapi.autoWait()
            break

    if len(goroot_path_str) > 0:
        _info("Go ROOT Path: %s\n" % goroot_path_str)

    return goroot_path_str.replace("\\", "/")
def parse_pclntable(module_data):
    pPcHeader = module_data.pPcHeader
    pc_header = parse_pc_header(pMem=pPcHeader)
    ptrSize = pc_header.ptrSize
    numberOfFuncs = pc_header.nFunc

    log._info("Number of Functions : %d" % numberOfFuncs)

    pclntable_start = module_data.pPclnTable
    cur_addr = pclntable_start
    for idx in range(numberOfFuncs):
        cur_addr = pclntable_start + (2 * ptrSize) * idx
        func_rva = common.mem_read_integer(addr=cur_addr, read_size=ptrSize)
        _func_structure_offset = common.mem_read_integer(addr=cur_addr +
                                                         ptrSize,
                                                         read_size=ptrSize)
        _func_addr = pclntable_start + _func_structure_offset

        if not idc.GetFunctionName(func_rva):
            log._info("Unk Func @0x%x" % func_rva)
            idc.MakeUnkn(func_rva, idc.DOUNK_EXPAND)
            idaapi.autoWait()
            idc.MakeCode(func_rva)
            idaapi.autoWait()
            if idc.MakeFunction(func_rva):
                idaapi.autoWait()
                log._info("Create Func @0x%x" % func_rva)

        _func = parse__func(pMem=_func_addr)
        #args=_func.args
        #func_id=_func.args

        func_name_addr = module_data.pFuncNameTable + _func.nameoff
        func_name = idc.GetString(func_name_addr)
        if func_name:
            clean_func_name = utils.clean_function_name(func_name)
            log._info("@0x%x Name : [%s]" % (func_rva, func_name))
            idc.MakeComm(func_rva, "@0x" + str(hex(func_rva)) + " entry")
            idaapi.autoWait()

            if idc.MakeStr(func_name_addr,
                           func_name_addr + len(func_name) + 1):
                idaapi.autoWait()
            else:
                log._error("@0x%x Name : [%s] Failed..." %
                           (func_rva, func_name))

        _func_addr = idaapi.get_func(func_rva)
        if _func_addr is not None:
            if idc.MakeNameEx(_func_addr.startEA,
                              func_name,
                              flags=idaapi.SN_FORCE):
                idaapi.autoWait()
                log._info("@0x%x Name : [%s]" % (func_rva, func_name))
            else:
                log._error("@0x%x Name : [%s] Failed..." %
                           (func_rva, func_name))
def decrypt(argv, funcName):
    myEH = flare_emu.EmuHelper()
    print("decrypting...")
    mu = myEH.emulateRange(idc.get_name_ea_simple(funcName),
                           stack=[0, argv[0], argv[1]],
                           memAccessHook=mem_hook)
    decrypted_data = myEH.getEmuBytes(argv[0], argv[1])
    print('decrypted: {}'.format(decrypted_data))
    # make string in idb file
    if funcName == "DecryptAsciiStr":
        # make ascii str
        idc.MakeStr(argv[0], argv[0] + argv[1])
    if funcName == "DecryptUnicodeStr":
        # make unicode str
        old_type = idc.GetLongPrm(INF_STRTYPE)
        idc.SetLongPrm(idc.INF_STRTYPE, idc.ASCSTR_UNICODE)
        idc.MakeStr(argv[0], argv[0] + (argv[1] * 2))
        idc.SetLongPrm(idc.INF_STRTYPE, old_type)
    return decrypted_data
Exemple #7
0
def MakeAndGetString(ea, length=-1, comment=None):
    """
    Creates a string at the specified address and returns the string value.
    :param ea: address to make string at
    :param comment: optional comment to place at the specified address
    :return: the value of the string at the specified address
    """

    # Make the string.
    if length is -1:
        idc.MakeStr(ea, idc.BADADDR)
    else:
        idc.MakeStr(ea, ea + length)

    # Check if the comment is valid and if so place it at the address.
    if comment is not None:
        idc.MakeComm(ea, comment)

    # Get the string value.
    return idc.GetString(ea, length)
def analyze_invoke2(funcaddr):
    #print('funcaddr : %08X - %s' % (funcaddr, GetFunctionName(funcaddr)))

    func_st = idc.GetFunctionAttr(funcaddr, idc.FUNCATTR_START)
    func_en = idc.GetFunctionAttr(funcaddr, idc.FUNCATTR_END)
    funcname = idc.GetFunctionName(func_st)
    addr = func_st
    state = 0

    if not funcname.startswith('sub_'):
        return

    while addr < func_en:
        mnem = idc.GetMnem(addr)

        #print('  %08X: %s' % (addr, mnem))

        if mnem == 'lea':
            oprand1 = idc.GetOpnd(addr, 1)
            match = name_re.match(oprand1)

            #print('              %s' % (oprand1))

            if match is not None:
                #print('              %s' % (match.group(1)))

                strname = match.group(1)
                nameaddr = idc.LocByName(strname)

                if strname.startswith('off'):
                    idc.MakeStr(nameaddr, idc.BADADDR)

                name = idc.GetString(nameaddr, -1, idc.ASCSTR_C)

                #print('    opaddr:   %X' % addr)
                #print('    strname:  %s' % strname)
                #print('    nameaddr: %X' % nameaddr)
                #print('    name:     %s' % name)

                if state == 0:
                    libname = name
                    state = 1
                else:
                    name = method_re.match(name).group(0)

                    #print('    %X: %s @%s' % (func_st, name, libname))

                    idc.MakeNameEx(func_st, name, idc.SN_NOWARN | idc.SN_AUTO)
                    break

        addr = idc.NextHead(addr, func_en)

        if addr == idc.BADADDR:
            break
Exemple #9
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 "_cgo_" in srcfile_path or "go/src/git" in srcfile_path):
                # 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 fix_ascii(self, address):
     string_table_start_address = self.get_string_table_start_address(address)
     string_address = string_table_start_address
     while True:
         if string_address:
             print("Start Make string at address: %s" % hex(string_address))
             if idaapi.IDA_SDK_VERSION >= 700:
                 idc.create_strlit(string_address, idc.BADADDR)
             else:
                 idc.MakeStr(string_address, idc.BADADDR)
             string_address = self.get_next_ascii_string_address(string_address)
         else:
             break
Exemple #11
0
def make_str(address):
    """Calculate the length, undefine and make an ascii string."""
    # calculate the length, with a hardcoded maximum length
    ret = ''
    for offset in xrange(MAX_STRING_LENGTH):
        ch = idc.GetOriginalByte(address + offset)
        if not ch:
            break

        ret += chr(ch)

    idc.MakeUnknown(address, offset, idc.DOUNK_SIMPLE)
    idc.MakeStr(address, address + offset)
    return ret
Exemple #12
0
def get_goversion():
    global GOVER

    func_goroot = find_func_by_name("runtime_schedinit")
    if func_goroot is None:
        _error("Failed to find func runtime_schedinit")
        return

    schedinit_flowchart = idaapi.FlowChart(f=func_goroot)
    _debug("Flowchart number of runtime_schedinit: %d" %
           schedinit_flowchart.size)

    for fc_idx in xrange(schedinit_flowchart.size):
        fc = schedinit_flowchart[fc_idx]
        _debug("Current flowchart start addr: 0x%x" % fc.startEA)
        # mov     dword_AD744C, 7 ; dword_AD744C stores length of Go Version string
        if idc.GetMnem(fc.startEA) == "mov" and idc.GetOpType(fc.startEA, 0) == 2 \
            and str(idc.GetOperandValue(fc.startEA, 1)) == "7":
            _debug("Find length of go version string @ 0x%x" % fc.startEA)
            possible_goversion_len_addr = idc.GetOperandValue(fc.startEA, 0)
            _debug("Possible go version string len addr: 0x%x" %
                   possible_goversion_len_addr)
            possible_goversion_str_ptr_addr = possible_goversion_len_addr - ADDR_SZ
            possible_goversion_str_addr = read_mem(
                possible_goversion_str_ptr_addr)
            _debug("Possible go version string addr: 0x%x" %
                   possible_goversion_str_addr)
            possible_goversion_len = read_mem(possible_goversion_len_addr)
            _debug("Real go version string len: %d" % possible_goversion_len)
            if possible_goversion_len >= 5 and possible_goversion_len < 10:
                if idc.MakeStr(
                        possible_goversion_str_addr,
                        possible_goversion_str_addr + possible_goversion_len):
                    idaapi.autoWait()
                    goversion_str = str(
                        idc.GetManyBytes(possible_goversion_str_addr,
                                         possible_goversion_len))
                    _debug(goversion_str)
                    if goversion_str.startswith("go"):
                        GOVER = goversion_str[2:]
                        _info("\nGo version: %s\n" % GOVER)
                    else:
                        _debug("Invalid go string")
                else:
                    _debug("Failed to create go version string")
            else:
                _debug("Invalid go version len")
Exemple #13
0
    def stringify(self):
        n = 0
        ea = self.get_start_ea(self.DATA)

        if ea == idc.BADADDR:
            ea = idc.FirstSeg()

        print("Looking for possible strings starting at: %s:0x%X..." %
              (idc.SegName(ea), ea)),

        for s in idautils.Strings():
            if s.ea > ea:
                if not idc.isASCII(idc.GetFlags(s.ea)) and idc.MakeStr(
                        s.ea, idc.BADADDR):
                    n += 1

        print "created %d new ASCII strings" % n
Exemple #14
0
 def fix_vxworks_idb(load_address, vx_version, symbol_table_start,
                     symbol_table_end):
     current_image_base = idaapi.get_imagebase()
     symbol_interval = 16
     if vx_version == 6:
         symbol_interval = 20
     symbol_table_start += load_address
     symbol_table_end += load_address
     ea = symbol_table_start
     shift_address = load_address - current_image_base
     while shift_address >= 0x70000000:
         idaapi.rebase_program(0x70000000, 0x0008)
         shift_address -= 0x70000000
     idaapi.rebase_program(shift_address, 0x0008)
     while ea < symbol_table_end:
         # for VxWorks 6 unknown symbol format
         if idc.Byte(ea + symbol_table_end - 2) == 3:
             ea += symbol_interval
             continue
         offset = 4
         if idaapi.IDA_SDK_VERSION >= 700:
             idc.create_strlit(idc.Dword(ea + offset), idc.BADADDR)
         else:
             idc.MakeStr(idc.Dword(ea + offset), idc.BADADDR)
         sName = idc.GetString(idc.Dword(ea + offset), -1, idc.ASCSTR_C)
         print("Found %s in symbol table" % sName)
         if sName:
             sName_dst = idc.Dword(ea + offset + 4)
             if vx_version == 6:
                 sName_type = idc.Dword(ea + offset + 12)
             else:
                 sName_type = idc.Dword(ea + offset + 8)
             idc.MakeName(sName_dst, sName)
             if sName_type in need_create_function:
                 # flags = idc.GetFlags(ea)
                 print("Start fix Function %s at %s" %
                       (sName, hex(sName_dst)))
                 idc.MakeCode(sName_dst)  # might not need
                 idc.MakeFunction(sName_dst, idc.BADADDR)
         ea += symbol_interval
     print("Fix function by symbol table finish.")
     print(
         "Start IDA auto analysis, depending on the size of the firmware this might take a few minutes."
     )
     idaapi.autoWait()
Exemple #15
0
    def defineAsciiString(self, ea):
        r"""Define an ascii string at the given address.

        Args:
            ea (int): effective start address of the wanted ascii string

        Return Value:
            The length of the defined string + 1 for the '\0' terminator
        """
        content = idc.GetString(ea, -1, -1)
        if not sark.Line(ea).is_string:
            self._analyzer.logger.debug("Defined a unique ascii string at: 0x%x (Length of %d)", ea, len(content) + 1)
        idc.MakeUnknown(ea, len(content) + 1, 0)
        # Backward compatibility is always fun
        if idaapi.IDA_SDK_VERSION <= 700:
            idaapi.make_ascii_string(ea, len(content) + 1, idc.ASCSTR_C)
        else:
            idc.MakeStr(ea, ea + len(content) + 1)
        return len(content) + 1
Exemple #16
0
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
'''
go_parser.py:
IDA Plugin for Golang Executable file parsing.
'''

__author__ = "JiaYu"
__license__ = "MIT"
__version__ = "1.0"
__email__ = ["*****@*****.**"]

import idc, idaapi
idaapi.require("common")

#ADDR_SZ = 8
START_EA = 0x98C710
END_EA = 0x990F58

curr_addr = START_EA
while curr_addr <= END_EA:
    curr_str_addr = common.read_mem(curr_addr)
    curr_str_len = common.read_mem(curr_addr + common.ADDR_SZ)
    if curr_str_addr > 0 and curr_str_addr != idc.BADADDR and curr_str_len > 1:
        if idc.MakeStr(curr_str_addr, curr_str_addr + curr_str_len):
            idaapi.autoWait()

            curr_str = str(idc.GetManyBytes(curr_str_addr, curr_str_len))
            print("@ 0x%x: %s" % (curr_str_addr, curr_str))

    curr_addr += 2 * common.ADDR_SZ
Exemple #17
0
def get_goroot():
    goroot_path_str = ""
    '''
    Get GOROOT path string
    '''
    func_goroot = find_func_by_name("runtime_GOROOT")
    if func_goroot is None:
        _error("Failed to find func contains goroot")
        return goroot_path_str

    goroot_flowchart = idaapi.FlowChart(f=func_goroot)
    ret_cbs = find_ret_cb(goroot_flowchart)
    '''
    runtime.GOROOT() normally has 2 return code blocks:
    1. False return
        mov     [rsp+28h+arg_0], rax
        mov     [rsp+28h+arg_8], rcx
        mov     rbp, [rsp+28h+var_8]
        add     rsp, 28h
        retn

    2. True return(Which we needed):

        (1). goroot string length as ptr
        mov     rax, cs:runtime_internal_sys_DefaultGoroot
        mov     rcx, cs:qword_D9AB58
        mov     [rsp+28h+arg_0], rax
        mov     [rsp+28h+arg_8], rcx
        mov     rbp, [rsp+28h+var_8]
        add     rsp, 28h
        retn

        (2). goroot string length as instant number
        lea     rax, unk_7220B5
        mov     [rsp+28h+arg_0], rax
        mov     [rsp+28h+arg_8], 0Dh
        mov     rbp, [rsp+28h+var_8]
        add     rsp, 28h
        retn
    '''
    for cb_idx in ret_cbs:
        if idc.GetOpType(goroot_flowchart[cb_idx].startEA, 0) == 1:
            # e.g.: mov     rax, cs:runtime_internal_sys_DefaultGoroot
            '''
            Op Types refer: https://www.hex-rays.com/products/ida/support/sdkdoc/ua_8hpp.html#aaf9da6ae7e8b201108fc225adf13b4d9
                o_void  =      0  # No Operand               
                o_reg  =       1  # General Register (al,ax,es,ds...)    reg
                o_mem  =       2  # Direct Memory Reference  (DATA)      addr
                o_phrase  =    3  # Memory Ref [Base Reg + Index Reg]    phrase
                o_displ  =     4  # Memory Reg [Base Reg + Index Reg + Displacement] phrase+addr
                o_imm  =       5  # Immediate Value                      value
                o_far  =       6  # Immediate Far Address  (CODE)        addr
                o_near  =      7  # Immediate Near Address (CODE)        addr
                ......
            '''
            goroot_path_len = 0
            goroot_path_addr = 0

            curr_addr = goroot_flowchart[cb_idx].startEA
            goroot_path_addr_val = idc.GetOperandValue(curr_addr, 1)

            end_addr = goroot_flowchart[cb_idx].endEA
            curr_addr = idc.FindCode(curr_addr, idaapi.SEARCH_DOWN)
            # find goroot path length and OpType of length(instant len number or addr of len)
            while curr_addr <= end_addr:
                len_optype = idc.GetOpType(curr_addr, 1)
                if len_optype == 2:
                    # addr of len
                    # mov     rcx, cs:qword_D9AB58
                    goroot_path_addr = read_mem(goroot_path_addr_val)
                    goroot_path_len = read_mem(goroot_path_addr_val + ADDR_SZ)
                    break
                elif len_optype == 5:
                    # instant number as len
                    # mov     [rsp+28h+arg_8], 0Dh
                    goroot_path_addr = goroot_path_addr_val
                    goroot_path_len = idc.GetOperandValue(curr_addr, 1)
                    break

                curr_addr = idc.FindCode(curr_addr, idaapi.SEARCH_DOWN)

            if goroot_path_len == 0 or goroot_path_addr == 0:
                raise Exception("Invalid GOROOT Address ang Length")

            goroot_path_str = str(
                idc.GetManyBytes(goroot_path_addr, goroot_path_len))
            if goroot_path_str is None or len(goroot_path_str) == 0:
                raise Exception("Invalid GOROOT")
            idc.MakeStr(goroot_path_addr, goroot_path_addr + goroot_path_len)
            idaapi.autoWait()
            break

    if len(goroot_path_str) > 0:
        _info("Go ROOT Path: %s\n" % goroot_path_str)

    return goroot_path_str.replace("\\", "/")
def map_metadata(file, addr):
    flags = 0
    flags |= 0x0001  # NEF_SEGS
    size = os.stat(file).st_size

    li = idaapi.open_linput(file, False)

    #print('li = %s' % str(li))

    rc = idaapi.load_binary_file(file, li, flags, 0, 0, addr, size)

    #print('rc = %d' % rc)

    names = [
        'stringLiteral',
        'stringLiteralData',
        'strings',
        'events',
        'properties',
        'methods',
        'parameterDefaultValues',
        'fieldDefaultValues',
        'fieldAndParameterDefaultValueData',
        'fieldMarshaledSizes',
        'parameters',
        'fields',
        'genericParameters',
        'genericParameterConstraints',
        'genericContainers',
        'nestedTypes',
        'interfaces',
        'vtableMethods',
        'interfaceOffsets',
        'typeDefinitions',
        'rgctxEntries',
        'images',
        'assemblies',
        'metadataUsageLists',
        'metadataUsagePairs',
        'fieldRefs',
        'referencedAssemblies',
        'attributesInfo',
        'attributeTypes',
    ]

    baseaddr = addr

    idc.MakeDword(addr + 0)
    idc.MakeNameEx(addr + 0, 'META_Sig', idc.SN_NOWARN | idc.SN_AUTO)
    idc.MakeDword(addr + 4)
    idc.MakeNameEx(addr + 0, 'META_Version', idc.SN_NOWARN | idc.SN_AUTO)

    for i in range(len(names)):
        descaddr = baseaddr + 8 + i * 8

        idc.MakeStruct(descaddr, 'OffsetAndCount')
        idc.MakeNameEx(descaddr, 'META_%sDesc' % names[i],
                       idc.SN_NOWARN | idc.SN_AUTO)

        dataaddr = baseaddr + idc.Dword(descaddr + 0)
        datasize = idc.Dword(descaddr + 4)

        idc.MakeNameEx(dataaddr, 'META_%s' % names[i],
                       idc.SN_NOWARN | idc.SN_AUTO)

    # string literal
    descaddr = idc.LocByName('META_stringLiteralDesc')
    size1 = idc.Dword(descaddr + 4)
    addr1 = idc.LocByName('META_stringLiteral')
    addr1end = addr1 + size1
    addr2 = idc.LocByName('META_stringLiteralData')

    #print('addr1: %X' % (addr1))
    #print('addr2: %X' % (addr2))

    while addr1 < addr1end:
        strsize = idc.Dword(addr1 + 0)
        stroff = idc.Dword(addr1 + 4)

        #print('%X - %X' % (addr2 + stroff, addr2 + stroff + strsize))

        idc.MakeStr(addr2 + stroff, addr2 + stroff + strsize)

        addr1 += 8

    idc.Jump(baseaddr)
Exemple #19
0
    def parse(self):
        fd = self.fd
        fd.seek(8)

        fd.file2base(0, 0, 8, False)
        AddWasmSegment(0, 8, "HEADER")

        while True:
            try:
                s = WasmSection()
                s.start_ea = fd.tell()
                _, s.id = varint_decode_stream(fd)
                assert s.id in range(
                    12), "[parser] Found invalid id %d at %#x" % (s.id,
                                                                  s.start_ea)
                _, s.payload_len = varint_decode_stream(fd)
                dbg("{:d} - {:s}".format(s.id, WasmSection.id_str(s.id)))

                if s.id == WasmSection.CUSTOM:
                    sizeof_namelen, s.name_len = varint_decode_stream(fd)
                    s.name = fd.read(s.name_len)
                    s.payload_data = fd.read(s.payload_len - len(s.name) -
                                             sizeof_namelen)

                elif s.id == WasmSection.CODE:
                    s.payload_data = self.__parse_code_section(fd)

                elif s.id == WasmSection.ELEMENT:
                    s.payload_data = self.__parse_element_section(fd)

                elif s.id == WasmSection.IMPORT:
                    s.payload_data = self.__parse_import_section(fd)

                elif s.id == WasmSection.EXPORT:
                    s.payload_data = self.__parse_export_section(fd)

                else:
                    s.payload_data = fd.read(s.payload_len)

                s.end_ea = fd.tell()
                self.sections.append(s)
            except Exception as e:
                err("ParseSection() raised exception '%s', skipping..." %
                    (str(e), ))
                break

        dbg("[*] found %d sections" % len(self.sections))

        found_code_section = False
        for s in self.sections:
            if s.id == WasmSection.CODE:
                found_code_section = True
                break

        assert found_code_section, "WASM file invalid: no CODE section"

        for s in self.sections:
            name = WasmSection.id_str(s.id)
            print("[+] Adding new Section '%s': %x-%x" %
                  (name, s.start_ea, s.end_ea))
            fd.file2base(s.start_ea, s.start_ea, s.end_ea, True)
            cls = ""

            if s.id == WasmSection.CODE:
                self.code_start = s.start_ea
                self.code_end = s.end_ea
                for fb in s.payload_data.function_bodies:
                    add_entry(fb.start_ea, fb.start_ea,
                              "sub_{:08x}".format(fb.start_ea), 1)

                cls = "CODE"

            if s.id == WasmSection.EXPORT:
                for idx, ee in enumerate(s.payload_data.entries):
                    dbg("[EXPORT] Making str %d at %x (len=%x)" %
                        (idx, ee.start_ea, ee.field_len))
                    idc.MakeStr(ee.start_ea, ee.start_ea + ee.field_len)

            if s.id == WasmSection.IMPORT:
                for idx, imp in enumerate(s.payload_data.entries):
                    # dbg("[IMPORT] Making module str %d at %x (len=%x)" % (idx, imp.module_str_addr, imp.module_len))
                    # idc.MakeStr(imp.module_str_addr, imp.module_str_addr+imp.module_len)
                    # dbg("[IMPORT] Making field str %d at %x (len=%x)" % (idx, imp.field_str_addr, imp.field_len))
                    # idc.MakeStr(imp.field_str_addr, imp.field_str_addr+imp.field_len)
                    __class = idaapi.get_many_bytes(imp.module_str_addr,
                                                    imp.module_len)
                    __func = idaapi.get_many_bytes(imp.field_str_addr,
                                                   imp.field_len)
                    MakeDword(imp.module_str_addr)
                    MakeName(imp.module_str_addr, "%s::%s" % (__class, __func))

                cls = "XTRN"

                # TODO add entry in Modules tab

            AddWasmSegment(s.start_ea, s.end_ea, name, cls)

        return
Exemple #20
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 = idaapi.get_func(func_addr)
            if real_func is not None:
                orig_func_name = idc.get_func_name(real_func.startEA)
                if len(self.name) > 0 and orig_func_name.startswith("sub_"):
                    if idc.MakeNameEx(real_func.startEA,
                                      self.name,
                                      flags=idaapi.SN_FORCE):
                        idaapi.autoWait()
                        common._debug("Rename function 0x%x: %s" %
                                      (real_func.startEA, self.name))
                    else:
                        common._error('Failed to rename function @ 0x%x' %
                                      real_func.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()
Exemple #21
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()
Exemple #22
0
def make_string(addr, siz):
    print "Creating string at %x %d size" % (addr, siz)
    idc.MakeUnknown(addr, siz, idc.DOUNK_SIMPLE)
    idc.MakeStr(addr, addr+siz)
Exemple #23
0
    def make_data(self, object_version, address):
        size = 0
        try:
            size = object_version.get_size()
        except KeyError:
            pass
        flags = None
        try:
            flags = object_version.get_object_flags()
        except KeyError:
            pass

        if size == 0:
            idc.MakeUnkn(address, idc.DOUNK_EXPAND)
        else:
            if flags is not None:
                if idc.isASCII(flags):
                    try:
                        str_type = object_version.get_string_type()
                        YaToolIDATools.check_and_set_str_type(str_type)
                    except KeyError:
                        pass
                    idc.MakeStr(address, address + size)
                    idc.SetFlags(address, flags)

                if idc.isStruct(flags):
                    found = False
                    for xref_offset_operand, xref_id_attr in object_version.get_xrefed_id_map(
                    ).iteritems():
                        (xref_offset, xref_operand) = xref_offset_operand
                        for xref_hash, xref_attrs in xref_id_attr:

                            if xref_hash in self.struc_ids:
                                struc_id = self.struc_ids[xref_hash]
                                if DEBUG_EXPORTER:
                                    logger.debug(
                                        "making unknown from 0x%08X to 0x%08X"
                                        % (address, address + size))
                                idaapi.do_unknown_range(
                                    address, size, idc.DOUNK_DELNAMES)

                                #   idc.MakeUnkn(address, DOUNK_SIMPLE | idc.DOUNK_DELNAMES)
                                #   for i in xrange(1, size):
                                #       MakeName(address + i, "")
                                #       idc.MakeUnkn(address + i, DOUNK_SIMPLE | idc.DOUNK_DELNAMES)
                                # idc.MakeStructEx uses idaapi.doStruct (but asks for name while
                                # we already have the struc id)
                                if DEBUG_EXPORTER:
                                    logger.debug(
                                        "Making struc at %s : %s (sizeof(%s)=0x%08X, size=0x%08X, flags=0x%08X"
                                        % (self.yatools.address_to_hex_string(
                                            address),
                                           self.yatools.address_to_hex_string(
                                               struc_id),
                                           idaapi.get_struc_name(struc_id),
                                           idc.GetStrucSize(struc_id), size,
                                           flags))
                                idc.SetCharPrm(idc.INF_AUTO, True)
                                idc.Wait()
                                if idaapi.doStruct(address, size,
                                                   struc_id) == 0:
                                    if DEBUG_EXPORTER:
                                        logger.warning("Making struc failed")
                                idc.SetCharPrm(idc.INF_AUTO, False)
                                #                                     idc.SetFlags(address, flags)
                                found = True
                    else:
                        logger.error(
                            "bad struc flags : idc.isStruct is true but no xref available for object %s"
                            % self.hash_provider.hash_to_string(
                                object_version.get_id()))
                    if not found:
                        logger.error(
                            "bad struc flags : idc.isStruct is true "
                            "but no struc available for object %s (%s)" %
                            (self.hash_provider.hash_to_string(
                                object_version.get_id()),
                             object_version.get_name()))
                else:
                    idc.MakeData(address, flags & (idc.DT_TYPE | idc.MS_0TYPE),
                                 size, 0)

            else:
                idc.MakeData(address, idc.FF_BYTE, size, 0)

        self.make_name(object_version, address, False)

        self.set_type(object_version, address)
Exemple #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()
Exemple #25
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