Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何还原windows可执行文件的原始入口点?_C++_Windows_Assembly_Portable Executable - Fatal编程技术网

C++ 如何还原windows可执行文件的原始入口点?

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文件中。修改该值,此时原始值将丢失。如果要获取原始值,必须在修改值之

我正在尝试学习如何修改windows PE并制作打包机。我现在做的是获取一个exe文件,在其中添加一个新的部分,并将oep更改为该新部分。新的部分只会跳回文件的原始地址。以下是新章节的代码:

__asm {
    pushad
        mov eax, 0x0044F125 //oep
        jmp eax
}

如你所见,我必须硬编码oep地址。有什么方法可以存储oep或计算它吗?

oep作为RVA存储在PE文件中。修改该值,此时原始值将丢失。如果要获取原始值,必须在修改值之前读取并记住它。

首先,PE文件的入口点位于标题中,总之,PE格式包含:

  • MZ标头(出于兼容性目的,但包含PE标头的偏移量)
  • PE头(包含有关文件、节数、导入等的信息)。包含:文件头,可选头(这是包含PE文件入口点的头)
  • 节标题
  • 截面数据
有关PE的更多信息:

  • ,有关二进制格式的详细信息,特别是PE格式的详细信息
如果您想进行打包,您需要:

  • 遍历PE头结构以找到原始入口点
  • 使用新的入口点保存和更新
  • 添加新添加部分的信息
  • 第2点和第3点可以按任何顺序进行。如果你先做第2点,你需要知道该部分的位置,阅读现有部分很容易计算。如果你先做第3点,你已经知道新的入口点


    如果您愿意,您可以查看有关如何修改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我知道你为什么问这个问题。不管怎样,没关系。啊,废话,另一个家伙编辑了对不起,我真的被这东西弄疯了。请查看我的答案。这正是我们告诉你的。