我试图写一个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

  • 复制kernel32.dll-> b.dll
  • 修改PE镜像文件b.dll,使其不依赖于ntdll.dll,而是依赖于a.dll
  • 编写一个简单程序a.exe,并修改PE镜像文件a.exe,使其不依赖kernel32.dll,而是依赖b.dll。
  • 运行a.exe,程序使
  • 崩溃

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

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

    最佳答案

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

    因此,如果您尝试将它们加载到其他地址中,它们将会崩溃。从理论上讲,您可以尝试为他们重建重定位信息...但是我不会打赌。

    我的问题又是:为什么不能使用预加载的kernel32/ntdll?为什么觉得您需要私有(private)拷贝?如我所见,您应该将它们视为系统API,因此不要理会它们。

    09-10 04:15
    查看更多