做完文件校驗後將映像映射到內存當中。
[cpp]
/*
* 將文件內容按虛擬地址信息映射到地址空間,返回模塊的基地址
*/
char* LdrLayoutPe(char*pImage, DWORD FileSize)
{
PIMAGE_FILE_HEADER pFileHeader;
PIMAGE_SECTION_HEADER pSectionHeader;
char* pOptionalHeader;
char* pImageBase;
char* pRealImageBase;
DWORD SizeOfImage;
WORD Magic;
DWORD i;
if(!LdrValidateImage(pImage, FileSize))
return NULL;
pFileHeader = _GetFileHeaderFromPe(pImage);
pSectionHeader = _GetSectionHeaderFromPe(pFileHeader);
pOptionalHeader = (char*)pFileHeader + sizeof(IMAGE_FILE_HEADER);
Magic = *(WORD*)pOptionalHeader;
pImageBase = _GetImageBaseFromPe(pFileHeader);
SizeOfImage = *(DWORD*)(pOptionalHeader + 0x38);
pRealImageBase = (char*)VirtualAlloc(pImageBase, SizeOfImage, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
if(!pRealImageBase){
pRealImageBase = (char*)VirtualAlloc(NULL, SizeOfImage, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
if(!pRealImageBase)
return FALSE;
}
//拷貝文件頭信息
RtlCopyMemory(pRealImageBase, pImage, (char*)pSectionHeader - pImage + pFileHeader->NumberOfSections*sizeof(PIMAGE_SECTION_HEADER));
//拷貝節信息到內存
for(i = 0; i < pFileHeader->NumberOfSections; i++){
if(!pSectionHeader[i].PointerToRawData)
continue;
RtlCopyMemory(pRealImageBase + pSectionHeader[i].VirtualAddress,
pImage + pSectionHeader[i].PointerToRawData, pSectionHeader[i].SizeOfRawData);
}
return pRealImageBase;
}
摘自 雲淡風輕