安全中国首页 > 文章中心 > 编释语言
 
安全中国网友投稿专用上传FTP空间:
Ftp服务器:www.anqn.com
Ftp端口:21
用户名:anqn
密 码:anqn.com
 

《加密解密 技术内幕》1.33 JIURL PE 格式学习总结(四)-- PE文件中的资源(图)

更新时间:2008-3-12 0:56:07
责任编辑:阿loosen
热 点:
    程序所用到的各种资源,比如 bmp,cursor,menu,对话框等都存在PE文件中。
    我们将详细介绍关于资源的各种结构,通过一个例子来说明资源及其相关结构是怎么放在PE文件中的。以及如何在遍历PE文件中的所有资源。我们只最终找到这些资源在文件中的位置和长度。而不具体分析某种资源的格式,比如有个BMP的资源,我们不分析BMP格式。

一 找到资源在文件中位置。

    资源都放在PE文件的某个节中,该节的节表项中的PointerToRawData,就是资源节在文件中的位置。

1.1 得到PE Header在文件中的位置。
    通过DOS Header结构的成员e_lfanew,可以确定PE Header的在文件中的位置。

1.2 得到文件中节的数目。
    确定PE Header的在文件中的位置之后,就可以确定PE Header中的成员FileHeader和成员OptionalHeader在文件中的位置。根据 FileHeader 中的 成员NumberOfSections 的值,就可以确定文件中节的数目,也就是节表数组中元素的个数。

1.3 得到节表在文件中的位置。
    PE Header在文件中的位置加上PE Header结构的大小就可以得到节表在文件中的开始位置。PE Header结构的大小可以由Signature的大小加上FileHeader的大小再加上FileHeader中的SizeOfOptionalHeade来确定。其实到目前为止SizeOfOptionalHeade也就是结构Optional Header的大小也是固定的,所以整个PE Header结构的大小也是固定。不过为了安全起见,还是用Signature的大小加上FileHeader的大小再加上FileHeader中的SizeOfOptionalHeade来确定比较保险。

1.4 得到资源节在文件中的位置。
    第1.2步中我们确定了文件中节的数目,第1.3步中我们确定了节表在文件中的位置。
    现在有两种方法来确定资源在文件中的位置。
    第一种方法,根据节的数目,遍历节表数组。也就是从0到(节表数-1)的每一个节表项。
比较每一个节表项的Name字段,看是否等于".rsrc"。如果等于。就找到了资源节的节表项。
这个节表项中的 PointerToRawData 中的值,就是资源节在文件中的位置。
    第二种方法,取得PE Header中的Optional Header中的DataDirectory数组中的第三项,
也就是资源项。DataDirectory[]数组的每项都是IMAGE_DATA_DIRECTORY结构,该结构定义如下。
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
取得DataDirectory数组中的第三项中的成员VirtualAddress的值。这个值就是在内存中资源节的RVA。
然后根据节的数目,遍历节表数组。也就是从0到(节表数-1)的每一个节表项。
每个节在内存中的RVA的范围是从该节表项的成员VirtualAddress字段的值开始(包括这个值),
到VirtualAddress+Misc.VirtualSize的值结束(不包括这个值)。
我们遍历整个节表,看我们取得的资源节的RVA,在哪个节表项的RVA范围之内。
如果在范围之内,就找到了资源节的节表项。
这个节表项中的 PointerToRawData 中的值,就是资源节在文件中的位置。
如果这个PE文件没有资源的话,DataDirectory数组中的第三项内容为0。

这样我们就得到了资源在文件中开始的位置。

二 PE文件中的资源。

    我们已经得到了资源节在文件中的位置。
资源节最开始是一个IMAGE_RESOURCE_DIRECTORY结构。
在WINNT.H中定义如下。

typedef struct _IMAGE_RESOURCE_DIRECTORY {
DWORD Characteristics;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
WORD NumberOfNamedEntries;
WORD NumberOfIdEntries;
// IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];
} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;
这个结构长度为16字节,共有6个字段。
各字段含义如下:
Characteristics: Resource flags,保留用于以后使用,目前都为0。
TimeDateStamp:资源编译器产生资源的时间。
MajorVersion:
MinorVersion:
NumberOfNamedEntries:用字符串来标示IMAGE_RESOURCE_DIRECTORY_ENTRY项的,紧跟着本结构的IMAGE_RESOURCE_DIRECTORY_ENTRY数组的成员个数。
Number of ID Entries:用整形数字来表示IMAGE_RESOURCE_DIRECTORY_ENTRY项的,紧跟着本结构的IMAGE_RESOURCE_DIRECTORY_ENTRY数组的成员个数。

    IMAGE_RESOURCE_DIRECTORY后面一定会紧跟着一个IMAGE_RESOURCE_DIRECTORY_ENTRY数组。
IMAGE_RESOURCE_DIRECTORY_ENTRY结构定义如下。

typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {
union {
struct {
DWORD NameOffset:31;
DWORD NameIsString:1;
};
DWORD Name;
WORD Id;
};
union {
DWORD OffsetToData;
struct {
DWORD OffsetToDirectory:31;
DWORD DataIsDirectory:1;
};
};
} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;

1 2 3 4 下一页

 
相关文章
一日一文章
 
一日一软件
一日一动画