Exemple #1
0
def get_imp(uc, rva, base_addr, SizeOfImportTable, read_values=False):
    rva += base_addr
    entry_size = len(bytes(IMAGE_IMPORT_DESCRIPTOR()))
    num_of_dll = SizeOfImportTable // entry_size
    imp_info_list = []
    imp_struct_list = []
    for i in range(num_of_dll):
        uc_imp = uc.mem_read(rva, entry_size)
        imp_struct = IMAGE_IMPORT_DESCRIPTOR.from_buffer(uc_imp)
        imp_struct_list.append(imp_struct)
        if read_values:
            try:
                dll_name = get_string(getattr(imp_struct, "Name") + base_addr, uc, break_on_unprintable=True)
                imp_names = []
                rva_to_iat = getattr(imp_struct, "FirstThunk")
                while True:
                    new_val = struct.unpack("<I", uc.mem_read(base_addr + rva_to_iat, 4))[0]
                    if new_val == 0:
                        break
                    imp_name = (get_string(new_val + 2 + base_addr, uc, break_on_unprintable=True), rva_to_iat)
                    imp_names.append(imp_name)
                    rva_to_iat += 4

                imp_info_list.append(ImportValues(imp_struct, dll_name, imp_names))
            except UcError as ue:
                return imp_info_list

        rva += entry_size

    if read_values:
        return imp_info_list
    return imp_struct_list
Exemple #2
0
    def append_original_imports(self, uc, hdr, original_imp):
        rva_to_imp_table = hdr.data_directories[1].VirtualAddress
        size_of_imp_table = hdr.data_directories[1].Size
        base_addr = hdr.opt_header.ImageBase

        new_size = size_of_imp_table + len(original_imp) * len(
            bytes(IMAGE_IMPORT_DESCRIPTOR()))

        rva_end = rva_to_imp_table + size_of_imp_table
        total_new_offset = rva_end + new_size + 0x100

        fct_name_offset = total_new_offset

        for imp_desc in original_imp:
            image_import_by_name_offsets = []

            for imp in imp_desc.imports:
                fct_name = b'\x00\x00' + imp + b'\x00'
                uc.mem_write(fct_name_offset + base_addr, fct_name)
                image_import_by_name_offsets.append(fct_name_offset)
                fct_name_offset += len(fct_name)

            fct_name_offset += 0x50
            imp_desc.Import_Descriptor.Characteristics = fct_name_offset

            iat_offset = 0 + imp_desc.Import_Descriptor.FirstThunk

            for addr in image_import_by_name_offsets:
                uc.mem_write(fct_name_offset + base_addr,
                             struct.pack("<I", addr))

                uc.mem_write(iat_offset + base_addr, struct.pack("<I", addr))

                fct_name_offset += 4
                iat_offset += 4

            fct_name_offset += 0x10

            imp_desc.Import_Descriptor.Name = fct_name_offset
            new_name = imp_desc.name.encode('ascii') + b'\x00'
            uc.mem_write(fct_name_offset + base_addr, new_name)

            fct_name_offset += 0x20
            image_import_descriptor = IMAGE_IMPORT_DESCRIPTOR(
                imp_desc.Import_Descriptor.Characteristics,
                imp_desc.Import_Descriptor.TimeDateStamp,
                imp_desc.Import_Descriptor.ForwarderChain,
                imp_desc.Import_Descriptor.Name,
                imp_desc.Import_Descriptor.FirstThunk,
            )
            uc.mem_write(rva_end + base_addr, bytes(image_import_descriptor))
            rva_end += len(bytes(image_import_descriptor))

        hdr.data_directories[1].Size = new_size
        hdr.sync(uc)
        return hdr
