VOID PrintfResourceTable(){
//定义一个名称数组
static char* szResName[0x11] =
{ 0, "鼠标指针", "位图", "图标", "菜单", "对话框", "字符串列表",
"字体目录", "字体", "快捷键", "非格式化资源", "消息列表",
"鼠标指针组", "zz", "图标组", "xx", "版本信息"
};
//读取文件
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNtHeader = NULL;
PIMAGE_FILE_HEADER pFileHeader = NULL;
PIMAGE_OPTIONAL_HEADER pOptionalHeader = NULL;
PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = NULL;
printf("打印的文件是:%s!\n", INFILEPATH);
//定义文件缓冲区
LPVOID pFileBuffer = NULL;
ReadPEFile(INFILEPATH, &pFileBuffer);
if (pFileBuffer != 0){
printf("文件打开成功!\n");
}
else
{
printf("文件打开失败!\n");
free(pFileBuffer);
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew);
pFileHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNtHeader) + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
pDataDirectory = (PIMAGE_DATA_DIRECTORY)(((DWORD)pOptionalHeader) + 96);
pDataDirectory += 2;
PIMAGE_RESOURCE_DIRECTORY pResourceDirectory = NULL;
DWORD RESRVA = pDataDirectory->VirtualAddress;
DWORD RESFOA = 0;
RESFOA = RVATOFOA(RESRVA, RESFOA, pFileBuffer);
//定位资源目录
pResourceDirectory = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pFileBuffer + RESFOA);
//printf("NumberOfNameEntries:%d,NumberOfIdEntries:%d\n", pResourceDirectory->NumberOfNamedEntries, pResourceDirectory->NumberOfIdEntries);
//获取RESOURCEENTRY 的个数
size_t NumEntry = pResourceDirectory->NumberOfIdEntries + pResourceDirectory->NumberOfNamedEntries;
//资源目录表的宽度
size_t dwResourceData = sizeof(PIMAGE_RESOURCE_DIRECTORY);
//定位资源目录节点
PIMAGE_RESOURCE_DIRECTORY_ENTRY pResEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pResourceDirectory + 16);
//获取第一层
for (size_t i = 0; i < NumEntry; i++)
{
if (!pResEntry[i].NameIsString){//0
if (pResEntry[i].Id < 0x11)
//如果id大于0x11就是自己写的ID资源
{
printf("资源类型ID:%p %s\n", pResEntry[i].Id, szResName[pResEntry[i].Id]);
}
else{
char type[20];
sprintf_s(type, "%d", pResEntry[i].Id);
printf("资源类型ID:%p %s\n", pResEntry[i].Id, type);
}
}
else{//1那么这个第一个联合体的最高位为1,也就是说NameIsString为1,如果资源是未知的,这种资源属于字符串作为资源标识, Name就不会起作用了,NameOffset会指向IMAGE_RESOUCE_DIR_STRING_U的位置
//先获取偏移
PIMAGE_RESOURCE_DIR_STRING_U pStringRes = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pResourceDirectory + pResEntry[i].NameOffset);
//定义一个用来接收自定义字符串的宽数组然后直接复制
WCHAR szStr[MAX_PATH] = { 0 };
memcpy_s(szStr, MAX_PATH, pStringRes->NameString, pStringRes->Length*sizeof(WCHAR));
printf("资源名称:%ls \n", szStr);
}
//第二层
if (pResEntry[i].DataIsDirectory){
printf("第二层目录偏移是:%p\n", pResEntry[i].OffsetToDirectory);
//定义二层目录的目录头 以及entry
PIMAGE_RESOURCE_DIRECTORY pResDirectory2 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResourceDirectory + pResEntry[i].OffsetToDirectory);
PIMAGE_RESOURCE_DIRECTORY_ENTRY pResEntry2 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pResDirectory2 + 1);
//获得ENtry个数
size_t NumEntry2 = pResDirectory2->NumberOfIdEntries + pResDirectory2->NumberOfNamedEntries;
for (DWORD i = 0; i < NumEntry2; i++)
{
if (!pResEntry2[i].NameIsString)
{
printf("->资源标识ID:%d\n", pResEntry2[i].Id);
}
else
{
// 显示资源字符串
// NameOffset为相对资源的文件偏移
// 字符串偏移为 资源基地址+NameOffset
PIMAGE_RESOURCE_DIR_STRING_U pstcString = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pResourceDirectory + pResEntry2[i].NameOffset);
WCHAR szStr[MAX_PATH] = { 0 };
memcpy(szStr,
pstcString->NameString,
pstcString->Length*sizeof(WCHAR)
);
printf("->资源字符串:%ls\n", szStr);
}
}
//第三层
PIMAGE_RESOURCE_DIRECTORY pResourceDirectory3 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResourceDirectory + pResEntry2[i].OffsetToDirectory);
printf("第三层目录:%d\n", pResourceDirectory3->NumberOfIdEntries);
PIMAGE_RESOURCE_DIRECTORY_ENTRY pResEntry3 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pResourceDirectory3 + 1);
if (!pResEntry3[i].DataIsDirectory)
{
// 取数据偏移,显示数据
PIMAGE_RESOURCE_DATA_ENTRY pResData = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD)pResourceDirectory + pResEntry3->OffsetToData);
printf("->->->数据RVA:%x\t数据大小:%x\n", pResData->OffsetToData,pResData->Size);
//printf("->->->数据大小:%x\n", pResData->Size);
//printf("->->->数据RVA:%x\n", pResData->OffsetToData);
}
}
printf("\n\n\n");
}
}