def define_functions():
    native_rvas = [
        0x1930,
        0x3A90,
        0x44b0,
    ]
    native_rvas = [(0x400000 + x) for x in native_rvas]

    for ea in native_rvas:

        if ea == 0x401930:
            # undefine and force convert to code as IDA doesn't analyse it at first
            print "Defining fcn GODDAG at 0x%x" % ea
            print "Making", ea, "unknown and defining it to code..."
            idc.MakeUnkn(ea, 1)
            idc.MakeCode(ea)
            idc.MakeUnkn(ea + 8, 1)
            idc.MakeCode(ea + 7)
        else:
            if ea == 0x403A90:
                fcn_name = "NativeGRUNDTAL_NORRVIKEN"
                print "Defining fcn %s at 0x%x" % (fcn_name, ea)
            elif ea == 0x4044B0:
                fcn_name = "FYRKANTIGImpl"
                print "Defining fcn %s at 0x%x" % (fcn_name, ea)

            idc.MakeFunction(ea)
            idc.MakeNameEx(ea, fcn_name, idc.SN_NOWARN)
Exemplo n.º 2
0
def main():
    for segstart, segend, segname in enum_segments():
        if segname not in ('.text', '.data'):
            continue

        for src, dst in find_pointers(segstart, segend):
            if is_code(src):
                # ignore instructions like:
                #
                #     call    ds:__vbaGenerateBoundsError
                #print('code pointer: 0x%x -> 0x%x' % (src, dst))
                continue

            # TODO: fix this: just look at the few previous bytes and ensure they are ASCII/Unicode
            if is_in_string(src):
                # for example, the following contains 0x444974 (a common valid offset):
                #
                #     text:004245B0 aRequestid    db 'requestID',
                #
                # enable or disable this behavior as you wish
                print('string pointer: 0x%x -> 0x%x' % (src, dst))
                pass
                #continue

            print('pointer from 0x%x to 0x%x' % (src, dst))

            if is_unknown(dst):
                print('destination unknown, making byte: 0x%x' % (dst))
                idc.MakeByte(dst)

            elif is_head(dst):
                # things are good
                pass

            else:
                # need to undefine head, and make byte
                head_va = get_head(dst)
                print('destination overlaps with head: 0x%x' % (head_va))
                idc.MakeUnkn(head_va, dst - head_va)
                idc.MakeByte(head_va)
                idc.MakeByte(dst)

            idc.MakeUnkn(src, 4)
            idc.MakeDword(src)
            # this doesn't seem to always work :-(
            # ref: https://reverseengineering.stackexchange.com/questions/17798/how-can-i-mark-a-global-variable-as-an-offset-using-idapython
            #idc.OpOffset(src, 0)
            ida_offset.op_offset(src, 0, idc.REF_OFF32)
Exemplo n.º 3
0
def main():
    for segstart, segend, segname in enum_segments():
        if segname not in ('.text', '.data'):
            continue

        for src, dst in find_pointers(segstart, segend):
            if is_code(src):
                # ignore instructions like:
                #
                #     call    ds:__vbaGenerateBoundsError
                #print('code pointer: 0x%x -> 0x%x' % (src, dst))
                continue

            if is_in_string(src):
                # for example, the following contains 0x444974 (a common valid offset):
                #
                #     text:004245B0 aRequestid    db 'requestID',
                #
                # enable or disable this behavior as you wish
                print('string pointer: 0x%x -> 0x%x' % (src, dst))
                pass
                #continue

            print('pointer from 0x%x to 0x%x' % (src, dst))

            if is_unknown(dst):
                print('destination unknown, making byte: 0x%x' % (dst))
                idc.MakeByte(dst)

            elif is_head(dst):
                # things are good
                pass

            else:
                # need to undefine head, and make byte
                head_va = get_head(dst)
                print('destination overlaps with head: 0x%x' % (head_va))
                idc.MakeUnkn(head_va, dst - head_va)
                idc.MakeByte(head_va)
                idc.MakeByte(dst)

            idc.MakeUnkn(src, 4)
            idc.MakeDword(src)
            # this doesn't seem to always work :-(
            idc.OpOffset(src, 0)
Exemplo n.º 4
0
def assign_struct_to_address(address, struct_name):
    idc.ApplyType(address, get_Tinfo_from_name(struct_name))
    struct_id = idaapi.get_struc_id(struct_name)
    if struct_id != 0xffffffffffffffff:
        struct_size = idaapi.get_struc_size(struct_id)
        for i in range(struct_size):
            idc.MakeUnkn(address+i, 0)
        return idaapi.doStruct(address, struct_size, struct_id)
    return False
