看完视频想自己动手实践一下看看QQ.exe的PE格式
2012版的qq中protect版本和本来的版本是有大的不一样的。这里从两个exe文件大小的不同就可以看出来了。这里就先分析一下普通的qq.exe文件好了。
首先用Resource Hacker工具查看一下资源文件,发现在图标这一栏里面有8只大小不一样的企鹅。。。。。。
我这里第4只好像特别大。。。。这里就先分析下第1只企鹅的图标资源吧。。。。
关于资源表这里就不特别讲解了,大家可以参考一下小甲鱼的课件,讲的很清楚的哦。
http://www.fishc.com/a/shipin/jiemixilie/_PExilie_/1051.html
这里就把课件里面的一张最重要的图片贴出来吧:
然后自己就跟着这张图片还有小甲鱼的讲解自己也演练了一遍:
/*
qq.exe resource analyse
by Miibotree
*/
//块对齐和文件对齐都是1000H 所以这里的RVA和offset是一样的,方便了计算
//资源表的RVA是1A000 大小是10790
//第四个区块.rsrc的起始地址是1A000 大小是10790 说明这个区块里面存的全部都是资源
//然后用WinHex打开qq.exe正式来分析一下
//第一层目录 资源类型
typedef struct _IMAGE_RESOURCE_DIRECTORY {
DWORD Characteristics; 00 00 00 00H
DWORD TimeDateStamp; 00 00 00 00H
WORD MajorVersion; 00 04H
WORD MinorVersion; 00 00H
WORD NumberOfNamedEntries; 00 00H
WORD NumberOfIdEntries; 00 04H//这里说明有4种资源类型
// IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];
} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;
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;
// name OffsetToData
//一。1 0000 0003H 8000 0030H 图标 8(十六进制) = 1000(二进制)最高位为1,低31位作为指针使用
//一。2 0000 000EH 8000 0080H 版本信息
//一。3 0000 0010H 8000 0098H qq自定义的
//一。4 0000 0018H 8000 00B0H 应该也是qq自定义的
//一。5 0000 0000H 0000 0000H 最后一个全部都是0表示结束了吧
//第一层结束,我们首先追踪一下qq图标吧,所以先飞到第二层去了,哈哈
//第二层目录 资源ID
//一.1.二
typedef struct _IMAGE_RESOURCE_DIRECTORY {
DWORD Characteristics; 00 00 00 00H
DWORD TimeDateStamp; 00 00 00 00H
WORD MajorVersion; 00 04H
WORD MinorVersion; 00 00H
WORD NumberOfNamedEntries; 00 00H
WORD NumberOfIdEntries; 00 08H//这里说明有8个图标
// IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];
} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;
//一。1.二。1-8
// name OffsetToData
// 0000 0001H 8000 00C8H
// 0000 0002H 8000 00E0H
// 0000 0003H 8000 00F8H
// 0000 0004H 8000 0110H
// 0000 0005H 8000 0128H
// 0000 0006H 8000 0140H
// 0000 0007H 8000 0158H
// 0000 0008H 8000 0170H
// 0000 0000H 0000 0000H
//第二层结束,飞到第三层去吧,呵呵呵呵
//第三层目录 资源代码页
//一。1.二。1。三
typedef struct _IMAGE_RESOURCE_DIRECTORY {
DWORD Characteristics; 00 00 00 00H
DWORD TimeDateStamp; 00 00 00 00H
WORD MajorVersion; 00 04H
WORD MinorVersion; 00 00H
WORD NumberOfNamedEntries; 00 00H
WORD NumberOfIdEntries; 00 01H//这里说明只有一个资源代码页
// IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];
} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;
//一。1.二。1。三。1
// name OffsetToData
// 0000 0409H 0000 01D0H
// 0000 0000H 0000 0000H
//第三层结束,离我们的最终胜利越来越近了,加油啊啊啊啊啊
//节点 资源数据指针
//一。1.二。1。三。1。四
IMAGE_RESOURCE_DATA_ENTRY STRUCT
OffsetToData DWORD ? ; 资源数据的RVA 00 01 A2 80H
Size DWORD ? ; 资源数据的长度 00 00 01 28H
CodePage DWORD ? ; 代码页, 一般为0 00 00 04 E0H
Reserved DWORD ? ; 保留字段 00 00 00 00H
IMAGE_RESOURCE_DATA_ENTRY ENDS
//节点 资源数据指针结束,现在终于可以进入我们的最终小企鹅图标的庐山真面目了。。。
//图标资源
//1A280 - 1A3A8
最后得到了图标资源的位置。用eXeScope打开看一下,发现是一样的。呵呵,简单就分析到这里了。