真正的 PE32(+) 入口点 - 是否记录在任何地方?

逆向工程 视窗 聚乙烯
2021-06-13 07:30:23

Microsoft 文档将WinMain()作为 Windows 程序的入口点,但与DllMain()不同,它似乎是由编译器提供的启动代码安排的纯虚构。

我查看了几个 Win32 编译器(32 位和 64 位)的输出,在所有情况下,传递给的信息WinMain()都是由启动代码合成的,而不是基于 Windows 加载程序传递给入口点的任何参数. 此外,我分析的所有样本——以及我记得在“网上”看到的所有示例——都使用了,ExitProcess()即使从入口点简单返回似乎具有完全相同的效果。

有没有人知道任何关于 PE32(+) 入口点游戏规则的文件 - 官方的或其他的?

2个回答

Microsoft 文档将WinMain()作为 Windows 程序的入口点

不,Microsoft 的文档没有将 WinMain() 作为Windows 程序入口点。

从上面链接到的 WinMain() 文档(重点是我的)-“WinMain 入口点 [是]用户提供的基于 Windows 的图形应用程序的入口点......根据编程框架,对 WinMain 的调用功能可以在特定于该框架的附加活动之前和之后进行。”

换句话说,如果您正在构建本机应用程序,您的编译器可能会构建您的可执行文件,以便在您的 WinMain() 函数之前执行其框架初始化代码。

有没有人知道任何关于 PE32(+) 入口点游戏规则的文件 - 官方的或其他的?

是的,根据Microsoft PE 和 COFF 规范AddressOfEntryPointPE 标头中字段定义为“对于程序映像,这是起始地址”。该字段通常指向上述框架初始化代码。

请注意,尽管AddressOfEntryPoint是程序的起始地址,但该地址处的代码将TLS 回调函数(也记录在 PE/COFF 文档中)(如果存在)之后以及静态加载的 DLL 的 DllMain() 函数之后执行。

由 Windows 加载程序传递给入口点的参数

正如@igor-skochinsky在此处解释的那样,“PE 文件入口点的寄存器没有定义的值。” 然而,正如他所指出的,EAX经常指向AddressOfEntryPointEBX经常指向 PEB。

您可能需要参考@Ange 的初始值文档以在入口点查找其他非官方寄存器值。

真正的 PE 入口点是什么意思?

我认为您对 WinMain 和 AddressOfEntryPoint 感到困惑。

WinMain 不是 AddressOfEntryPoint 它们是不同的东西。

入口点地址

当可执行文件加载到内存时,入口点的地址,相对于图像库。对于程序映像,这是起始地址。对于设备驱动程序,这是初始化函数的地址。入口点对于 DLL 是可选的。当不存在时,此字段应为 0。

AddressOfEntryPoint 没有参数,它只是可执行文件的起始地址。(也许除了在 Windows Vista+ 上,我已经看到 PEB 地址是由 kernel32.BaseThreadInitThunk 作为参数传递的)

你说的对。来自入口点的简单 RET 就足以退出该过程。但我想这样你就必须保持堆栈平衡。

看看 Microsoft Portable Executable and Common Object File Format

PE文件格式