This commit is contained in:
恍兮惚兮 2024-06-25 19:49:49 +08:00
parent 6d640336b1
commit 8a6181861a
4 changed files with 238 additions and 24 deletions

View File

@ -0,0 +1,233 @@
from ctypes import (
c_size_t,
windll,
memmove,
Structure,
c_uint64,
cast,
POINTER,
sizeof,
c_char_p,
)
from ctypes.wintypes import LPVOID, DWORD, WORD, LONG, BYTE
ULONGLONG = c_uint64
kernel32 = windll.kernel32
VirtualAlloc = kernel32.VirtualAlloc
VirtualAlloc.argtypes = LPVOID, c_size_t, DWORD, DWORD
VirtualAlloc.restype = LPVOID
VirtualFree = kernel32.VirtualFree
VirtualFree.argtypes = LPVOID, c_size_t, DWORD
class IMAGE_DOS_HEADER(Structure):
_fields_ = [("_nouse", WORD * 30), ("e_lfanew", LONG)]
class IMAGE_FILE_HEADER(Structure):
_fields_ = [
("Machine", WORD),
("NumberOfSections", WORD),
("TimeDateStamp", DWORD),
("PointerToSymbolTable", DWORD),
("NumberOfSymbols", DWORD),
("SizeOfOptionalHeader", WORD),
("Characteristics", WORD),
]
class IMAGE_DATA_DIRECTORY(Structure):
_fields_ = [
("VirtualAddress", DWORD),
("Size", DWORD),
]
IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16
class IMAGE_OPTIONAL_HEADER32(Structure):
_fields_ = [
("Magic", WORD),
("MajorLinkerVersion", BYTE),
("MinorLinkerVersion", BYTE),
("SizeOfCode", DWORD),
("SizeOfInitializedData", DWORD),
("SizeOfUninitializedData", DWORD),
("AddressOfEntryPoint", DWORD),
("BaseOfCode", DWORD),
("BaseOfData", DWORD),
("ImageBase", DWORD),
("SectionAlignment", DWORD),
("FileAlignment", DWORD),
("MajorOperatingSystemVersion", WORD),
("MinorOperatingSystemVersion", WORD),
("MajorImageVersion", WORD),
("MinorImageVersion", WORD),
("MajorSubsystemVersion", WORD),
("MinorSubsystemVersion", WORD),
("Win32VersionValue", DWORD),
("SizeOfImage", DWORD),
("SizeOfHeaders", DWORD),
("CheckSum", DWORD),
("Subsystem", WORD),
("DllCharacteristics", WORD),
("SizeOfStackReserve", DWORD),
("SizeOfStackCommit", DWORD),
("SizeOfHeapReserve", DWORD),
("SizeOfHeapCommit", DWORD),
("LoaderFlags", DWORD),
("NumberOfRvaAndSizes", DWORD),
("DataDirectory", IMAGE_DATA_DIRECTORY * IMAGE_NUMBEROF_DIRECTORY_ENTRIES),
]
class IMAGE_OPTIONAL_HEADER64(Structure):
_fields_ = [
("Magic", WORD),
("MajorLinkerVersion", BYTE),
("MinorLinkerVersion", BYTE),
("SizeOfCode", DWORD),
("SizeOfInitializedData", DWORD),
("SizeOfUninitializedData", DWORD),
("AddressOfEntryPoint", DWORD),
("BaseOfCode", DWORD),
("ImageBase", ULONGLONG),
("SectionAlignment", DWORD),
("FileAlignment", DWORD),
("MajorOperatingSystemVersion", WORD),
("MinorOperatingSystemVersion", WORD),
("MajorImageVersion", WORD),
("MinorImageVersion", WORD),
("MajorSubsystemVersion", WORD),
("MinorSubsystemVersion", WORD),
("Win32VersionValue", DWORD),
("SizeOfImage", DWORD),
("SizeOfHeaders", DWORD),
("CheckSum", DWORD),
("Subsystem", WORD),
("DllCharacteristics", WORD),
("SizeOfStackReserve", ULONGLONG),
("SizeOfStackCommit", ULONGLONG),
("SizeOfHeapReserve", ULONGLONG),
("SizeOfHeapCommit", ULONGLONG),
("LoaderFlags", DWORD),
("NumberOfRvaAndSizes", DWORD),
("DataDirectory", IMAGE_DATA_DIRECTORY * IMAGE_NUMBEROF_DIRECTORY_ENTRIES),
]
class IMAGE_NT_HEADERS32(Structure):
_fields_ = [
("_nouse", DWORD),
("FileHeader", IMAGE_FILE_HEADER),
("OptionalHeader", IMAGE_OPTIONAL_HEADER32),
]
class IMAGE_NT_HEADERS64(Structure):
_fields_ = [
("_nouse", DWORD),
("FileHeader", IMAGE_FILE_HEADER),
("OptionalHeader", IMAGE_OPTIONAL_HEADER64),
]
IMAGE_SIZEOF_SHORT_NAME = 8
class IMAGE_SECTION_HEADER(Structure):
_fields_ = [
("Name", BYTE * IMAGE_SIZEOF_SHORT_NAME),
("VirtualSize", DWORD),
("VirtualAddress", DWORD),
("SizeOfRawData", DWORD),
("PointerToRawData", DWORD),
("PointerToRelocations", DWORD),
("PointerToLinenumbers", DWORD),
("NumberOfRelocations", WORD),
("NumberOfLinenumbers", WORD),
("Characteristics", DWORD),
]
MEM_COMMIT = 0x00001000
MEM_DECOMMIT = 0x00004000
PAGE_READWRITE = 0x04
IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10B
IMAGE_DIRECTORY_ENTRY_IMPORT = 1
class IMAGE_IMPORT_DESCRIPTOR(Structure):
_fields_ = [
("OriginalFirstThunk", DWORD),
("TimeDateStamp", DWORD),
("ForwarderChain", DWORD),
("Name", DWORD),
("FirstThunk", DWORD),
]
def Rva2Offset(rva, psh, pnt, IMAGE_NT_HEADERS):
pSeh = psh
psh = cast(psh, POINTER(IMAGE_SECTION_HEADER))
pnt = cast(pnt, POINTER(IMAGE_NT_HEADERS))
for i in range(pnt.contents.FileHeader.NumberOfSections):
pSeh1 = cast(pSeh, POINTER(IMAGE_SECTION_HEADER)).contents
if (
rva >= pSeh1.VirtualAddress
and rva < pSeh1.VirtualAddress + pSeh1.VirtualSize
):
break
pSeh += sizeof(IMAGE_SECTION_HEADER)
pSeh = cast(pSeh, POINTER(IMAGE_SECTION_HEADER)).contents
return rva - pSeh.VirtualAddress + pSeh.PointerToRawData
def importanalysis(fname):
with open(fname, "rb") as ff:
bs = ff.read()
virtualpointer = VirtualAlloc(None, len(bs), MEM_COMMIT, PAGE_READWRITE)
memmove(virtualpointer, bs, len(bs))
ntheaders_addr = (
virtualpointer
+ cast(virtualpointer, POINTER(IMAGE_DOS_HEADER)).contents.e_lfanew
)
ntheaders = cast(ntheaders_addr, POINTER(IMAGE_NT_HEADERS32)).contents
IMAGE_NT_HEADERS = IMAGE_NT_HEADERS32
magic = ntheaders.OptionalHeader.Magic
if magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC:
ntheaders = cast(ntheaders_addr, POINTER(IMAGE_NT_HEADERS64)).contents
IMAGE_NT_HEADERS = IMAGE_NT_HEADERS64
pSech = (
ntheaders_addr
+ sizeof(DWORD)
+ sizeof(IMAGE_FILE_HEADER)
+ ntheaders.FileHeader.SizeOfOptionalHeader
)
pImportDescriptor = virtualpointer + Rva2Offset(
ntheaders.OptionalHeader.DataDirectory[
IMAGE_DIRECTORY_ENTRY_IMPORT
].VirtualAddress,
pSech,
ntheaders_addr,
IMAGE_NT_HEADERS,
)
pImportDescriptor_data = cast(
pImportDescriptor, POINTER(IMAGE_IMPORT_DESCRIPTOR)
).contents
collect = []
while pImportDescriptor_data.Name:
offset = Rva2Offset(
pImportDescriptor_data.Name, pSech, ntheaders_addr, IMAGE_NT_HEADERS
)
name = virtualpointer + offset
collect.append((cast(name, c_char_p).value.decode(), offset))
pImportDescriptor += sizeof(IMAGE_IMPORT_DESCRIPTOR)
pImportDescriptor_data = cast(
pImportDescriptor, POINTER(IMAGE_IMPORT_DESCRIPTOR)
).contents
VirtualFree(virtualpointer, len(bs), MEM_DECOMMIT)
return collect

