PE 文件格式启发式学习Word下载.docx

上传人:b****4 文档编号:18391666 上传时间:2022-12-16 格式:DOCX 页数:13 大小:28.63KB
下载 相关 举报
PE 文件格式启发式学习Word下载.docx_第1页
第1页 / 共13页
PE 文件格式启发式学习Word下载.docx_第2页
第2页 / 共13页
PE 文件格式启发式学习Word下载.docx_第3页
第3页 / 共13页
PE 文件格式启发式学习Word下载.docx_第4页
第4页 / 共13页
PE 文件格式启发式学习Word下载.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

PE 文件格式启发式学习Word下载.docx

《PE 文件格式启发式学习Word下载.docx》由会员分享,可在线阅读,更多相关《PE 文件格式启发式学习Word下载.docx(13页珍藏版)》请在冰豆网上搜索。

PE 文件格式启发式学习Word下载.docx

CheckSum;

Subsystem;

DllCharacteristics;

SizeOfStackReserve;

SizeOfStackCommit;

SizeOfHeapReserve;

SizeOfHeapCommit;

LoaderFlags;

z

NumberOfRvaAndSizes;

IMAGE_DATA_DIRECTORY 

DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];

IMAGE_OPTIONAL_HEADER32, 

*PIMAGE_OPTIONAL_HEADER32;

1.3

慢点,别一下子贴那么多东西,我还没有找到 

的位置呢,

告诉我怎样找

贴上那个_IMAGE_OPTIONAL_HEADER结构好说话,它的位置紧跟在 

MAGE_FILE_HEADER 

之后

告诉你个小技巧,那个Magic对NT 

x86来讲总是010B,在头文件找到那个010b,就是IMAGE_OPTIONAL_HEADER32 

结构的地址。

1.4

问题越来越多了。

还没有说清呢,又出来一个IMAGE_FILE_HEADER。

先不管IMAGE_FILE_HEADER

先按你的小技巧,在头部找到010b, 

因为是little 

endial, 

在ultraedit 

中要找0b 

01.

好,找到了,离那个 

50 

45 

00 

(ascii 

PE)相距不远,在偏移D8处,按你所说SectionAlignment和FileAlignment 

应该在结构第9个,第10个DWORD 

处。

好,找到了,在f8处有00001000, 

FC处为00 

02 

(我已经考虑了endian,以后不用提醒了)。

呀,进步不小吗?

这样一下子你就把IMAGE_OPTIONAL_HEADER32 

中所有的东西都找出来了。

1.5

是的,我可以把Optional 

header中所有东西都找出来,但我现在除了刚才介绍的第9个DWORD为内存对齐大小,第10个DWORD为文件对齐大小,其它我都不知道是干什么的?

别着急,其实还是很容易理解的,从字面意义就能猜大概。

不过我们现在还不是通读Optional 

header的时候,还是拣我们最关心的问题插手吧。

1.6 

还是回到text 

段上来吧,刚才你对text段大小,位置,属性分析的头头是到

你是从那看出来的?

1.6

是从section 

中看出来的,每一个section, 

都有一个section 

描述其位置,大小,属性。

section 

的结构是这样定义的

#define 

IMAGE_SIZEOF_SHORT_NAME 

8

_IMAGE_SECTION_HEADER 

Name[IMAGE_SIZEOF_SHORT_NAME];

union 

PhysicalAddress;

VirtualSize;

Misc;

VirtualAddress;

SizeOfRawData;

PointerToRawData;

PointerToRelocations;

PointerToLinenumbers;

NumberOfRelocations;

NumberOfLinenumbers;

Characteristics;

IMAGE_SECTION_HEADER, 

*PIMAGE_SECTION_HEADER;

1.7

呦,慢点,怎么又往外甩结构,我很菜!

哦,不太多,还行吧。

不过你还是告诉我具体位置在哪吧,我好拿结构和数据对对号。

好,正是这种学习方法。

你一定能学会的。

节表头是一个数组,它把所有节的位置,长度,属性放在了一起

紧跟在option 

