文件映射方式读取PE文件的问题
DWORD WINAPI ReadThreadProc(LPVOID lpParameter)
{
HANDLE hFile = 0; //文件句柄
HANDLE hHeap = 0; //堆句柄
HANDLE hFileMap = 0; //文件映射句柄
LPVOID lpBuffStart = 0; //指向文件缓冲区开始地址
LPVOID lpCurrent = 0; //当前文件指针
DWORD dwSizeOfFileLow; //文件大小
//打开文件
hFile = ::CreateFile(strFilePath.GetBuffer(),
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
NULL,
NULL
);
if(hFile == INVALID_HANDLE_VALUE)
{
::AfxMessageBox(_T("打开文件出错"));
return 0;
}
dwSizeOfFileLow = GetFileSize(hFile,NULL); //获取文件尺寸
hFileMap = ::CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,0); //建立文件映射
if(hFileMap)
{
lpBuffStart = ::MapViewOfFile(hFileMap,FILE_MAP_READ,0,0,0); //映射文件视图
if(!lpBuffStart)
{
::AfxMessageBox(_T("建立文件视图出错"));
return 0;
}
}
else
{
::AfxMessageBox(_T("建立文件映射出错"));
return 0;
}
lpCurrent = lpBuffStart;
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpCurrent; //调试跟踪这里数据成员的值正常
lpCurrent = (LPDWORD)lpCurrent + pDosHeader->e_lfanew; //移动到PE文件头,调试跟踪这里,最后的结果lpCurrent相加的结果有问题 1240300 = 1240000 + 192
PIMAGE_NT_HEADERS pNTHeaders = (PIMAGE_NT_HEADERS)lpCurrent; //单步跟踪到这里就不行了,成员全为0
::UnmapViewOfFile(lpBuffStart);
::CloseHandle(hFile);
return 1;
}
详细问题请看注释部分,文件映射问题.
我自己认为就算PIMAGE_NT_HEADERS pNTHeaders定位地址出错,pNTHeaders里面的成员,应该错误的值,不应该全是0
------解决方案--------------------lpCurrent = (LPDWORD)lpCurrent + pDosHeader->e_lfanew; //移动到PE文件头,调试跟踪这里,最后的结果
这一行有问题的,应该改成
lpCurrent = (PBYTE)lpCurrent + pDosHeader->e_lfanew;
否则是按pDosHeader->e_lfanew×4的偏移去移动。去好好看一下指针操作的注意事项吧。
------解决方案--------------------192?不是应该是3C的么。
------解决方案--------------------lpCurrent = (LPDWORD)lpCurrent + pDosHeader->e_lfanew;
PIMAGE_NT_HEADERS pNTHeaders = (PIMAGE_NT_HEADERS)lpCurrent;
改成这样转换
C/C++ code
PIMAGE_NT_HEADERS pNTHeaders = (PIMAGE_NT_HEADERS)((DWORD)lpCurrent+ (DWORD)(pDosHeader ->e_lfanew));
------解决方案--------------------
楼上的都说明白了,就是NT头指针移动的问题
------解决方案--------------------
都写PE分析的程序了,应该有些动手能力吧,这种问题随便一调试,看看变量的值不就清楚了?