C++ 如何还原windows可执行文件的原始入口点?
我正在尝试学习如何修改windows PE并制作打包机。我现在做的是获取一个exe文件,在其中添加一个新的部分,并将oep更改为该新部分。新的部分只会跳回文件的原始地址。以下是新章节的代码:C++ 如何还原windows可执行文件的原始入口点?,c++,windows,assembly,portable-executable,C++,Windows,Assembly,Portable Executable,我正在尝试学习如何修改windows PE并制作打包机。我现在做的是获取一个exe文件,在其中添加一个新的部分,并将oep更改为该新部分。新的部分只会跳回文件的原始地址。以下是新章节的代码: __asm { pushad mov eax, 0x0044F125 //oep jmp eax } 如你所见,我必须硬编码oep地址。有什么方法可以存储oep或计算它吗?oep作为RVA存储在PE文件中。修改该值,此时原始值将丢失。如果要获取原始值,必须在修改值之
__asm {
pushad
mov eax, 0x0044F125 //oep
jmp eax
}
如你所见,我必须硬编码oep地址。有什么方法可以存储oep或计算它吗?oep作为RVA存储在PE文件中。修改该值,此时原始值将丢失。如果要获取原始值,必须在修改值之前读取并记住它。首先,PE文件的入口点位于标题中,总之,PE格式包含:
- MZ标头(出于兼容性目的,但包含PE标头的偏移量)
- PE头(包含有关文件、节数、导入等的信息)。包含:文件头,可选头(这是包含PE文件入口点的头)
- 节标题
- 截面数据
- ,有关二进制格式的详细信息,特别是PE格式的详细信息
如果您愿意,您可以查看有关如何修改PE格式以及如何进行打包的更多提示。好的,我发现它实际上是在文件中写入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
}
现在他们只从文件中恢复它,如下所示:
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
}
您为什么要计算它?它是静态的?您将如何计算它?您建议的计算的输入是什么?如果我的问题不正确,我很抱歉,但我想知道的是,当您更改oep时,如何找到oep您已经更改了它。AFAIK它只存储一次(在扩展标题中).这就是我看到的一些文件注入器,它们改变了oep,甚至upx也改变了oep,但它们最终都改变了它??要么它们记住了值,要么它们使用魔法来恢复它。请查看我的回答它提供了什么?它与我们告诉你的完全一样。阅读原始值,并记住它。我没有编辑我的答案。我不是qui我知道你为什么问这个问题。不管怎样,没关系。啊,废话,另一个家伙编辑了对不起,我真的被这东西弄疯了。请查看我的答案。这正是我们告诉你的。