예제 #1
0
    def fix_imports_by_dllname(self, uc, hdr, total_size,
                               dllname_to_functionlist):
        pe_write(uc, hdr.opt_header.ImageBase, total_size,
                 ".unipacker_brokenimport.exe")
        with open(".unipacker_brokenimport.exe", 'rb') as f:
            b = f.read()

        dllname_to_ptrs = []

        for k in dllname_to_functionlist.keys():
            k = k.split('#')[0]
            dllname_to_ptrs.append(
                (k, self.locate_ptr_to_occurences(b,
                                                  self.find_occurences(b, k))))

        if len(dllname_to_ptrs) == 1 and len(dllname_to_ptrs[0][1]) == 1:
            addr = dllname_to_ptrs[0][1]
        elif len(dllname_to_ptrs) == 1:
            # TODO Try Fix Imports by Imported Function Names
            print("FAILED here")
            return None  # FAILED
        else:
            for i in range(len(dllname_to_ptrs) - 1):
                addrlist = dllname_to_ptrs[i][1]
                addrlist2 = dllname_to_ptrs[i + 1][1]
                a1, a2 = self.search_offset_two(addrlist, addrlist2, 0x14)
                if a1 is not None and a2 is not None:
                    break

            if a1 is None and a2 is None:
                print(f"FAILED a1: {a1}, a2: {a2}")
                return None  # FAILED

            dllname_to_ptrs[0] = (dllname_to_ptrs[0][0], [a1])
            dllname_to_ptrs[1] = (dllname_to_ptrs[1][0], [a2])

            offset = 0x14

            for i in range(len(dllname_to_ptrs)):
                if i + 1 < len(dllname_to_ptrs):
                    cmp = dllname_to_ptrs[i][1][0]
                    val = None
                    for e in dllname_to_ptrs[i + 1][1]:
                        if cmp + 0x14 == e:
                            val = e
                    dllname_to_ptrs[i + 1] = (dllname_to_ptrs[i + 1][0], [val])

            # select pointer
            addr = dllname_to_ptrs[0][1][0]
            for i in range(len(dllname_to_ptrs)):
                if addr > dllname_to_ptrs[i][1][0]:
                    addr = dllname_to_ptrs[i][1][0]

        hdr.data_directories[1].VirtualAddress = addr - 0xC
        hdr.data_directories[1].Size = len(dllname_to_functionlist) * 5 * 4
        # Per Dll 1 IMAGE_IMPORT_DESCRIPTOR (THUNK_DATA), Per IMAGE_IMPORT_DESCRIPTOR 5 DWORDS, Size in bytes so time 4
        os.remove(".unipacker_brokenimport.exe")
        return hdr
예제 #2
0
    def find_iat(self,
                 uc,
                 base_addr,
                 total_size,
                 iat_array,
                 dll_name,
                 offset=0x4):
        # hex = ' '.join('0x%02x' % hx for hx in iat_array)
        # print(f"IAT_ARRAY:{hex}")
        pe_write(uc, base_addr, total_size, ".unipacker_brokenimport.exe")
        with open(".unipacker_brokenimport.exe", 'rb') as f:
            b = f.read()

        # Part 1: Find all possible ptrs

        possible_ptrs = []
        for iat_entry in iat_array:
            found_ptr = -1
            possible_addr = []
            while True:
                found_ptr = b.find(struct.pack("I", iat_entry),
                                   (found_ptr + 1), len(b))
                if found_ptr == -1:
                    break
                else:
                    possible_addr.append(found_ptr)

            possible_ptrs.append(possible_addr)

        # Part 2: Validate with offset
        if len(possible_ptrs) == 1:
            if len(possible_ptrs[0]) == 0:
                return None
            return possible_ptrs[0][
                0]  # TODO Default first check with allocated section
        ptrs = []
        for i in range(len(possible_ptrs) - 1):
            l1 = possible_ptrs[i]
            l2 = possible_ptrs[i + 1]
            a1, a2 = self.search_offset_two(l1, l2, offset)
            if a1 is None:
                print("Not Found!")
            ptrs.append(a1)

        lx = possible_ptrs[-1]
        for elem in lx:
            if elem - offset == ptrs[-1]:
                ptrs.append(elem)

        # print_addr_list(f"Printing possible ptrs for {dll_name}: ", ptrs)

        return ptrs[0]
