PE文件格式详解

Posted 2f28

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PE文件格式详解相关的知识,希望对你有一定的参考价值。

0x00 前言

  前面两篇讲到了输出表的内容以及涉及如何在hexWorkShop中找到输出表及输入DLL,感觉有几个地方还是没有理解好,比如由数据目录表DataDirectory[16]找到输出表表后以为找到输入DLL就完了,其实这一流程的最终功能是通过输入DLL找到输入DLL调用的函数,这一步骤是通过输出表结构中的OriginalFristThunk或者OriginalFristThunk所指向的INT或者IAT结构来找到的。这里要说明的是,虽然一般情况通过OriginalFristThunk也行,但是有些情况下它的值被设置为0了,这样就无法利用了,最委托的的方式是通过FristThunk所指向的IAT表来找寻。下面来通过实例实践这一过程。

0x01 找寻输入DLL以及输入DLL调用的函数

   材料及工具:名为PE.exe的可执行文件,工具hexWrokshopLordPE

   思路:找到PE文件头——》找到数据目录表第二项——》通过地址转换找到输出表数组——》逐个读出输出表数组的OriginalFristThunkFristThunk值——》通过INT或者IAT逐个读出被调用函数的名字地址——》通过名字地址找到函数名。

1)将目标文件拖入hexWrokShop,快捷键ctrl+g跳往载入地址的3ch处,这里即PE文件头地址,如下图:

技术分享图片

 2)跳往40h处,该处即为文件头,如下图:

技术分享图片

 

3)跳往PE文件头+80h处,该处存储了输入数据表的地址如下图:

技术分享图片

4)RVA=2040h转化位FileOffset地址,这里我们利用lordpe协助转化,转化后值为440h。

技术分享图片

5)跳转至440h处,该处即为输出表IID数组的数据所在,每项为五对双字组成,结尾以五对双字0。我这个实例一共两组,如下图:

技术分享图片

 将以上根据字段数据统计如下表(PS:由于hex中是由低位到高位的故统计时应该注意高低位的换位):

 

OriginalFristThunk

TimeStamp

ForwardChain

Name

FristThunk

0000208C

00000000

00000000

00002174

00002010

0000207C

00000000

00000000

000021B4

00002000

利用表中的Name字段我们可以直接推出输入DLL的名字,第一项NameRVA2174h,转化为FileOffset值为:574h,跳往574h,我们可以看到第一个DLLUSER32.DLL,如下图:

技术分享图片

 第二项的Name值为RVA值为21B4h,转化位FileOffset值为5B4h,跳往574h,我们知道第二项DLLKERNEL32.DLL,如下图:

 技术分享图片

6)知道了输入DLL不是我们目的终点,我们还要知道DLL所调用的所有函数名字地址,这里有两个字段可用,第一个是OriginalFristThunk,它所指向的是一个名为输入名称表(INT)的结构,这个结构是由多个IMAGE_THUNK_DATA结构所组成的数组。第二个是FristThunk,它所指向的是一个名称为输入地址表的(IAT)的结构,这个结构也是有多个IMAGE_THUNK_DATA结构所组成的数组。IMAGE_THUNK_DATA双字数组的每项指向另一个结构——IMAGE_IMPORT_BY_NAME。最终通过IMAGE_IMPORT_BY_NAME找到被DLL调用的函数。一般而言,这两个被指向的数组值是相等的。我们接下来分别用两个字段来查找。我们先用第一项的OriginalFristThunk来试试,将208C转化为FileOffset48ch。掉跳往48ch,的如下图结果,共十一项,以双字0结尾。

技术分享图片

我们用FristThunk来试试,将2010h转化为FileOffset410h,跳往410h,可得下图:

技术分享图片

 它们的值都为:

102100001C210000F4200000E0200000502100006421000002210000CE200000BC2000002E21000042210000,将数据按八个字节拆分与翻转的下表:

    第一项指向的IAMGE_THUNK_DATA数组

00002110

0000211C

000020F4

000020E0

00002150

00002164

00002102

000020CE

000020BC

0000212E

00002142

 

 

 

 

 

接下来进行地址转换,的下表:

510

51c

4f4

4e0

550

564

502

4ce

4bc

52e

542

 

7)由上表逐个查询出被调用函数名,如下图:

技术分享图片

 

重复以上操作的下表:

RVA

FileOffset

Hint

函数名

00002110

510

019B

LoadIconA

0000211C

51c

01DD

PostQuitMessage

000020F4

4f4

0128

GetMessageA

000020E0

4e0

0094

DispatchMessageA

00002150

550

027D

TranslateMessage

00002164

564

028B

UpdateWindow

00002102

502

0197

LoadCursorA

000020CE

4ce

0083

DefWindowProcA

000020BC

4bc

0058

CreateWindowExA

0000212E

52e

01EF

RegisterClassExA

00002142

542

0265

ShowWindow

 

 

 

 

8)当然你可能会觉得这样找输入表实在太麻烦了,确实是,但是只有经过这样找你才能弄明白输出表到底是如何存放的转换的,从而对PE文件格式有更为透彻理解。接下来我们通过强大的lordPE来轻松查找到输入表和输入函数。如下图:

技术分享图片

技术分享图片

 0x02 总结

  这两天看加密与解密收获很大,对于对逆向破解的朋友我强烈建议读一读此书,有相同兴趣的朋友欢迎评论留言交流。

以上是关于PE文件格式详解的主要内容,如果未能解决你的问题,请参考以下文章

PE 格式详解与试验

PE 格式详解与试验

PE文件格式详解,第三讲,可选头文件格式,以及节表

PE文件格式详解

PE文件格式详解

PE 文件格式 详解 二