之后,所以你从文件头部往下找就可以了。

看到IMAGE_SECTION_HEADER结构的第一个成员了吗,它是

Name【8】

这是节名称,你要找的text 

段名字就是 

.text, 

你看ultraedit

ascii 

码区离文件开始不远的地方,有一个.text, 

对应的二进制

数据是2E 

74 

65 

78 

74, 

这就是text 

端IMAGE_SECTION_HEADER处

1.8

原来玄机在这里呀。

我试试看。

哦,看见了,在1B8处。

前8个

字节是节名称。

后面的00 

28 

到底是物理地址还是虚拟大小,

(偷偷的,虚拟大小,表示内存中只有0x28个字节有效,其它全是0),在后面00 

10 

是虚拟相对地址 

俗称RVA, 

就是在内存中相对与起始地址的偏移。

再后面00 

为SizeOfRawData, 

就是文件中大小,再后面 

04 

PointerToRawData,是文件的偏移 

后面有三个DWORD 

全是0,他们

是重定位信息和行号,很好,EXE文件可以不用管这些。

最后一个

60 

20 

代表属性可读,可写,是代码。

好,我终于理解你的第一句话了。

不解释一下,我怎么能一下子听的懂呢!

谢谢你。

那么我又有问题了。

那程序针真是搜索这个.text字符串找到Text 

节表头吗?

不是。

前面说过,节表头紧随Optional 

之后。

1.9

结构变量太多,我数了一下都没数清,到底占多少个字节呢?

正等着你这一问呢?

是啊,数都数不清,纵是现在记住了将来也容易忘。

估计微软也想到了这一点,他把OPTION 

的大小放到了 

_IMAGE_FILE_HEADER 

的一个变量中,

下面是_IMAGE_FILE_HEADER 

的定义

Machine;

NumberOfSections;

TimeDateStamp;

PointerToSymbolTable;

NumberOfSymbols;

SizeOfOptionalHeader;

IMAGE_FILE_HEADER, 

*PIMAGE_FILE_HEADER;

SizeOfOptionalHeader 

一般总是0xE0

1.10

我今天已经学了不少东西了,看样子后面还很多的样子。

再问最后一个问题。

FILE_HEADER 

在文件什么位置呢。

这个简单,就在PE标识符后面。

看到了吗,在C0处,ascii 

是PE. 

二进制是50 

00

代学生:

哦,看到了,今天10个问题已经满了,我还想学,可是有点累了。

代老师:

今天就到这里吧,好好休息一下。

接问题1.10后的第11个问题

2.11

干脆就把位置问题先问到底吧。

PE标识符 

54 

总是在文件偏移00c0 

处吗。

基本上可以这么说,主要是因为前面的部分是dos 

头部和dos 

dos 

头部 

IMAGE_DOS_HEADER 

的结构我就不贴了,因为dos 

已经离我们远去,它

已经失掉了意义,dos 

体也几乎是固定不变的了。

这部分的作用是当你拿这个

PE程序到dos 

系统上运行时,dos 

执行会在控制台上打印一行提示信息,

"

this 

program 

cannot 

be 

run 

in 

DOS 

mode"

然后停在哪。

总比你一运行,DOS

就hang 

机强多了。

如果拿PE代码在DOS 

下直接执行,不用说那肯定hang 

机。

微软就是怕这个事情发生才用了这么一个措施。

现在你只需要记住一件事,文件头两个字母是MZ标记,在3c偏移地址,00 

c0

指的是NT 

的文件偏移,如果这个偏移处的标识正好是PE. 

可以肯定,这个文件

就是PE 

文件了。

如果在3c偏移地址处存其它DWORD 

地址,那就到所指定的地址去找

如果该处正好ASCII 

PE"

此处就是NT的header 

2.12

怎么有这么多header, 

能否概要总结一下:

好的。

在文件开头部分是 

_IMAGE_DOS_HEADER 

,小名MZ 

header, 

我们已经不用关心它了。

只要关心地址偏移0x3c 

处,该处存有 

_IMAGE_NT_HEADER 

