首页 > 解决方案 > 在 Windows 上的 32 位进程中强制加载超过 2GB (0x80000000) 的 DLL

问题描述

为了在我们的调试器中测试一个极端情况,我需要想出一个程序,它的 DLL 加载超过 2GB ( 0x80000000)。当前的测试用例是一个多 GB 的游戏,它加载 >700 个 DLL,我想要一些更简单、更小的东西。有没有办法可靠地实现它而无需太多的摆弄?我假设我需要使用/LARGEADDRESSAWARE并以某种方式消耗足够的 VA 空间来将新的 DLL 提升到 2GB 以上,但我对细节很模糊......

标签: winapidllportable-executablevirtual-address-space

解决方案


好的,我尝试了几次,但我设法想出了一些可行的方法。

// cl /MT /Ox test.cpp /link /LARGEADDRESSAWARE
// occupy the 2 gigabytes!
#define ALLOCSIZE (64*1024)
#define TWOGB (2*1024ull*1024*1024)

#include <windows.h>
#include <stdio.h>

int main()
{
  int nallocs = TWOGB/ALLOCSIZE;
  for ( int i = 0; i < nallocs+200; i++ )
  {
   void * p = VirtualAlloc(NULL, ALLOCSIZE, MEM_RESERVE, PAGE_NOACCESS);
   if ( i%100 == 0)
   {
     if ( p != NULL )
       printf("%d: %p\n", i, p);
     else
     {
       printf("%d: failed!\n", i);
       break;
     }
   }
  }
  printf("finished VirtualAlloc. Loading  a DLL.\n");
  //getchar();
  HMODULE hDll = LoadLibrary("winhttp");

  printf("DLL base: %p.\n", hDll);
  //getchar();
  FreeLibrary(hDll);
}

在 Win10 x64 上产生:

0: 00D80000
100: 03950000
200: 03F90000
[...]
31800: 7FBC0000
31900: 00220000
32000: 00860000
32100: 80140000
32200: 80780000
32300: 80DC0000
32400: 81400000
32500: 81A40000
32600: 82080000
32700: 826C0000
32800: 82D00000

32900: 83340000
finished VirtualAlloc. Loading  a DLL.
DLL base: 83780000.

推荐阅读