PE 文件格之资源,是一个三级结构。
代码先放上:
#include "stdio.h"
#include "windows.h"
void GetDataAnd(DWORD RVA,int size,int type)//解析特定类型,自己添加
{
}
BOOL GetResour(DWORD nResoure,DWORD npose,DWORD nrfile,HANDLE file,int nType = -1)//nResoure 资源add npose 偏移 nrfile 段偏移
{
IMAGE_RESOURCE_DIRECTORY nmain={0};
DWORD backdatenum;
SetFilePointer(file,nResoure+npose,NULL,FILE_BEGIN);
ReadFile(file,&nmain,sizeof(nmain),&backdatenum,0);//读取一个
DWORD nmainnum=nResoure+sizeof(nmain)+npose;
IMAGE_RESOURCE_DIRECTORY_ENTRY sundate={0};
for (int i=0;i<nmain.NumberOfIdEntries+nmain.NumberOfNamedEntries;++i,nmainnum+=sizeof(sundate))
{
SetFilePointer(file,nmainnum,NULL,FILE_BEGIN);
ReadFile(file,&sundate,sizeof(sundate),&backdatenum,NULL);
if((sundate.OffsetToData&0x80000000)!=0)//最高位,如果是1,那就到第三层了
{
char ittoname[30]={0};
if((sundate.Name&0x80000000)!=0)//最高位,如果是2,那就是一个自定义的类型,非系统的类型
{
//m_DrivesRoot=m_resourcetree.InsertItem("date", 0, 1,treepoint);
printf("Date\n");
}
else
{
switch(sundate.Id)
{
case 1:
strcpy(ittoname,"光标");
break;
case 2:
strcpy(ittoname,"位图");
break;
case 3:
strcpy(ittoname,"图标");
break;
case 4:
strcpy(ittoname,"菜单");
break;
case 5:
strcpy(ittoname,"对话框");
break;
case 6:
strcpy(ittoname,"字符串");
break;
case 7:
strcpy(ittoname,"字体目录");
break;
case 8:
strcpy(ittoname,"字体");
break;
case 9:
strcpy(ittoname,"加速键");
break;
case 10:
strcpy(ittoname,"未格式化资源");
break;
case 11:
strcpy(ittoname,"消息表");
break;
case 12:
strcpy(ittoname,"光标组");
break;
case 13:
strcpy(ittoname,"未知");
break;
case 14:
strcpy(ittoname,"图标组");
break;
case 15:
strcpy(ittoname,"未知");
break;
case 16:
strcpy(ittoname,"版本信息");
break;
default:
strcpy(ittoname,"其它");
break;
}
if(nType<0)
{
printf("%s\n",ittoname);//第一层
GetResour(nResoure,sundate.OffsetToData&0x7fffffff,nrfile,file,sundate.Id);
}
else
{
printf("%d\n",sundate.Id);//第二层
GetResour(nResoure,sundate.OffsetToData&0x7fffffff,nrfile,file,nType);
}
}
//去掉最高位
}
else//第三层
{
IMAGE_RESOURCE_DATA_ENTRY rdata={0};
SetFilePointer(file,sundate.OffsetToData+nResoure,NULL,FILE_BEGIN);
ReadFile(file,&rdata,sizeof(rdata),&backdatenum,NULL);
//p->id=atoi(m_resourcetree.GetItemText(treepoint));
int RVA=rdata.OffsetToData-nrfile;
int size=rdata.Size;
printf(" RVA :%08x Size:%d (文件位置:%08x)\n",RVA,size,RVA-nrfile);
GetDataAnd(RVA,size,nType);//针对性,对某个类型进行解析
}
}
return TRUE;
}
BOOL GetPEHeadFromFile(char *filePath,PIMAGE_DOS_HEADER nhead,PIMAGE_NT_HEADERS npe,PIMAGE_SECTION_HEADER *nSection)
{
HANDLE file=INVALID_HANDLE_VALUE;
try
{
file=CreateFile(filePath,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_READONLY,0);//打开文件
if(file==INVALID_HANDLE_VALUE ) return FALSE;//如果错误
DWORD backdatenum;
ReadFile(file,nhead,sizeof(IMAGE_DOS_HEADER),&backdatenum,0);
if(memcmp(&nhead->e_magic,"MZ",2)!=0) throw (1);//判断DOS魔术字
SetFilePointer(file,nhead->e_lfanew,0,FILE_BEGIN);
ReadFile(file,npe,sizeof(IMAGE_NT_HEADERS),&backdatenum,0);
if(npe->Signature != 0x00004550) throw (2);
*nSection = new IMAGE_SECTION_HEADER[npe->FileHeader.NumberOfSections];
PIMAGE_SECTION_HEADER Section = *nSection;
for (int i = 0 ; i < npe->FileHeader.NumberOfSections ; ++i)
{
ReadFile(file,&Section[i],sizeof(Section[i]),&backdatenum,0);
if(backdatenum!=sizeof(Section[i])) throw(3);
printf("节点名:%s\n",Section[i].Name);
printf(" 虚拟偏移:%08X\n",Section[i].VirtualAddress);
printf(" 虚拟大小:%08X\n",Section[i].Misc.VirtualSize);
printf(" 实际偏移:%08X\n",Section[i].PointerToRawData);
printf(" 实际大小:%08X\n",Section[i].SizeOfRawData);
printf(" 文件特征:%08X\n",Section[i].Characteristics);
}
//printf("%x %x %d %d",IMAGE_Import.VirtualAddress,IMAGE_Export.VirtualAddress,IMAGE_Import_ID,IMAGE_Export_ID);
CloseHandle(file);
}
catch (...)
{
printf("不是有效的PE");
CloseHandle(file);
return FALSE;
}
return TRUE;
}
BOOL DirInSecton(PIMAGE_DATA_DIRECTORY ndir,PIMAGE_SECTION_HEADER nsection)
{
if(ndir->VirtualAddress>=nsection->VirtualAddress&&ndir->VirtualAddress<=nsection->VirtualAddress+nsection->Misc.VirtualSize)
{
return TRUE;
}
return FALSE;
}
void AnyResourcesFromFile(PIMAGE_SECTION_HEADER Section,PIMAGE_NT_HEADERS npe,char *filePath)
{
IMAGE_DATA_DIRECTORY* IMAGE_Resources = &npe->OptionalHeader.DataDirectory[2];//资源在2号
int IMAGE_Resources_ID = -1;
for (int i = 0 ; i < npe->FileHeader.NumberOfSections ; ++i)
{
if(DirInSecton(IMAGE_Resources,Section+i))
{
IMAGE_Resources_ID = i;
break;
}
}
if(IMAGE_Resources_ID>=0)
{
int n_Resoure_file=Section[IMAGE_Resources_ID].VirtualAddress-Section[IMAGE_Resources_ID].PointerToRawData;
int n_Resoure=IMAGE_Resources->VirtualAddress-n_Resoure_file;
HANDLE file=INVALID_HANDLE_VALUE;
file=CreateFile(filePath,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_READONLY,0);
if(file==INVALID_HANDLE_VALUE ) return ;
GetResour(n_Resoure,0,n_Resoure_file,file,-1);//分析资源,最后一个参数必须为小于0,为处理方便
}
}
int main(int argc, char* argv[])
{
printf("Hello World!\n");
IMAGE_DOS_HEADER head;
IMAGE_NT_HEADERS pe;
PIMAGE_SECTION_HEADER Section;
char file[] = "C:\\windows\\notepad.exe";
if(GetPEHeadFromFile(file,&head,&pe,&Section))
{
AnyResourcesFromFile(Section,&pe,file);
}
return 0;
}
这三层模式。类似
A代表:IMAGE_RESOURCE_DIRECTORY
B代表:IMAGE_RESOURCE_DIRECTORY_ENTRY
A 指向多个B
B又指向一个A。
B中有结束标志。
如果 想从那些资源数据中保存可详见资源:http://download.csdn.net/download/he702477275/4972957