rcx 是否总是指向进程入口点的 PEB?

Sir*_*dom 5 c windows assembly winapi x86-64

64 位 Windows 似乎调用 exe 的入口点,rcx = r8 = &PEB并且rdx = r9 = &entrypoint好像入口点已声明entrypoint(PEB *peb, void *entry)

这些细节是在任何地方指定的,还是没有记录在案且不值得依赖?

RbM*_*bMm 4

从 vista windows 开始,使用一个参数调用 exe 入口点 - PEB的地址 ,因此 exe 入口点的签名必须是下一个

ULONG __stdcall ep(PEB* ); 
Run Code Online (Sandbox Code Playgroud)

因为在 x64 中,第一个参数是通过rcx寄存器传递的 - 您可以在此处查看PEB的地址。另一个寄存器中的值是随机的。但我怎么说 - 这不仅仅与 64 位相关。在所有 Windows 版本中,第一个参数中将包含PEB的地址。

这没有记录,但我确信非常可靠,并且在新的 Windows 版本中不会改变。

在wdk中存在nt.lib。这是静态(非导入)库 - 它为只能使用ntdll.dll导入的应用程序实现了微型 crt(主要启动执行应用程序,如autochk.exe)此库实现了 exe ( ) 的入口点,该入口点比使用常用参数调用NtProcessStartup[W]您的[w]main。当前NtProcessStartup[W]的实现使用指向PEB第一个(和单个)参数的指针。假设我们链接到当前的nt.lib实现。因为这是静态库 - 代码NtProcessStartup[W]将位于您的 exe 内部并且尚未更改。如果 Windows 不再在第一个参数中传递PEB的地址 - 所有与当前nt.lib链接的 exe将在启动时崩溃。所以我认为这已经不会改变

  • 请注意,对于通过 [`RtlCreateUserProcess`](https://github.com/reactos/reactos/blob/893a3c9d030fd8b078cbd747eeefd3f6ce57e560/sdk/lib/rtl/process.c#L178) 创建本机进程(链接到应符合Server 2003),NT 始终将 PEB 地址传递给启动例程。这在 Vista 中并不是什么新鲜事。您可以在 [`RtlInitializeContext`](https://github.com/reactos/reactos/blob/893a3c9d030fd8b078cbd747eeefd3f6ce57e560/sdk/lib/rtl/i386/thread.c#L22) 中查看 `RtlCreateUserThread` 如何为 x86 设置堆栈。 (2认同)
  • 在 Vista 之前,WINAPI `CreateProcessW` 通过 `BaseCreateStack` 和 [`BaseInitializeContext`](https://github.com/reactos/reactos/blob/effdb6f232aa4448179c2b0a0f70aaa20856357c/dll/win32/kernel32/client/utils.c 创建初始上下文#L508),在 x86 中设置上下文将寄存器 `EAX` 和 `EBX` 中的启动地址和 PEB 地址传递给 [`BaseProcessStartThunk`](https://github.com/reactos/reactos/blob/effdb6f232aa4448179c2b0a0f70aaa20856357c/ dll/win32/kernel32/client/i386/thread.S#L29)。 (2认同)
  • 然而,thunk仅在调用[`BaseProcessStartup`](https://github.com/reactos/reactos/blob/93220e26d078b566ed67d56adad79e7e1e4c16f0/dll/win32/kernel32/client/proc.c#时推送`EAX`(起始地址) L448)。`EBX`中的PEB地址被忽略,并且不带参数调用实际的图像起始地址。再说一遍,这是 Vista 之前的事情。 (2认同)