以下代码在 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/