PE资源分析

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;
  }

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值