예제 #3
0
파일: shell.py 프로젝트: snemes/unipacker
 def do_onlydmp(self, args):
     args = args or "dump"
     pe_write(self.engine.uc, self.sample.BASE_ADDR,
              self.sample.virtualmemorysize, args)
예제 #4
0
    def dump_image(self,
                   uc,
                   base_addr,
                   virtualmemorysize,
                   apicall_handler,
                   sample,
                   path="unpacked.exe"):
        ntp = apicall_handler.ntp
        dllname_to_functionlist = sample.dllname_to_functionlist
        if len(sample.allocated_chunks) == 0:
            total_size = virtualmemorysize
        else:
            total_size = sorted(sample.allocated_chunks)[-1][1] - base_addr
            virtualmemorysize = total_size

        print(f"Totalsize:{hex(total_size)}, "
              f"VirtualMemorySize:{hex(virtualmemorysize)}")

        print_chunks(sample.allocated_chunks)

        try:
            hdr = PE(uc, base_addr)
        except InvalidPEFile as i:
            print("Invalid PE File... Cannot dump")
            return

        old_number_of_sections = hdr.pe_header.NumberOfSections

        print("Setting unpacked Entry Point")
        print(f"OEP:{hex(uc.reg_read(UC_X86_REG_EIP) - base_addr)}")
        hdr.opt_header.AddressOfEntryPoint = uc.reg_read(
            UC_X86_REG_EIP) - base_addr

        print("Fixing Imports...")
        hdr = self.fix_imports(uc, hdr, virtualmemorysize, total_size,
                               dllname_to_functionlist,
                               sample.original_imports)

        print("Fixing sections")
        self.fix_sections(hdr, old_number_of_sections, virtualmemorysize)

        print("Set IAT-Directory to 0 (VA and Size)")
        hdr.data_directories[12].VirtualAddress = 0
        hdr.data_directories[12].Size = 0

        print(
            f"RVA to import table: {hex(hdr.data_directories[1].VirtualAddress)}"
        )

        if (virtualmemorysize - 0xE000) <= hdr.data_directories[
                1].VirtualAddress <= virtualmemorysize or len(
                    sample.allocated_chunks) != 0 or True:
            print(f"Totalsize:{hex(total_size)}, "
                  f"VirtualMemorySize:{hex(virtualmemorysize)}, "
                  f"Allocated chunks: {sample.allocated_chunks}")
            # print("Relocating Headers to End of Image")
            # hdr.dos_header.e_lfanew = virtualmemorysize - 0x10000
            # hdr = self.add_section(hdr, '.newhdr', 0x10000, virtualmemorysize-0x10000)
            # print("Adding new import section")
            # hdr = self.add_section(hdr, '.nimdata', 0xe000, (virtualmemorysize - 0x10000) + 0x2000)
            # print("Appending allocated chunks at the end of the image")
            # hdr = self.chunk_to_image_section_hdr(hdr, base_addr, sample.allocated_chunks)
            # TODO Fix chunk unmapped space with 0
        else:
            virtualmemorysize -= 0x10000
            total_size = virtualmemorysize

        hdr.sync(uc)

        print("Fixing SizeOfImage...")
        hdr.opt_header.SizeOfImage = alignments(
            total_size, hdr.opt_header.SectionAlignment)

        print("Fixing Memory Protection of Sections")
        hdr = self.fix_section_mem_protections(hdr, ntp)

        hdr.sync(uc)

        print("Fixing Checksum")
        hdr = self.fix_checksum(uc, hdr, base_addr, total_size)
        hdr.sync(uc)

        dllcharacteristics = hdr.opt_header.DllCharacteristics & 0xFFBF
        hdr.opt_header.DllCharacteristics = dllcharacteristics  # Remove Dynamic Base
        hdr.sync(uc)

        print(f"Dumping state to {path}")
        pe_write(uc, base_addr, total_size, path)