唯一坑点:在找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\n", pDirString->NameString); // 第一层资源类型
}else{ //0
printf("第一层资源类型: %d\n",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"\t第二层资源名称: %s\n", pDirString->NameString); // 第二层资源名称
}else{ //0
printf("\t第二层资源名称: %d\n",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"\t\t第三层代码页编号: %s\n", pDirString->NameString); // 第三层代码页编号
}else{ //0
printf("\t\t第三层代码页编号: %d\n",pImageResourceEntryThree[k].NameOffset); // 第三层代码页编号
}
//======================IMAGE_RESOURCE_DATA_ENTRY=========================
//pImageDataDire IMAGE_RESOURCE_DATA_ENTRY
pImageDataDire = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD)pImageResourceDireOne + (DWORD)pImageResourceEntryThree[k].OffsetToDirectory);
printf("\t\t\t VirtualAddress: 0x%X, Size: 0x%X\n", pImageDataDire->VirtualAddress, pImageDataDire->Size);
}
}
printf("==================================\n");
}
}
原文:https://www.cnblogs.com/zpchcbd/p/14687686.html