View File

@ -1,5 +1,4 @@
PyQt5==5.15.10
PyQt5-Qt5==5.15.2
webviewpy==1.3.0
pefile
tinycss2

View File

@ -1,5 +1,4 @@
PyQt6==6.7.0
PyQt6-Qt6==6.7.0
webviewpy==1.3.0
pefile
tinycss2

View File

@ -1,7 +1,7 @@
import modulefinder, shutil, os, sys, pefile
import modulefinder, shutil, os, sys
import builtins, platform
import sys
from importanalysis import importanalysis
pyversion = platform.python_version()
pyversion2 = "".join(pyversion.split(".")[:2])
x86 = platform.architecture()[0] == "32bit"
@ -222,31 +222,15 @@ for f in collect:
if f.endswith(".pyc") or f.endswith("Thumbs.db"):
os.remove(f)
elif f.endswith(".exe") or f.endswith(".pyd") or f.endswith(".dll"):
try:
pe = pefile.PE(f)
import_table = pe.DIRECTORY_ENTRY_IMPORT
imports = []
for entry in import_table:
if entry.dll.decode("utf-8").lower().startswith("api"):
imports.append(entry.dll.decode("utf-8"))
pe.close()
except:
continue
if f.endswith("Magpie.Core.exe"):
continue
if f.endswith("QtWidgets.pyd"):
imports += [
"api-ms-win-crt-runtime-l1-1-0.dll",
"api-ms-win-crt-heap-l1-1-0.dll",
]
# pefile好像有bug仅对于QtWidgets.pyd这个文件只能读取到导入了Qt5Widgets.dll
imports=importanalysis(f)
print(f, imports)
if len(imports) == 0:
continue
with open(f, "rb") as ff:
bs = bytearray(ff.read())
for _dll in imports:
for _dll,offset in imports:
if _dll.lower().startswith("api-ms-win-core"):
# 其实对于api-ms-win-core-winrt-XXX实际上是到ComBase.dll之类的不过此项目中不包含这些
_target = "kernel32.dll"
@ -254,9 +238,8 @@ for f in collect:
_target = "ucrtbase.dll"
_dll = _dll.encode()
_target = _target.encode()
idx = bs.find(_dll)
# print(len(bs))
bs[idx : idx + len(_dll)] = _target + b"\0" * (len(_dll) - len(_target))
bs[offset : offset + len(_dll)] = _target + b"\0" * (len(_dll) - len(_target))
# print(len(bs))
with open(f, "wb") as ff:
ff.write(bs)