Exemplo n.º 5
0
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))
Exemplo n.º 6
0
    def renameDword(self):
        proc_addr = self._import_table.item(self._import_table.currentRow(), 3).text()
        proc_name = str(self._import_table.item(self._import_table.currentRow(), 2).text())
        renamed = 0
        if proc_addr:
            try:
                proc_addr = int(proc_addr, 16)
                proc_bin_str = " ".join([x.encode("hex") for x in struct.pack("<I", proc_addr)])
                next_dword = idc.FindBinary(idc.MinEA(), idc.SEARCH_DOWN|idc.SEARCH_NEXT, proc_bin_str)
                while next_dword != idc.BADADDR:
                    log.debug("Trying to fix-up 0x{:08x}".format(next_dword))
                    # DWORDs can be "inaccessible" for many reasons and it requires "breaking up" the data blobs
                    # and manually fixing them

                    # Reason 1: In a dword array in an unknown section
                    if idc.isUnknown(next_dword):
                        idc.MakeUnkn(next_dword, idc.DOUNK_EXPAND)
                        idc.MakeDword(next_dword)
                    # Reason 2: In a dword array in a data section
                    elif idc.isData(next_dword):
                        hd = idc.ItemHead(next_dword)
                        idc.MakeDword(hd)
                        idc.MakeDword(next_dword)
                    # Reason 3: In a dword array in a code section (validate via "dd <dword>,")
                    elif idc.isCode(next_dword) and idc.GetDisasm(next_dword).startswith("dd "):
                        hd = idc.ItemHead(next_dword)
                        idc.MakeDword(hd)
                        idc.MakeDword(next_dword)

                    # Only perform
                    if idc.Name(next_dword).startswith(("off_", "dword_")) or idc.Name(next_dword) == "":
                        success = idc.MakeNameEx(next_dword, proc_name, idc.SN_NOWARN|idc.SN_NON_AUTO)
                        i = 0
                        new_proc_name = proc_name
                        while not success and i < 10:
                            new_proc_name = "{}{}".format(proc_name, i)
                            success = idc.MakeNameEx(next_dword, new_proc_name, idc.SN_NOWARN|idc.SN_NON_AUTO)
                            i += 1
                        if success:
                            renamed += 1
                            item = self._import_table.item(self._import_table.currentRow(), 5)
                            item.setText("{}, {}".format(str(item.text()), new_proc_name))
                            log.debug("DWORD @ 0x{:08x} now has name {}".format(next_dword, new_proc_name))
                        else:
                            log.error("Unable to auto-rename successfully, terminating search")
                            break
                    else: log.debug("Value at 0x{:08x} does not meet renaming requirements".format(next_dword))
                    next_dword = idc.FindBinary(next_dword+4, idc.SEARCH_DOWN|idc.SEARCH_NEXT, proc_bin_str)
            except Exception, e:
                log.error("Error encountered: {}".format(e))
            log.debug("Renamed {:d} instances of {}".format(renamed, proc_name))
Exemplo n.º 7
0
def _convert_address_to_function(func):
    """Convert an address that IDA has classified incorrectly into a proper function."""
    # If everything goes wrong, we'll try to restore this function.
    orig = idc.FirstFuncFchunk(func)
    # If the address is not code, let's undefine whatever it is.
    if not idc.isCode(idc.GetFlags(func)):
        if not is_mapped(func):
            # Well, that's awkward.
            return False
        item = idc.ItemHead(func)
        itemend = idc.ItemEnd(func)
        if item != idc.BADADDR:
            _log(1, 'Undefining item {:#x} - {:#x}', item, itemend)
            idc.MakeUnkn(item, idc.DOUNK_EXPAND)
            idc.MakeCode(func)
            # Give IDA a chance to analyze the new code or else we won't be able to create a
            # function.
            idc.Wait()
            idc.AnalyseArea(item, itemend)
    else:
        # Just try removing the chunk from its current function. IDA can add it to another function
        # automatically, so make sure it's removed from all functions by doing it in loop until it
        # fails.
        for i in range(1024):
            if not idc.RemoveFchunk(func, func):
                break
    # Now try making a function.
    if idc.MakeFunction(func) != 0:
        return True
    # This is a stubborn chunk. Try recording the list of chunks, deleting the original function,
    # creating the new function, then re-creating the original function.
    if orig != idc.BADADDR:
        chunks = list(idautils.Chunks(orig))
        if idc.DelFunction(orig) != 0:
            # Ok, now let's create the new function, and recreate the original.
            if idc.MakeFunction(func) != 0:
                if idc.MakeFunction(orig) != 0:
                    # Ok, so we created the functions! Now, if any of the original chunks are not
                    # contained in a function, we'll abort and undo.
                    if all(idaapi.get_func(start) for start, end in chunks):
                        return True
            # Try to undo the damage.
            for start, _ in chunks:
                idc.DelFunction(start)
    # Everything we've tried so far has failed. If there was originally a function, try to restore
    # it.
    if orig != idc.BADADDR:
        _log(0, 'Trying to restore original function {:#x}', orig)
        idc.MakeFunction(orig)
    return False
