我正在尝试学习如何修改Windows PE并制作一个打包器。我目前所做的是获取一个exe文件,向其添加一个新的部分并将oep更改为该新部分。新部分只是跳回文件的原始地址。以下是新部分的代码:
__asm {
pushad
mov eax, 0x0044F125 //oep
jmp eax
}
正如您所看到的,我必须对oep地址进行硬编码。有什么方法可以存储oep或计算它吗?
答案 0 :(得分:1)
首先,PE文件的入口点在标题中,总之,PE格式包含:
有关PE的更多信息:
如果你想做一个包装工,你需要:
第2点和第3点可以按任何顺序执行,如果您先执行第2点,则需要知道该部分的位置,并且可以轻松计算读取现有部分。如果您首先执行第3点,则您已经知道新的入口点。
如果您需要,可以查看UPX packer以获取有关如何修改PE格式以及如何一般地执行打包程序的更多提示。
答案 1 :(得分:0)
OEP作为RVA存储在PE文件中。您修改该值,此时原始值将丢失。如果你想获得原始值,你必须在修改值之前阅读它并记住它。
答案 2 :(得分:0)
好的,我发现它实际上是在文件本身写oep:
void write_stub_entry_point(PIMAGE_NT_HEADERS nt_headers, void *stub_addr) {
if (stub_addr != NULL) {
const char *signature = "\xFF\xEE\xDD\xCC";
unsigned int index = 0;
while (memcmp(((unsigned char *)stub_addr + index), signature, sizeof(int)) != 0) {
++index;
}
DWORD old_protections = 0;
VirtualProtect(((unsigned char *)stub_addr + index), sizeof(DWORD), PAGE_EXECUTE_READWRITE, &old_protections);
memcpy(((unsigned char *)stub_addr + index), &nt_headers->OptionalHeader.AddressOfEntryPoint, sizeof(DWORD));
VirtualProtect(((unsigned char *)stub_addr + index), sizeof(DWORD), old_protections, NULL);
}
}
现在他们只能从文件中恢复它:
__asm { //Epilogue, stub exit point
mov eax, target_image_base
add eax, 0xCCDDEEFF //Signature to be replaced by original entry point (OEP)
mov esp, ebp
mov[esp + 0x20], eax //Store OEP in EAX through ESP to preserve across popad
pop ebp
popad //Restore thread context, with OEP in EAX
jmp eax //Jump to OEP
}