Windows 32位和64位之间的代码差异

我正在试验下面的代码来模拟GetProcAddress。

// Retrieve NT header from base address. IMAGE_NT_HEADERS *GetNtHeaderFromBase( void *pBaseAddr ) { IMAGE_DOS_HEADER *pDosHeader; IMAGE_NT_HEADERS *pNtHeaders; pDosHeader = ((IMAGE_DOS_HEADER *)pBaseAddr); if(pDosHeader->e_magic != 0x5A4D) return NULL; pNtHeaders = ((IMAGE_NT_HEADERS *)((DWORD)pBaseAddr + pDosHeader->e_lfanew)); if(pNtHeaders->Signature != 0x4550) return NULL; return ((pNtHeaders == NULL) ? NULL : pNtHeaders); } // This emulates GetProcAddress. void *GetFuncAddr( DWORD pBaseAddr, char *lpszFuncName ) { IMAGE_NT_HEADERS *pNtHeaders; IMAGE_DATA_DIRECTORY *pDataDir; IMAGE_EXPORT_DIRECTORY *pExportDir; const char **lpszNames; DWORD *lpdwFuncs, dwIndex; pNtHeaders = GetNtHeaderFromBase((void *)pBaseAddr); if(pNtHeaders == NULL) return NULL; pDataDir = ((IMAGE_DATA_DIRECTORY *)(pNtHeaders->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_EXPORT)); if(pDataDir == NULL) return NULL; pExportDir = ((IMAGE_EXPORT_DIRECTORY *)(pBaseAddr + pDataDir->VirtualAddress)); if(pExportDir == NULL) return NULL; lpdwFuncs = ((DWORD *)(pBaseAddr + pExportDir->AddressOfFunctions)); lpszNames = ((const char **)(pBaseAddr + pExportDir->AddressOfNames)); if(lpdwFuncs == NULL || lpszNames == NULL) return NULL; for(dwIndex = 0; dwIndex < pExportDir->NumberOfFunctions; dwIndex++) { // decrypt funcname and get the address if(!cmpstr(((char *)(pBaseAddr + lpszNames[dwIndex])), lpszFuncName)) return (void*)(pBaseAddr + lpdwFuncs[dwIndex]); } return NULL; } 

但是,当我在Windows Vista x64上运行该程序时,出现访问冲突。 我以为这是GetNtHeaderFromBase(IMAGE_DOS_HEADER和IMAGE_NET_HEADER上传递的数字)上的数字,但我无法find任何地方可能是一个x64位二进制文​​件的任何参考。

任何人都有什么想法,我需要做这个代码,使其在64位Windows下工作? 或者,更好的方法来实现一个在x32和x64上工作的getprocaddress-like函数?

感谢您的帮助和代码。

杰西。

原因是你正在为pBaseAddr方法在DWORD中存储一个指针大小的值。 指针值在64位窗口上是8个字节,而DWORD只有4个字节。 您需要执行以下任一操作

  1. 将pBaseAddr作为指针传递(首选方法)
  2. 将它作为size_t传递,它将在32位窗口上正确地为4个字节,在64位窗口上正确地为8个字节。

我不确定这是否是唯一的问题,但即使在64位平台上, DWORD也是32位。 你正在投射指针,并在64位导致截断。 如果你想要一个指针大小的整数,你应该使用DWORD_PTR或者ULONG_PTR

我也会检查你的结构在这方面是64位安全的。