Exemplo n.º 8
0
    def origFun(self, ip):
        print('look for fun having ip 0x%x' % ip)
        fun = self.getFun(ip)
        if fun is None:
            simicsString = gdbProt.Evalx(
                'SendGDBMonitor("@cgc.getSO(0x%x)");' % ip)
            print('No function found.  Check load for: %s' % simicsString)
            if ':' in simicsString:
                sofile, start_end = str(simicsString).rsplit(':', 1)
                print('sofile is %s start_end is %s' % (sofile, start_end))
                if '-' not in start_end:
                    print('Bad response from getSO: %s' % simicsString)
                    return
                full = os.path.join(self.root_prefix, sofile[1:])
                sopath = self.getFunPath(full)
                start, end = start_end.split('-')
                start = int(start, 16)
                end = int(end, 16)
                self.add(sopath, start)
                fun = self.getFun(ip)
                print('start 0x%x end 0x%x' % (start, end))
                idaapi.analyze_area(start, end)
                for fun in sorted(self.funs):
                    if fun >= start and fun <= end:
                        name = str(self.funs[fun]['name'])
                        nea = idaapi.get_name_ea(idaapi.BADADDR, name)
                        if nea != idaapi.BADADDR:
                            name = name + '_so'
                        idc.MakeName(int(fun), name)
                        print('made name for 0x%x  %s' % (int(fun), name))
                for fun in self.funs:
                    if fun >= start and fun <= end:
                        #print('fun 0x%x name <%s>' % (fun, name))
                        idc.MakeFunction(fun, idaapi.BADADDR)

        elif fun is not None:
            print('Do one fun 0x%x' % fun)
            for i in range(self.funs[fun]['start'], self.funs[fun]['end']):
                idc.MakeUnkn(i, 1)
            idaapi.auto_mark_range(self.funs[fun]['start'],
                                   self.funs[fun]['end'], 25)
            idaapi.autoWait()
            return fun
        return None
Exemplo n.º 9
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.MakeComm(funcs_entry, "Functions number")
        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)
            if not idc.GetFunctionName(func_addr):
                common._debug("Creating function @ %x" % func_addr)
                idc.MakeUnkn(func_addr, idc.DOUNK_EXPAND)
                idaapi.autoWait()
                idc.MakeCode(func_addr)
                idaapi.autoWait()
                if idc.MakeFunction(func_addr):
                    idaapi.autoWait()
                    common._info("Create function @ 0x%x" % func_addr)

            name_off = common.read_mem(curr_addr + self.ptr_sz,
                                       forced_addr_sz=self.ptr_sz)
            name_addr = self.start_addr + self.ptr_sz + name_off
            func_st_addr = name_addr - self.ptr_sz
            func_st = FuncStruct(func_st_addr, self)
            func_st.parse()

            # Make comment for name offset
            idc.MakeComm(curr_addr + self.ptr_sz,
                         "Func Struct @ 0x%x" % func_st_addr)
            idaapi.autoWait()
    def fix_names(self):
        """ 
            Fix the table of imports and map enums to apis.
        """
        start_addr  = idc.AskAddr(idc.here(), "Enter table start address")

        ## check if address is within the base address and maximum address
        if (start_addr < idc.MinEA()) or (start_addr > idc.MaxEA()):
            idc.Warning("You have entered an invalid start address")
            idc.Exit

        self.start_addr = start_addr    
        current_addr = self.start_addr

        #Current size of PoisonIvy IAT
        end_addr = current_addr + 568

        # Walk the table 8 bytes at a time
        while current_addr <= end_addr:

            idc.MakeQword(current_addr)
            print "DEBUG: Current address - 0x%08x" % current_addr
            addr = idc.Qword(current_addr)
            print "DEBUG: address - 0x%08x" % addr
            if addr == -1:
                print "[!] Skipping address 0x%08x - 0x%08x" % (current_addr, addr)
                current_addr += 8
                continue

            # Make the current address an offset
            idc.OpOff(current_addr,0,0)
            # We need to undefine the bytes incase IDA autoanalysis had converted an incorrect byte
            idc.MakeUnkn(addr, 1)
            # Create code at this address 
            idc.MakeCode(addr)
            # Create function at the same address
            idc.MakeFunction(addr, addr+16)
            # Read the second operand at the address which should be the negative API address value
            imp_addr = idc.GetOperandValue(addr, 1)

            if imp_addr == -1:
                print "[!] Couldn't get operand at address - 0x%08x" % addr
                current_addr +=8
                continue             

            # try:
            #     int_addr = int(imp_addr,16)
            # except ValueError as e:
            #     print "[!] Failed on: %s - %s\n" % (imp_addr, e)
            #     current_addr +=8 
            #     continue
            
            # if we know about this value then let's do the work
            if imp_addr in self.enums.keys():
                enum_id = self.enums[imp_addr]
                # Convert operand to enum 
                idc.OpEnumEx(addr, 1, enum_id,0)
                const_id = idc.GetConstEx(enum_id, imp_addr, 0, -1)
                fn_name = "fn_"+idc.GetConstName(const_id)
                off_name = "ptr_"+idc.GetConstName(const_id)
                # Rename the function to the symbol name.
                # We append fn_ to the symbol for the function name
                # and ptr_ to the offset in the table.
                if not idc.MakeNameEx(addr, fn_name, idaapi.SN_NOWARN):
                    print "[!] Failed to rename function %s at 0x%08x\n" % (fn_name, addr)
                if not idc.MakeNameEx(current_addr, off_name, idaapi.SN_NOWARN):
                    print "[!] Failed to rename offset %s at 0x%08x\n" % (off_name,current_addr)

            current_addr += 8

        return 
