您的位置:首页 > 其它

PE资源分析

2007-03-21 11:49 274 查看
PE资源分析_备忘(假设文件以Image形式影射):

1,得到IMAGE_NT_HEADERS
2,得到第一个Section ==>pSection=IMAGE_FIRST_SECTION(pNtHeader);
3,得到.rsrc ==> pResSection++; where pResSection->Name==".rsrc"
4,得到PIMAGE_RESOURCE_DIRECTORY resDir=pNtHeader->OptionalHeader.DataDirectory[2];
5,资源是一个树形结构,resDir是Root,它说明了其下包含是多少个结点数
resDir->NumberOfNameEntries说明"命名项"的个数,
resDir->NumberOfIdEntries说明"标识项"(即由数字ID来标识的)的个数
resDir->NumberOfNameEntries+resDir->NumberOfIdEntries 表示子结点的总数
这些子结点包括在resDir->DirectoryEntries[]数组里(该成员在WINNT.h头的定义中被注释了)
resDir->DirectoryEntries 有类型是 IMAGE_RESOURCE_DIRECTORY_ENTRY
6,得到dirEntry=resDir->DirectoryEntries[0];这是第一个结点,从树的角度来看是第二层(Root为第一层)
第二层结点的dirEntry2->Id标识了资源的类型(也即,资源是按类型分的).
以下是在Winuser.h中定义的资源类型(详见Winuser.h)
/*
* Predefined Resource Types
*/
#define RT_CURSOR MAKEINTRESOURCE(1)
#define RT_BITMAP MAKEINTRESOURCE(2)
#define RT_ICON MAKEINTRESOURCE(3)
#define RT_MENU MAKEINTRESOURCE(4)
#define RT_DIALOG MAKEINTRESOURCE(5)
#define RT_STRING MAKEINTRESOURCE(6)
#define RT_FONTDIR MAKEINTRESOURCE(7)
#define RT_FONT MAKEINTRESOURCE(8)
#define RT_ACCELERATOR MAKEINTRESOURCE(9)
#define RT_RCDATA MAKEINTRESOURCE(10)
#define RT_MESSAGETABLE MAKEINTRESOURCE(11)
7,通过dirEntry->DataIsDirectory标识该结点是不是目录(通常第二层会是目录,即类型目录)
如果是目录,通过通过dirEntry->OffsetToDirectory来得到目录(IMAGE_RESOURCE_DIRECTORY)
PIMAGE_RESOURCE_DIRECTORY resDir2=pBaseAddress+pResSection->VirtualAddress+dirEntry->OffsetToDirectory;
得到dirEntry2=resDir2->DirectoryEntries[0];通过dirEntry2->Id来标识资源类型
8,通常第三层是实际的数据,
PIMAGE_RESOURCE_DIRECTORY resDir3=pBaseAddress+pResSection->VirtualAddress+dirEntry2->OffsetToDirectory;
dirEntry3=resDir3->DirectoryEntries[0];通过dirEntry3->Id来标识资源的ID,
9,得到IMAGE_RESOURCE_DATA_RESOURCE,
PIMAGE_RESOURCE_DATA_RESOURCE dataRes=pBaseAddress+pResSection->VirtualAddress+dirEntry2->OffsetToData;
10,根据类型来判断如果取数据,如是版本信息可以做如下处理:
#define RT_VERSION MAKEINTRESOURCE(16)
typedef struct _VS_VERSIONINFO {
WORD wLength;
WORD wValueLength;
WORD wType;
/*由于是可变结构
WCHAR szKey[];
WORD Padding1[];
VS_FIXEDFILEINFO Value;
WORD Padding2[];
WORD Children[];
*/
}VS_VERSIONINFO,*PVS_VERSIONINFO;//见MSDN文档
//defined in Winver.h
typedef struct _VS_FIXEDFILEINFO {
DWORD dwSignature;
DWORD dwStrucVersion;
DWORD dwFileVersionMS;
DWORD dwFileVersionLS;
DWORD dwProductVersionMS;
DWORD dwProductVersionLS;
DWORD dwFileFlagsMask;
DWORD dwFileFlags;
DWORD dwFileOS;
DWORD dwFileType;
DWORD dwFileSubtype;
DWORD dwFileDateMS;
DWORD dwFileDateLS;
}VS_FIXEDFILEINFO,*PVS_FIXEDFILEINFO;
PVS_VERSIONINFO pVerInfo;
PVS_FIXEDFILEINFO pFixedInfo;
CHAR* pPointer;
ULONG uLen;
WCHAR wChar[MAX_PATH];//注册不要溢出
if( RT_VERSION == dirEntry2->Id ) {
pVerInfo=pBaseAddress+dataRes->OffsetToData;
pPointer=(CHAR*)pVerInfo;
uLen=wcslen(L"VS_VERSION_INFO");
pPointer+=sizeof(VS_VERSIONINFO)+uLen*2+2;//uLen是字符个数据,因为是UNICODE需要*2,再加上结尾UNICODE_NULL
pFixedInfo=(((ULONG)(pPointer)+0x4-1)&~(0x4-1));//对齐32-bit
....
}
如果是字符串,需要以下结构(defined in winnt.h)
IMAGE_RESOURCE_DIRECTORY_STRING和IMAGE_RESOURCE_DIR_STRING_U,计算方法同上;
PIMAGE_RESOURCE_DIR_STRING_U pResStringU;
pResStringU=pBaseAddress+dataRes->OffsetToData;
while(( pBaseAddress+dataRes->OffsetData+dataRes->Size) - (CHAR*)pResStringU != 0 ) {
memcpy(wChar,pResStringU->NameString,pResStringU->Length*2);
wChar[pResStringU->Length]=0;
pResStringU=(CHAR*)pResStringU+pResStringU->Length*2;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: