如何在不链接kernel32.dll和ntdll.dll的情况下运行PE映像

cnz*_*lxj 7 c c++ windows system

我试着写一个peloader.我首先将可执行映像及其所有依赖的dll(包括kernel32.dll和ntdll.dll)加载到内存中,处理所有导入地址表,重写所有需要重定位的数据.

然后我按顺序调用所有图像的EntryPoint.我从ntdll.dll的EntryPoint获得返回码0,但kernel32.dll返回0xC0000000.当我试图调用可执行映像的EntryPoint时,程序崩溃了.

我知道Windows系统在创建进程时已经将ntdll.dll和kernel32.dll加载到进程内存中.我的问题是如何将ntdll.dll和kernel32.dll的另一个副本加载到内存中,并将我的模块链接到副本.

我做了一个实验:1.复制ntdll.dll - > a.dll

  1. 复制kernel32.dll - > b.dll
  2. 修改PE映像文件b.dll使其不依赖于ntdll.dll而是依赖于a.dll
  3. 编写一个简单的程序a.exe,并修改PE映像文件a.exe,使其不依赖于kernel32.dll而是b.dll
  4. 运行a.exe,程序崩溃了

是否可以使a.exe正确运行?

这是我关于堆栈溢出的第一个问题,对不起我糟糕的英语.谢谢.

rod*_*igo 4

我不认为你能做到这一点。kernel32.dll 和 ntdll.dll,AFAIK 是不可重定位的。也就是说,MS 删除了它们的重定位信息,因为它们已经加载到每个进程中,因此按照设计,它们分配的地址始终可用。

因此,如果您尝试将它们加载到不同的地址,它们就会崩溃。理论上你可以尝试为他们重建搬迁信息......但我不会打赌。

我的问题是:为什么不能使用预加载的 kernel32/ntdll?为什么您觉得需要私人副本?在我看来,您应该将它们视为系统 API,因此不要管它们。