Exemplo n.º 11
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)
Exemplo n.º 12
0
def undefBytes(ea, length) :
    curr = ea
    while curr < ea + length :
        idc.MakeUnkn(curr, 0)
        curr += 1
Exemplo n.º 13
0
    def AsmAndWrite(self, mnem, instr=None, write_ea=None, function=None):
        if mnem == '':
            return

        if write_ea != None:
            ea_write = write_ea
        else:
            ea_write = self.free_ea

        idc.MakeUnkn(ea_write, 0)
        #tmp = idaapi.assemble(self.free_ea, self.segment_start, self.free_ea, 1, mnem)

        if debug:
            print ">Assemble:AsmAndWrite - !Writing @ ea[%08x] ip[%08x] instr[%s]" % (
                ea_write, ea_write, mnem)
        tmp = idaapi.assemble(ea_write, 0, ea_write, 1, mnem)

        if instr != None:
            idaapi.set_cmt(ea_write, "%08x" % instr.GetOriginEA(), 0)

        if tmp == 0:
            if instr == None and function != None:
                raise MiscError

            if debug:
                print '>Assemble:AsmAndWrite - !Messy instruction', mnem
                print '>Assemble:AsmAndWrite - Trying original opcodes!'

            refs_from = [
                x for x in function.GetRefsFrom(instr.GetOriginEA())
                if x != None
            ]
            if len(refs_from) == 0:
                if instr.GetIsModified() == True:
                    raise MiscError

                instr_op = instr.GetOpcode()
                for pos in xrange(0, len(instr_op)):
                    idc.PatchByte(ea_write + pos, ord(instr_op[pos]))

                if idc.MakeCode(ea_write) == 0:
                    raise MiscError

                ea_write += idc.ItemSize(ea_write)

            elif len(refs_from) == 1:
                instr_op = instr.GetOpcode()
                for pos in xrange(0, len(instr_op)):
                    idc.PatchByte(ea_write + pos, ord(instr_op[pos]))

                if idc.MakeCode(ea_write) == 0:
                    raise MiscError

                ea_write += idc.ItemSize(ea_write)

            else:
                #print '>Assemble:AsmAndWrite - GetRefsFrom(%08x)' % instr.GetOriginEA(), [hex(x) for x in function.GetRefsFrom(instr.GetOriginEA()) if x != None]
                print '>Assemble:AsmAndWrite - refs_from', refs_from
                print '>Assemble:AsmAndWrite - ea_write [%08x]' % ea_write
                print '>Assemble:AsmAndWrite - mnem', mnem
                print '>Assemble:AsmAndWrite - instr.GetMnem', instr.GetMnem()
                print '>Assemble:AsmAndWrite - instr.GetDisasm', instr.GetDisasm(
                )
                raise MiscError
        else:
            if idc.MakeCode(ea_write) == 0:
                raise MiscError

            ea_write += idc.ItemSize(ea_write)

        if write_ea == None:
            self.free_ea = ea_write
Exemplo n.º 14
0
 def __call__(self):
     try:
         l.debug("Making unknown at " + hex(self.address))
         self.result = idc.MakeUnkn(self.address, self.size)
     except Exception:
         self.exception = True
Exemplo n.º 15
0
def undefBytes(ea, count):
    for i in range(count):
        idc.MakeUnkn(ea + i, 1)