导入表有些复杂,文件与内存中的格式不太一样
理解导入表的结构是关键
void TestPrintImportDirectory(LPSTR lpszFile)
{
LPVOID pFileBuffer = NULL;
pFileBuffer= ReadPEFile(lpszFile);
if(!pFileBuffer)
{
printf("文件读取失败\n");
return;
}
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader_ADD = NULL;
PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;
//Header信息
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
pDataDirectory = pOptionHeader->DataDirectory;
//IMAGE_DIRECTORY_ENTRY_IMPORT
/*
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory
*/
//确定导入表
//pImportDirectory = NULL;
IMAGE_DATA_DIRECTORY pImportDirectory = pDataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
DWORD ImportVirtualAddress = pImportDirectory.VirtualAddress;
DWORD ImportFoa = RVAToFileOffset(pFileBuffer,ImportVirtualAddress);
printf("ImportVirtualAddress: %x \n",ImportVirtualAddress);
printf("Size: %x \n",pImportDirectory.Size);
printf("ImportFoa: %x \n",ImportFoa);
//输出所有的导入表
//PIMAGE_THUNK_DATA32 pThunkData = NULL;
//第一个导入表
PIMAGE_IMPORT_DESCRIPTOR pImportDes = NULL;
pImportDes = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pFileBuffer + ImportFoa);
while(pImportDes->OriginalFirstThunk != 0x0 && pImportDes->FirstThunk != 0x0 )
{
//输出所有的dll
printf("OriginalFirstThunk: %x\n",pImportDes->OriginalFirstThunk);
DWORD pNameAddress = RVAToFileOffset(pFileBuffer,pImportDes->Name);
PSTR pDllName = (PSTR)((DWORD)pFileBuffer + pNameAddress);
printf("name: %s \n",pDllName);
printf("------------------------------------------\n");
//输出OriginalFirstThunk的信息
DWORD Thunk_Address = RVAToFileOffset(pFileBuffer,pImportDes->OriginalFirstThunk);
PIMAGE_THUNK_DATA32 pThunkData = (PIMAGE_THUNK_DATA32)((DWORD)pFileBuffer + Thunk_Address);
//根据pThunkData 的最高为来判断
DWORD ImportOrdinal = pThunkData->u1.Ordinal;
while(ImportOrdinal)
{
//输出所有所有的信息
//#define IMAGE_ORDINAL_FLAG32 0x80000000
if(ImportOrdinal & IMAGE_ORDINAL_FLAG32)
{
printf("按序号导入:%x\n",ImportOrdinal&0x0FFF);
}else
{
DWORD ImageNameAddress = RVAToFileOffset(pFileBuffer,ImportOrdinal);
PIMAGE_IMPORT_BY_NAME pImageName = (PIMAGE_IMPORT_BY_NAME)(DWORD(pFileBuffer)+ImageNameAddress);
printf("按名字导入:%x - %s \n",pImageName->Hint,pImageName->Name);
}
//向下移动
pThunkData = (PIMAGE_THUNK_DATA32)((DWORD)pThunkData + 4);
ImportOrdinal = pThunkData->u1.Ordinal;
}
printf("------------------------------------------\n");
//printf("FirstThunk:%x \n",pImportDes->FirstThunk);
DWORD pFirstThunk = (DWORD)pImportDes->FirstThunk;
printf("FirstThunk:%x \n",pImportDes->FirstThunk);
printf("------------------------------------------\n");
DWORD FirstThunk_Address = RVAToFileOffset(pFileBuffer,pFirstThunk);
PIMAGE_THUNK_DATA32 pNewThunkData = (PIMAGE_THUNK_DATA32)((DWORD)pFileBuffer + FirstThunk_Address);
DWORD newImportOrdinal = pNewThunkData->u1.Ordinal;
while(newImportOrdinal)
{
//输出所有所有的信息
//#define IMAGE_ORDINAL_FLAG32 0x80000000
if(newImportOrdinal & IMAGE_ORDINAL_FLAG32)
{
printf("按序号导入:%x\n",newImportOrdinal&0x0FFF);
}else
{
DWORD newImageNameAddress = RVAToFileOffset(pFileBuffer,newImportOrdinal);
PIMAGE_IMPORT_BY_NAME pNewImageName = (PIMAGE_IMPORT_BY_NAME)(DWORD(pFileBuffer)+newImageNameAddress);
printf("按名字导入:%x - %s \n",pNewImageName->Hint,pNewImageName->Name);
}
//向下移动
pNewThunkData = (PIMAGE_THUNK_DATA32)((DWORD)pNewThunkData + 4);
newImportOrdinal = pNewThunkData->u1.Ordinal;
}
printf("------------------------------------------\n");
pImportDes = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pImportDes + 20);
getchar();
}
}