【问题标题】:How to restore original entry point of a windows executable?如何恢复 Windows 可执行文件的原始入口点?
【发布时间】:2014-08-11 13:23:56
【问题描述】:

我正在尝试学习如何修改 windows PE 并制作打包程序。我目前所做的是获取一个 exe 文件,向其中添加一个新部分并将 oep 更改为该新部分。该新部分的唯一作用是跳回文件的原始地址。这是新部分的代码:

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

如您所见,我必须对 oep 地址进行硬编码。有什么方法可以存储或计算 oep?

【问题讨论】:

  • 为什么要计算它?是静态的吗?你将如何计算它?您提议的计算的输入是什么?
  • 如果我的问题不正确,我很抱歉,但我只想知道如何找回 oep
  • 当您更改了 oep 时,您已经更改了它。 AFAIK 它只存储一次(在扩展标题中)。
  • 这是我看到的一些文件注入器,它们都改变了 oep,甚至 upx 也能做到,但最后它们都把它改回来了怎么办?? rohitab.com/discuss/topic/33006-detailed-guide-to-pe-infection
  • 要么记住这个值,要么用魔法恢复它。

标签: c++ windows assembly portable-executable


【解决方案1】:

首先PE文件的入口点在标题中,概括地说PE格式包含:

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

关于 PE 的更多信息:

如果你想做一个打包机,你需要:

  1. 遍历 PE 标头结构以定位原始入口点
  2. 已保存并使用新入口点更新
  3. 添加新添加部分的信息。

第 2 点和第 3 点可以按任何顺序执行,如果您先执行第 2 点,您需要知道该部分的位置,阅读现有部分很容易计算。如果您先执行第 3 点,则您已经知道新的入口点。

如果您愿意,可以查看UPX packer,了解有关如何修改 PE 格式以及如何进行一般打包程序的更多提示。

【讨论】:

  • 请查看我的回答
【解决方案2】:

OEP 作为 RVA 存储在 PE 文件中。您修改该值,此时原始值将丢失。如果要获取原始值,则必须阅读并记住它,然后再修改值。

【讨论】:

  • 请查看我的回答
  • 它提供什么?这正是我们告诉你的。读取原始值,并记住它。
  • 我没有编辑我的答案。我不太清楚你为什么问这个问题。无论如何,没关系。
  • aah 废话,其他人编辑了抱歉,我真的被这些东西发疯了
【解决方案3】:

好的,我发现它实际上像这样将 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
}

【讨论】:

  • 这正是我们告诉你的。
猜你喜欢
  • 2014-09-06
  • 1970-01-01
  • 2015-12-09
  • 1970-01-01
  • 2013-03-16
  • 2017-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多