我正在开发一个项目,我想通过在 Windows 上使用 C 将正在运行的 PE(可移植可执行)文件的部分从内存复制到磁盘来创建新的可执行文件。但是,当我尝试运行输出文件时遇到问题,导致“无效访问内存”错误。
这是我的方法:
// current base address
IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*)hModule;
IMAGE_NT_HEADERS* ntHeaders = (IMAGE_NT_HEADERS*)((BYTE*)hModule + dosHeader->e_lfanew);
IMAGE_FILE_HEADER* fileHeader = &ntHeaders->FileHeader;
IMAGE_OPTIONAL_HEADER* optionalHeader = &ntHeaders->OptionalHeader;
unsigned char* buffer = (unsigned char*)malloc(optionalHeader->SizeOfImage);
memset(buffer, 0, optionalHeader->SizeOfImage);
// Copy the headers
memcpy(buffer, dosHeader, dosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS));
// Copy each section
IMAGE_SECTION_HEADER* sectionHeader = (IMAGE_SECTION_HEADER*)(ntHeaders + 1);
for (int i = 0; i < fileHeader->NumberOfSections; i++) {
memcpy(buffer + sectionHeader[i].VirtualAddress,
(BYTE*)hModule + sectionHeader[i].PointerToRawData,
sectionHeader[i].SizeOfRawData);
}
... then i write it to disk using writeFile API
PE之后,加载到内存中,它被修改,导入解析,并且
FirstThunk
指向的数据被修改为真实的api地址,当它在磁盘上时必须指向IMAGE_IMPORT_BY_NAME
或等于序数。因此,您必须修复导入的最低限度 - 将 OriginalFirstThunk
的上下文复制到 FirstThunk
。然而搬迁并不是问题。所需要的一切,pinth->OptionalHeader.ImageBase
对应于已经加载并进行重定位的真实图像基础。和窗户自行调整OptionalHeader.ImageBase
到新的正确底座。
导入后PE会出现延迟导入的情况,这个也需要修复,如果已经解决的话。全局变量可以修改,__security_cookie
- 它必须在开始时0x2B992DDFA232
或LdrInitSecurityCookie
失败,等等。我们可以修复几乎所有变量,除了全局变量,我们通常不知道如何修复初始值