本来该用递归来写的,奈何总是写不出来,所以写了一个遍历3层结构的程序。以后来写递归的
VOID _GetResourceInfo1(PVOID pFileBuffer)
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNtHeaders = NULL;
PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDirEntry1=NULL;
PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDirEntry2=NULL;
PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDirEntry3=NULL;
PIMAGE_RESOURCE_DIRECTORY pResDir1=NULL;
PIMAGE_RESOURCE_DIRECTORY pResDir2=NULL;
PIMAGE_RESOURCE_DIRECTORY pResDir3=NULL;
PIMAGE_RESOURCE_DIR_STRING_U pUStr=NULL;
PIMAGE_RESOURCE_DATA_ENTRY pResDataEntry=NULL;
DWORD dwUncodeAddr=0;
BYTE szBuffer[1024]={0};
BYTE szResName[256]={0};
DWORD dwResourceAddr=0;
DWORD dwSize,dwSize2,dwSize3;
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
{
printf("not a mz header!\n");
return ;
}
pNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
if (pNtHeaders->Signature != IMAGE_NT_SIGNATURE)
{
printf("not a PE header!\n");
return ;
}
//资源表在文件中的偏移
dwResourceAddr=(DWORD)pFileBuffer+_RVAToOffset(pFileBuffer,pNtHeaders->OptionalHeader.DataDirectory[2].VirtualAddress);
//第一层
pResDir1=(PIMAGE_RESOURCE_DIRECTORY)dwResourceAddr;
pResDirEntry1=(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pResDir1+sizeof(IMAGE_RESOURCE_DIRECTORY));
dwSize=pResDir1->NumberOfIdEntries+pResDir1->NumberOfNamedEntries;
for(int i=0;i<dwSize;i++)
{
//第一层的name
if(pResDirEntry1->NameIsString)
{
//用户自定义的资源类别
pUStr=(PIMAGE_RESOURCE_DIR_STRING_U)(dwResourceAddr+pResDirEntry1->NameOffset);
//跳过两字节,就是存储的名字地址。详见IMAGE_RESOURCE_DIR_STRING_U结构
dwUncodeAddr=(DWORD)pUStr+2;
//将UNICODE字符转换成多字节字符
memset(szResName,0,sizeof(szResName));
WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,(LPCWSTR)dwUncodeAddr,pUStr->Length,(char *)szResName,sizeof(szResName),NULL,NULL);
printf("类型:%s\n",szResName);
printf("-----------------------------------------\n");
}
else
{
//系统内定义的资源编号
switch(pResDirEntry1->Id)
{
case 1: printf("类型:光标\n");break;
case 2: printf("类型:位图\n");break;
case 3: printf("类型:图标\n");break;
case 4: printf("类型:菜单\n");break;
case 5: printf("类型:对话框\n");break;
case 6: printf("类型:字符串\n");break;
case 7: printf("类型:字体目录\n");break;
case 8: printf("类型:字体\n");break;
case 9: printf("类型:加速键\n");break;
case 0x0a: printf("类型:未格式化资源\n");break;
case 0x0b: printf("类型:消息表\n");break;
case 0x0c: printf("类型:光标组\n");break;
case 0x0d: printf("类型:图标组\n");break;
case 0x0e: printf("类型:版本信息\n");break;
default:
printf("类型: %x\n",pResDirEntry1->Id);
break;
}
printf("--------------------------------------------\n");
}
//第一层的offset //指向dir_entry
if(pResDirEntry1->DataIsDirectory)
{
//第二层的结构
pResDir2=(PIMAGE_RESOURCE_DIRECTORY)(dwResourceAddr+pResDirEntry1->OffsetToDirectory);
pResDirEntry2=(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pResDir2+sizeof(IMAGE_RESOURCE_DIRECTORY));
dwSize2=pResDir2->NumberOfIdEntries+pResDir2->NumberOfNamedEntries;
for(int j=0;j<dwSize2;j++)
{
//name 如果以字符作为ID
if(pResDirEntry2->NameIsString)
{
pUStr=(PIMAGE_RESOURCE_DIR_STRING_U)(dwResourceAddr+pResDirEntry2->NameOffset);
dwUncodeAddr=(DWORD)pUStr+2;
memset(szResName,0,sizeof(szResName));
WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,(LPCWSTR)dwUncodeAddr,pUStr->Length,(char *)szResName,sizeof(szResName),NULL,NULL);
printf("ID:%s\n",szResName);
}
else
{
printf("ID: %d\n",pResDirEntry2->Id);
}
//offset项
if(pResDirEntry2->DataIsDirectory)
{
//第三层的结构
pResDir3=(PIMAGE_RESOURCE_DIRECTORY)(dwResourceAddr+pResDirEntry2->OffsetToDirectory);
pResDirEntry3=(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pResDir3+sizeof(IMAGE_RESOURCE_DIRECTORY));
dwSize3=pResDir3->NumberOfIdEntries+pResDir3->NumberOfNamedEntries;
for(int k=0;k<dwSize3;k++)
{
//name指向的是代码页的编号,一般都为2056简体中文。这里省略
//offset
if(pResDirEntry3->DataIsDirectory==0)
{
pResDataEntry=(PIMAGE_RESOURCE_DATA_ENTRY)(dwResourceAddr+pResDirEntry3->OffsetToDirectory);
printf("偏移:0x%x 大小:0x%x\n",pResDataEntry->OffsetToData,pResDataEntry->Size);
}
else
{
}
pResDirEntry3++;
}
}
pResDirEntry2++;
}
}
else
{
//第一层一般都是等于1的
}
pResDirEntry1++;
}
}