的偏移。

在dos 

之间是dos 

体,我们也不用关心它了。

到底是什么样呢?

它实际是PE00标识+ 

NT_FILE_HEADER+NT_OPTION_HEADER

以下是它的结构声明。

_IMAGE_NT_HEADERS 

Signature;

//这里的标记是 

PE00

IMAGE_FILE_HEADER 

FileHeader;

//NT 

包含FILE 

和Option 

header

IMAGE_OPTIONAL_HEADER32 

OptionalHeader;

IMAGE_NT_HEADERS32, 

*PIMAGE_NT_HEADERS32;

2.13

这样对header有了一个总体认识,它占据着文件开始部分。

反正它是死的,而且每个文件只有

一个,有上面各个header 

的结构定义,无非是存储这一些数据,指针。

估计详细分析一下,

它也跑不了了。

我们还是抓主要的,主要的分析清了,可能顺便就把头中的相关结构变量分析了。

还是回到节表上来。

上次已经找到了节表头,前面说是在OptionalHeader下面,现在也可以

说是在NT 

header下面。

其中以.text 

居首,根据节表头结构,从.text 

偏移一个节表结构,

我们看到了第二个ascii 

字符 

“.rdata"

 

不远的地方还要一个”.data"

正好也偏移一个节表头结构“,

还有一个"

.rsrc"

再往后就是全0了,那么这是否是说,这个结构数组含有4个结构元素呢?

正是如此,在_IMAGE_FILE_HEADER 

中有一项定义了该数值 

//x86 

的machine代码是 

01 

4c 

(hello.exe 

中00c4处)

hello.exe 

中 

是 

04

与你数的完全一致。

对照一下问题1.9的_IMAGE_FILE_HEADER 

和 

的,你会很容易辨别的。

2.14

我对照过了,知道了它在文件中的位置。

干脆把NT 

FILE 

Header结构中的其他数据也分析一下吧。

反正也不多。

好,我再把该结构抄过来:

//答2.12已经说了,x86 

总是01 

4c

//hello.exe 

是00 

//时戳。

表示你的文件是何时生成的。

不过这个DWORD是用秒数表示的。

//调试信息,hello 

中为全0

//答1.9已经说了,OptionalHeader 

大小总是0xe0

是010F, 

看标志有5个bit 

是1,那就是说5个属性为真了。

FileHeader其它项都好理解,没有什么关键的东西,只有这个属性稍微麻烦一点,最多也不超过16个属性。

顺便问一下,你在ultraedit 

中看着这个FILE_HEADER 

吗?

哦哦,看着呢,我的光标就停在这个010F 

标志处呢。

好,继续。

16个属性一下都说出来也太多,先学习hello.exe 

的这5个吧。

bit0:

文件不包含重定位信息。

bit1:

文件可以运行。

bit2:

文件不包含行号信息

bit3:

文件不包含符号信息。

bit8:

32bit 

机器上运行。

怎样,这你个属性很好理解吧,可执行文件不需要重定位,行号及符号信息。

在32bit机器上运行。

说了半天原来没有一个关键性东西,我还以为有多神秘呢!

是的,搞懂了它有时也觉得失望,其实,懂了也就这么简单。

2.15

再问一个关键性问题,看起来有点菜。

我以为,有text段,有data段就可以了,

那么.rdata, 

.rsrc 

是干什么用的呢

这个问题确实很关键,这正是PE 

文件与以往文件的差别所在。

其实只有text段,data段,pe文件是不可以运行的,因为PE文件的运行总是要调用

系统文件,而系统文件都是以DLL 

文件格式存在的,所以你必须要在文件中有动态链接

信息。

2.16

太复杂了,什么是动态连接信息,什么是动态连接库,听说过但没有真正理解。

动态连接是多进程操作系统引进的一个概念。

在DOS时代,单任务是没有动态连接的。

在DOS 

时代,连接器总是把库文件直接连接到可执行文件中。

叫静态连接。

这种做法

在单任务时是可以接受的,无非是每个连接的文件都包含一个库文件,造成磁盘空间

