c - 在 Windows x64 上访问 char** 的内容会导致异常

标签 c windows pointers

以下代码在 Windows Vista x64 上导致异常,我不明白为什么。

size_t pBaseAddr;
char *lpszFuncName;
IMAGE_EXPORT_DIRECTORY *pExportDir;
const char **lpszNames;
unsigned int dwIndex;

lpszNames  = ((const char **)(pBaseAddr + pExportDir->AddressOfNames));
if(lpszNames == NULL)
  return NULL;

for(dwIndex = 0; dwIndex < pExportDir->NumberOfFunctions; dwIndex++)
{ 
   if(strcmp((char *)(pBaseAddr + lpszNames[dwIndex]), lpszFuncName) == 0)
       return Something;
}

我认为问题出在 strcmp() 行上,特别是在 lpszNames[dwIndex] 上。它适用于 32 位,但在 64 位上它会因访问冲突而崩溃。 如果您想查看完整代码 check my previous question

编辑:由于人们没有查看我在问题上发布的链接,我将发布原始问题的完整代码。

// 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 != IMAGE_DOS_SIGNATURE)
  return NULL;

 pNtHeaders = ((IMAGE_NT_HEADERS *)((DWORD)pBaseAddr + pDosHeader->e_lfanew));
 if(pNtHeaders->Signature != IMAGE_NT_SIGNATURE)
  return NULL;

 return ((pNtHeaders == NULL) ? NULL : pNtHeaders);
}


// This emulates GetProcAddress.
void *GetFuncAddr( size_t pBaseAddr, char *lpszFuncName ) 
{
 IMAGE_NT_HEADERS       *pNtHeaders;
 IMAGE_DATA_DIRECTORY   *pDataDir;
 IMAGE_EXPORT_DIRECTORY *pExportDir;
 const char      **lpszNames;
 size_t       *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  = ((size_t *)(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(strcmp((char *)(pBaseAddr + lpszNames[dwIndex]), lpszFuncName) == 0)
   return (void*)(pBaseAddr + lpdwFuncs[dwIndex]);
 }

 return NULL;
}

EDIT2:不,我没有使用 DWORD。

最佳答案

访问冲突意味着您可能试图取消引用 lpszNames 数组中的空指针。

lpszNames[dwIndex] 正在返回一个 char *,它可能没有指向有效数据。

你能验证 lpszNames[dwIndex] 不返回 null 吗?

实际上,它甚至不必为空,它可以只是定义为“ protected ”内存中的地址。

关于c - 在 Windows x64 上访问 char** 的内容会导致异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1771130/

相关文章:

c - 像 Matlab 在 C 中那样读取原始音频文件

java - 从 Java 以最小化状态启动应用程序

Ruby Dir.glob 问题仅在 Windows 上

java - Linux 和 Windows java 编译器生成相同还是不同的类文件?

c - 让 fgets 将字符保存到 C 中的变量中

c++ - 在编译系统中,链接器(ld)如何知道将myprogram.o链接到谁?

C++ new <datatype>(<value>) 到底做什么?

c - 在C中将变量插入指针数组的最有效方法

c++ - 将遗留 C 代码重构为 MVC 设计

c++ - 关于 C++ 指针和引用,需要澄清