Exemple #3
0
    def fix_imports_by_rebuilding(self, uc, hdr, virtualmemorysize, total_size,
                                  dllname_to_function_list):
        rva_to_image_import_descriptor = (virtualmemorysize - 0x10000) + 0x2000
        curr_addr_to_image_import_descriptor = rva_to_image_import_descriptor + hdr.base_addr
        num_of_image_import_descriptor = len(dllname_to_function_list)
        size_of_image_import_descriptor = len(bytes(
            IMAGE_IMPORT_DESCRIPTOR())) * num_of_image_import_descriptor

        rva_of_dll_name = rva_to_image_import_descriptor + size_of_image_import_descriptor + 20
        size_of_dll_name_array = 0
        for dll_name in dllname_to_function_list.keys():
            size_of_dll_name_array += len(dll_name.split('#')[0]) + 1

        rva_of_hint_name = rva_of_dll_name + size_of_dll_name_array + 0x10

        for dll_name in dllname_to_function_list.keys():
            iat_array = self.generate_iat_array(dllname_to_function_list,
                                                dll_name)
            # print(f"IAT_ARRAY for {dll_name}")
            ptr_iat = self.find_iat(uc, hdr.base_addr, total_size, iat_array,
                                    dll_name)

            if ptr_iat is None:
                continue

            orva_to_hint_name = rva_of_hint_name
            dll_name_b = dll_name.split('#')[0].encode('ascii') + b'\x00'
            print(f"writing dllname {dll_name} to: {hex(rva_of_dll_name)}")
            uc.mem_write(rva_of_dll_name + hdr.base_addr, dll_name_b)
            size_of_hint_name_array = len(
                dllname_to_function_list[dll_name]) * 0x4
            rva_to_image_import_by_name = rva_of_hint_name + size_of_hint_name_array + 0x10
            patch_addr = []
            for fct_name, fct_addr in dllname_to_function_list[dll_name]:
                if "/" not in fct_name:  # Import by Name
                    import_by_name = b'\x00\x00' + fct_name.encode(
                        'ascii') + b'\x00'
                    uc.mem_write(rva_to_image_import_by_name + hdr.base_addr,
                                 import_by_name)
                    uc.mem_write(
                        rva_of_hint_name + hdr.base_addr,
                        struct.pack("<I", rva_to_image_import_by_name))
                    patch_addr.append(rva_to_image_import_by_name)
                    rva_to_image_import_by_name += len(import_by_name)
                else:  # Import by ordinal
                    ordinal = int(
                        fct_name.split("/")[2], 10
                    ) + 0x80000000  # Import Lookup Table 1 bit defines ordinals (0x80000000)
                    uc.mem_write(rva_of_hint_name + hdr.base_addr,
                                 struct.pack("<I", ordinal))
                    patch_addr.append(ordinal)
                rva_of_hint_name += 4

            rva_of_hint_name = rva_to_image_import_by_name + 0x8

            self.patch_iat(uc, hdr.base_addr, patch_addr, ptr_iat)

            import_struct = IMAGE_IMPORT_DESCRIPTOR(
                orva_to_hint_name,
                0,
                0,
                rva_of_dll_name,
                ptr_iat,
            )

            print_addr_list("patch_addr: ", patch_addr)
            print(f"ptr_iat: {hex(ptr_iat)}")

            import_struct_payload = bytes(import_struct)

            uc.mem_write(curr_addr_to_image_import_descriptor,
                         import_struct_payload)

            rva_of_dll_name += len(dll_name_b)

            curr_addr_to_image_import_descriptor += len(
                bytes(IMAGE_IMPORT_DESCRIPTOR()))

        hdr.data_directories[1].VirtualAddress = rva_to_image_import_descriptor
        hdr.data_directories[1].Size = size_of_image_import_descriptor
        # hdr.data_directories[1].VirtualAddress = 0
        # hdr.data_directories[1].Size = 0
        hdr.sync(uc)
        return hdr
Exemple #4
0
from datetime import datetime

from unicorn import UcError

from unipacker.pe_structs import _IMAGE_DOS_HEADER, _IMAGE_FILE_HEADER, _IMAGE_OPTIONAL_HEADER, IMAGE_SECTION_HEADER, \
    _IMAGE_DATA_DIRECTORY, IMAGE_IMPORT_DESCRIPTOR, SectionHeader, DosHeader, PEHeader, OptionalHeader, \
    ImportDescriptor, DataDirectory
from unipacker.utils import InvalidPEFile, ImportValues, get_string

header_sizes = {
    "_IMAGE_DOS_HEADER": len(bytes(_IMAGE_DOS_HEADER())),  # 0x40
    "_IMAGE_FILE_HEADER": len(bytes(_IMAGE_FILE_HEADER())),  # 0x18
    "_IMAGE_OPTIONAL_HEADER": len(bytes(_IMAGE_OPTIONAL_HEADER())),  # 0xE0
    "IMAGE_SECTION_HEADER": len(bytes(IMAGE_SECTION_HEADER())),  # 0x28
    "_IMAGE_DATA_DIRECTORY": len(bytes(_IMAGE_DATA_DIRECTORY())),  # 0x8
    "IMAGE_IMPORT_DESCRIPTOR": len(bytes(IMAGE_IMPORT_DESCRIPTOR())),
}

short_hdr_names = {
    "DOS": "_IMAGE_DOS_HEADER",
    "DOS_HEADER": "_IMAGE_DOS_HEADER",
    "DOS_HDR": "_IMAGE_DOS_HEADER",
    "IMAGE_DOS_HEADER": "_IMAGE_DOS_HEADER",
    "PE": "_IMAGE_FILE_HEADER",
    "PE_HEADER": "_IMAGE_FILE_HEADER",
    "PE_HDR": "_IMAGE_FILE_HEADER",
    "FILE_HEADER": "_IMAGE_FILE_HEADER",
    "FILE_HDR": "_IMAGE_FILE_HEADER",
    "IMAGE_FILE_HEADER": "_IMAGE_FILE_HEADER",
    "OPT": "_IMAGE_OPTIONAL_HEADER",
    "OPT_HEADER": "_IMAGE_OPTIONAL_HEADER",