一个PE(可移植可执行)文件的入口点接收哪些参数?

7
如果你组装一个PE(.exe,Win32的可移植可执行文件),它有一个入口点,你可以称之为_start_main或任何你喜欢的名称。
问题是 - 这个入口点是否带有一些参数?如果是这样的话,它们是否可以在堆栈中访问?如果可以在堆栈中访问,那么这个入口点函数是否需要清除堆栈?我在哪里可以找到关于这方面的文档?

2
寄存器FS的值,在某种意义上... - Seva Alekseyev
2
你所询问的技术术语是 Windows 进程的 ABI(应用程序二进制接口)。ABI 还告诉你在新执行的进程中可以对寄存器等状态有什么期望(例如,Unix x86-64 ABI 表示大多数寄存器都未初始化。在实践中,Linux 将它们清零,以避免泄漏内核数据)。 - Peter Cordes
1个回答

6

进程在入口点时没有关于其参数的堆栈信息。您需要调用GetCommandLine或通过RTL_USER_PROCESS_PARAMETERS访问PEB中的信息,但这不是一个稳定的API。

每个语言支持库(如CRT)也必须执行此操作。


1
@user2214913 我认为微软没有在任何地方记录这些内容。查看代码后,您可以安全地从入口点返回。它将返回 kernel32.dll 中的 BaseThreadInitThunk,然后立即退出进程。 - typ1232
1
@user2214913 我使用了一个调试器 "OllyDbg",当源代码不可用时,它能够很好地工作,因为它具有良好的汇编分析功能。类似的软件还有:x64dbg、IDA。 - typ1232
3
@user2214913:原始入口点的签名是 DWORD CALLBACK RawEntryPoint(void)。我认为我曾在MSDN中看到过这个文档,但现在找不到了。你可以在WinMain仅仅是Win32进程入口点的约定名称中找到可靠的信息。 - IInspectable
2
有趣。显然,这与Linux x86-64 ABI有很大不同,其中命令行参数和环境变量在进入_start时由栈上的参数指向。令人惊讶的是,在ABI级别,命令行参数甚至是二等公民。您必须要求操作系统将它们提供给您,而不是默认情况下就有它们。此外,在Linux中,您无法从_start返回(您使用exit()系统调用)。动态库ABI与内核进程exec ABI分开,因此没有kernel32.dll等效物。 - Peter Cordes
2
@PeterCordes:你说的几乎都是错的。命令行参数是通过PEB传递给新创建的进程的。一个进程不需要查询操作系统。虽然你可以从本地Windows可执行文件的入口点返回,但这并不会终止进程。在Windows上,你也必须调用ExitProcesskernel32.dll不是内核模块。我对你试图表达的观点感到困惑。 - IInspectable
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接