的一点浪费。

但静态连接在多任务时代不可以接受。

例如每个进程都会调用 

kernel32.Dll

如果采用静态连接,造成磁盘空间浪费不说,假若系统有20个进程,系统中就将会

有20份kernel32.dll, 

内存的浪费将是不可容忍的,动态连接的概念就是保证系统中

只有一份DLL,同时各个进程又都能够很好的运行。

好在动态连接是加载器的功能,

我们程序不用刻意去做什么,所以用起来也不是太复杂。

2.17

哦!

是这样,我原来以为链接程序都把事情处理好了,原来还没有,多进程中还要由

加载器进行动态连接。

那我们怎样使用动态连接呢?

当我们用汇编语言或C 

C++或者其它语言开发是,生成的PE文件对系统库的调用都是

动态连接。

我们并没有做什么。

当你想调用自己生成的DLL(第三方DLL),可以采用隐含动态连接或者显示动态连接来

加载DLL. 

听起来很炫用起来很简单,隐含链接就跟使用系统dll 

一样,你只要在文件

中包含第三方头文件(好引用它的函数啊。

)在连接选项里设置第三方的lib,dll位置

链接程序就帮你搞定了。

显示动态连接是在你的程序里用loadlibrary 

加载DLL, 

用getprocess 

获取DLL中函数

地址,然后用函数指针调用第三方函数。

2.18

哦. 

听你的意思看来使用DLL 

也是很简单的。

系统DLL使用我们不用管,怎样使用第三方

DLL以后再说吧,我现在的重点是想搞明白PE 

的文件格式。

那么既然它调用了

kernel32.Dll 

中的函数。

而这个函数的地址连接程序不知道,只能由加载器在运行时动态加载。

那么,加载器是怎么知道要加载那个DLL, 

要执行DLL中的那个程序呢?

这个问题问到点子上去了。

搞清了这个问题,PE 

格式就可以说入门了。

我们还是结合hello.exe 

实例说吧。

有HIEW 

软件吗,准备一下。

好:

1. 

用hiew 

打开hello.exe

2. 

按F4, 

选Decode.

3. 

按F5, 

敲入偏移400(我们上面分析过,text 

段在400)

干脆我把代码贴过来吧, 

双// 

是我注释的。

00000400:

6A00 

push 

000

00000402:

6800304000 

000403000 

;

@0 

00000407:

680C304000 

00040300C 

@0♀"

0000040C:

0000040E:

E809000000 

call 

00000041C 

//hiew 

分析出,这是MessageBoxA

00000413:

90 

nop

00000414:

00000415:

00000417:

E806000000 

000000422 

分析出,这是ExitProcess

0000041C:

FF2508204000 

jmp 

d,[00402008]

00000422:

FF2500204000 

d,[00402000]

---------------------------------------------------------------------------

我们分析 

Messagebox 

吧。

40e 

处:

41c, 

41c 

ds:

[00402008]

00402008.

这是虚拟内存地址。

我们用hiew 

找到它。

具体操作如下:

选hex. 

要看数据,选hex 

合适

敲入偏移600.

在hiew 

中看到了下一行。

.00402000:

76 

00-00 

00-5C 

2.19

喂,慢点,打扰一下,我这个人就喜欢刨根问底。

你怎么知道要敲入600呢?

是这样,调用DLL采用动态连接,动态连接信息是放在.rdata 

段,叫只读数据段。

你刚才不是问.rdata, 

是干什么的吗?

我现在才讲到了.rdata 

要想知道.rdata 

在哪,你的问.rdata 

的节表头。

我们已经讲过所有节表头组成一个

数组,紧跟在NT 

Header(总header)之后。

.rdata 

是第二项节表头,其名字是ascii码

很明显的。

我把它copy 

到这啦。

00001e0:

2e72 

6461 

7461 

0000 

9200 

0020 

.rdata....... 

..

00001f0:

0002 

0006 

................

0000200:

4000 

0040 

2e64 

6174 

6100 

....@..@.data...

这里根据 

答1.

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1