打印PE导入表信息

导入表有些复杂,文件与内存中的格式不太一样

理解导入表的结构是关键


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();
	}
	
	
	
}

原文链接: 打印PE导入表信息 版权所有,转载时请注明出处,违者必究。
注明出处格式:流沙团 ( https://gyarmy.com/post-314.html )

发表评论

0则评论给“打印PE导入表信息”