stud_PE软件
从这张图片中我们得到如下信息

- 入口点的RVA: 1000, 入口点的VA = imageBase + RVA
- imageBase = 400000
- 入口点的RAW 也就是文件偏移???(这个好像我解释不清楚)
- 文件中的对齐粒度: 200
- 内存中的对齐粒度 1000
- 映像大小?
- 区段数目, 也就是节的数目
- 导入表 也就是IDT的RVA = 2014, 大小是 3C 也就是 60 个字节, 在文件中的偏移是 0614


查看每个节的具体信息
- 虚拟大小是指实际的大小
- 虚拟偏移量是指在内存中的RVA
- 原始大小是指在文件中(文件中的对齐粒度是200)的大小
- 原偏移量是指RAW
- 特性:如下图所示

从外部引入的函数

ok Stud_PE的分析就差不多到这里
PEView分析
挑最主要的说
DOS头中最重要的就是最后一个字段

文件头
最重要的也就是这个说明可选头大小的字段了

可选头
这几个字段都特别重要, 但是又经常记不住

节表
我觉得最重要的就是这两个了

知道了text节的RVA和原始文件偏移, 就可以计算节偏移
比如你知道了一个RVA是1024
这时候只需要将1024 - 600 = 424
这个就是这个RVA对应的文件偏移量了

其他的节表依次类推都可以了
.rdata节
这个节是最不想分析的。。。
- 这个节最重要的就是IDT, IDT的RVA可以通过可选头查到
- 看这个PE文件引用了几个外部的dll, n个dll就是 有(n+1)*20个字节大小
- IDT的每一项都是20个字节, 分成5个部分, 每一个部分都是4个字节, 第一个四个字节直接指向了INT, 最后一个四个字节直接指向了IAT。
- IDT的最后一项,也就是20个字节, 全部填0
- INT和IDT在文件中是一样的, 有几个dll, 就有几个项。
- INT和IDT的每一项都是8个字节,其中前四个字节指向hint, 后四个字节全部填0
- INT的第一项的四个字节的最高位如果是0, 代表用名字来引入函数, 如果是1, 代表用序号来引入函数
- IAT在内存中会被对应函数的地址取代, INT还是原来的
通过序号引入外部函数
首先明确一下PE文件是怎么引入外部的函数地
请看这张图

图上的IID应该是IDT
IDT有三个重要的字段, 第一个 OriginalFirstTrunk , 存储的值是指向INT的RVA,
最后一个 FirstTrunk 存储的值是指向IAT的RVA。
中间还有一项, name, 存储的值是指向hints里面的字符串。
所以IDT的目的是装载相应的库, INT是去根据序号或者函数的名字取dll中找到函数的地址, 然后再根据IDT中读到IAT的RVA, 把函数的地址一项项填到IAT中, 至此一个函数的引入就完成了。
再具体分析一下;
1.在IDT中找到库名字的RVA。

-
在文件中找到库的名字。装载相应的库
-
在IDT中找到INT的RVA
-
定位INT,
这时候可以看到是通过序号引入还是通过名字引入
如果是序号引入, 最高位是1, 十六进制表示是8, 这样就直接去库文件中找到相应的函数地址。
这里做了一个小实验, 本来文件是通过函数名引入的 但是如果我将高位修改为1, 这时候通过序号引入, 但是这个序号出错了。 所以报错如下


手动去找exitProcess的序号 183, 十六进制就是

然后修改函数的序号,这时候就能成功地引入外部的函数了。

当然, 也可以用peview去找函数的序号

- 通过INT找到函数的VA之后, 我们还需要通过IDT去定位IAT, 并将函数的VA放入到IAT中。
如此循环往复, 外部的函数就装载完了。
通过OD可以看到定位了外部函数的VA。

那么如何在内存中去查看IAT中的内容呢?
打造最小PE文件
修改最小对齐单位
可选文件头的目录项只需要引入函数节
节表也可以进行删除
网友评论