PE 资源表

唯一坑点:在找IMAGE_RESOURCE_DIRECTORY或者是IMAGE_RESOURCE_DATA_ENTRY,用OffsetToDirectory加的永远是以第一个IMAGE_RESOURCE_DIRECTORY来作为基址,也就是如下所示:

实现代码如下:

void PrintResourceTable(PVOID pFileBuffer){
	PIMAGE_DOS_HEADER pImageDosHeader = NULL;
	PIMAGE_FILE_HEADER pImageFileHeader = NULL;
	PIMAGE_OPTIONAL_HEADER32 pImageOptionalHeader = NULL;
	PIMAGE_SECTION_HEADER pImageSectionHeaderGroup = NULL;
	PIMAGE_SECTION_HEADER NewSec = NULL;

	PIMAGE_RESOURCE_DIRECTORY pImageResourceDireOne = NULL;
	PIMAGE_RESOURCE_DIRECTORY_ENTRY pImageResourceEntryOne = NULL;

	PIMAGE_RESOURCE_DIRECTORY pImageResourceDireTwo = NULL;
	PIMAGE_RESOURCE_DIRECTORY_ENTRY pImageResourceEntryTwo = NULL;

	
	PIMAGE_RESOURCE_DIRECTORY pImageResourceDireThree = NULL;
	PIMAGE_RESOURCE_DIRECTORY_ENTRY pImageResourceEntryThree = NULL;

	PIMAGE_DATA_DIRECTORY pImageDataDire = NULL;
	PIMAGE_RESOURCE_DIR_STRING_U pDirString = NULL;

	DWORD RVA = 0;
	DWORD FOA = 0;
	DWORD dwEntryNumOne = 0;
	DWORD dwEntryNumTwo = 0;
	DWORD dwEntryNumThree = 0;

	DWORD i=0;
	DWORD j=0;
	DWORD k=0;
	DWORD m=0;

	pImageDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
	pImageFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pImageDosHeader + pImageDosHeader->e_lfanew + 4);
	pImageOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pImageFileHeader + sizeof(IMAGE_FILE_HEADER));
	pImageSectionHeaderGroup = (PIMAGE_SECTION_HEADER)((DWORD)pImageOptionalHeader + pImageFileHeader->SizeOfOptionalHeader);
	
	RVA_TO_FOA(pFileBuffer,pImageOptionalHeader->DataDirectory[2].VirtualAddress,&FOA);
	/*
	
	  typedef struct _IMAGE_RESOURCE_DIRECTORY {								
	  DWORD   Characteristics;						//资源属性  保留 0		
	  DWORD   TimeDateStamp;						//资源创建的时间		
	  WORD    MajorVersion;						//资源版本号 未使用 0		
	  WORD    MinorVersion;						//资源版本号 未使用 0		
	  WORD    NumberOfNamedEntries;						//以名称命名的资源数量		
	  WORD    NumberOfIdEntries;						//以ID命名的资源数量		
	  //  IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];								
	  } IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;								
	*/

	pImageResourceDireOne = (DWORD)pFileBuffer + (DWORD)FOA;
	dwEntryNumOne = pImageResourceDireOne->NumberOfIdEntries + pImageResourceDireOne->NumberOfNamedEntries;
	pImageResourceEntryOne = (DWORD)pImageResourceDireOne + 16;
	for(i=0;i<dwEntryNumOne;i++){
		if(pImageResourceEntryOne[i].NameIsString == 1){ // 1
			pDirString = (PIMAGE_RESOURCE_DIR_STRING_U)pImageResourceEntryOne[i].NameOffset;
			wprintf(L"第一层资源类型: %s
", pDirString->NameString); // 第一层资源类型
		}else{ //0 
			printf("第一层资源类型: %d
",pImageResourceEntryOne[i].NameOffset); // 第一层资源类型
		}
		//======================pImageResourceDireTwo=========================
		pImageResourceDireTwo = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pImageResourceDireOne + (DWORD)pImageResourceEntryOne[i].OffsetToDirectory);
		dwEntryNumTwo = pImageResourceDireTwo->NumberOfIdEntries + pImageResourceDireTwo->NumberOfNamedEntries;
		pImageResourceEntryTwo = (DWORD)pImageResourceDireTwo + 16;
		for(j=0;j<dwEntryNumTwo;j++){
			if(pImageResourceEntryTwo[j].NameIsString == 1){ // 1
				pDirString = (PIMAGE_RESOURCE_DIR_STRING_U)pImageResourceEntryTwo[j].NameOffset;
				wprintf(L"	第二层资源名称: %s
", pDirString->NameString); // 第二层资源名称
			}else{ //0 
				printf("	第二层资源名称: %d
",pImageResourceEntryTwo[j].NameOffset); // 第二层资源名称
			}

			//======================pImageResourceDireThree=========================
			pImageResourceDireThree = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pImageResourceDireOne + (DWORD)pImageResourceEntryTwo[j].OffsetToDirectory);
			dwEntryNumThree = pImageResourceDireThree->NumberOfIdEntries + pImageResourceDireThree->NumberOfNamedEntries;
			pImageResourceEntryThree = (DWORD)pImageResourceDireThree + 16;
			for(k=0;k<dwEntryNumThree;k++){
				if(pImageResourceEntryThree[k].NameIsString == 1){ // 1
					pDirString = (PIMAGE_RESOURCE_DIR_STRING_U)pImageResourceEntryThree[k].NameOffset;
					wprintf(L"		第三层代码页编号: %s
", pDirString->NameString); // 第三层代码页编号
				}else{ //0 
					printf("		第三层代码页编号: %d
",pImageResourceEntryThree[k].NameOffset); // 第三层代码页编号
				}

				//======================IMAGE_RESOURCE_DATA_ENTRY=========================
				//pImageDataDire IMAGE_RESOURCE_DATA_ENTRY
				pImageDataDire = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD)pImageResourceDireOne + (DWORD)pImageResourceEntryThree[k].OffsetToDirectory);
				printf("			 VirtualAddress: 0x%X, Size: 0x%X
", pImageDataDire->VirtualAddress, pImageDataDire->Size);
			}
		}
		printf("==================================
");
	}
}

原文地址:https://www.cnblogs.com/zpchcbd/p/14687686.html