首页
社区
课程
招聘
[原创]菜鸟对PEid 0.95 Cave 查找功能逆向
发表于: 2016-6-17 12:21 11707

[原创]菜鸟对PEid 0.95 Cave 查找功能逆向

2016-6-17 12:21
11707
PEid 0.95 Cave 查找功能逆向

在学习CCDebuger前辈的OllyDBG入门系列七之汇编功能的时候,其中有一个部分用到了PEid的Cave查找功能,一开始不知道这个Cave查找是什么意思,CCDebuger前辈的截图使用的中文翻译版PEiD,里面显示的是‘搜索全0处’这个功能,如图所示


但是根据查找结果以及与文件对比,在文件该偏移处的size块内容并不是全0,在WinHex下查看如图所示

在我使用的从52pojie论坛下载的v0.95版本,这里显示的则是Cave 查找功能,如下图所示


不太理解这里是为什么,正好又一直在学习使用ollydbg,于是将PEid拖进了调试器,进行了简单的逆向以尝试解决疑问。

打开OD,载入PEid,执行后将任意文件拖进PEid中,这里我使用的是CCDebuger前辈用来做实例的myuninst程序,PEid先对该PE文件做了简单的查找分析,结果如下图所示


由于不知道怎么通过Ollydbg给右键菜单下断点,于是一开始我想在上图所示的按钮下Button的202 WM_LBUTTONUP断点,但是实际上程序断下来的地方是显示区段消息的一个界面,这个界面再通过右键菜单才能到Cave 查找功能,距离想要查找的地方太远,于是放弃。后来偶然想到,程序在显示Cave 查找结果的时候貌似是使用了MessageBox函数进行展示的,于是尝试着对MessageBoxA这个函数下断点,最终断在了0x44BDC6处,该函数部分如下

0044BC50  /$  55            push    ebp
0044BC51  |.  8BEC          mov     ebp, esp
0044BC53  |.  83E4 F8       and     esp, FFFFFFF8
0044BC56  |.  6A FF         push    -1
0044BC58  |.  68 7BCB4600   push    0046CB7B                         ;  SE handler installation
0044BC5D  |.  64:A1 0000000>mov     eax, dword ptr fs:[0]
0044BC63  |.  50            push    eax
0044BC64  |.  64:8925 00000>mov     dword ptr fs:[0], esp
0044BC6B  |.  81EC 18050000 sub     esp, 518
0044BC71  |.  53            push    ebx
0044BC72  |.  56            push    esi
0044BC73  |.  57            push    edi
0044BC74  |.  B9 0A000000   mov     ecx, 0A
0044BC79  |.  BE 186C4000   mov     esi, 00406C18                    ;      区段\t\t rva\t\t 偏移  MessageBoxA的各个项目的项目名称
0044BC7E  |.  8DBC24 200100>lea     edi, dword ptr [esp+120]

…………

0044BCB3  |.  6A 01         push    1
0044BCB5  |.  50            push    eax                              ;  文件路径指针
0044BCB6  |.  B9 001E4000   mov     ecx, 00401E00                    ;  this 指针
0044BCBB  |.  E8 E04BFFFF   call    004408A0                         ;  打开文件,并且将文件map映射到堆中
0044BCC0  |.  84C0          test    al, al
0044BCC2  |.  0F84 0E010000 je      0044BDD6
0044BCC8  |.  8B0D 101E4000 mov     ecx, dword ptr [401E10]          ;  [401E10] 文件大小
0044BCCE  |.  8B15 0C1E4000 mov     edx, dword ptr [401E0C]          ;  [401E0C] 映射的基地址
0044BCD4  |.  51            push    ecx
0044BCD5  |.  52            push    edx
0044BCD6  |.  B9 280D4700   mov     ecx, 00470D28
0044BCDB  |.  E8 E0760000   call    004533C0                         ;  检查文件正确性,并且构造一个文件结构,该结构存储在0x470d28处,保存文件一些属性

…………

0044BCE8  |.  6A 20         push    20
0044BCEA  |.  8D4424 14     lea     eax, dword ptr [esp+14]
0044BCEE  |.  68 280D4700   push    00470D28                         ;  上面建立的文件结构指针
0044BCF3  |.  50            push    eax                              ;  栈缓冲区变量,函数返回结果保存在这个变量中
0044BCF4  |.  E8 B7B2FEFF   call    00436FB0                         ;  关键!需要步进

…………

下面是一个循环,对每个section调用了wsprintf构造格式化字符串,生成结果字符串,最后使用MessageBoxA打印输出结果。wsprintf使用的参数部分是通过上面的sub_00436FB0函数计算得到的,后面我们只需要着重分析该函数即可知道我们想要的结果。

0044BD38  |.  8B1D 4C124000 mov     ebx, dword ptr [<&USER32.wsprint>;  USER32.wsprintfA
0044BD3E  |.  8BFF          mov     edi, edi
0044BD40  |> /8378 28 10    /cmp     dword ptr [eax+28], 10
0044BD44  |. |72 05         |jb      short 0044BD4B
0044BD46  |. |8B48 14       |mov     ecx, dword ptr [eax+14]
0044BD49  |. |EB 03         |jmp     short 0044BD4E
0044BD4B  |> |8D48 14       |lea     ecx, dword ptr [eax+14]
0044BD4E  |> |8B50 08       |mov     edx, dword ptr [eax+8]
0044BD51  |. |52            |push    edx                             ;  size
0044BD52  |. |8B50 04       |mov     edx, dword ptr [eax+4]
0044BD55  |. |8B00          |mov     eax, dword ptr [eax]
0044BD57  |. |52            |push    edx                             ;  offset
0044BD58  |. |50            |push    eax                             ;  RVA
0044BD59  |. |51            |push    ecx                             ;  section name
0044BD5A  |. |8D4C24 30     |lea     ecx, dword ptr [esp+30]         ;  output buffer
0044BD5E  |. |68 006C4000   |push    00406C00                        ;  %8s\t\t%08x\t%08x\t%08x\n\n
0044BD63  |. |51            |push    ecx
0044BD64  |. |FFD3          |call    ebx                             ;  调用wsprintf格式化构造MessageBoxA函数的输出字符串
0044BD66  |. |8D4424 38     |lea     eax, dword ptr [esp+38]
0044BD6A  |. |83C4 18       |add     esp, 18
0044BD6D  |. |8BC8          |mov     ecx, eax
0044BD6F  |. |90            |nop
0044BD70  |> |8A10          |/mov     dl, byte ptr [eax]
0044BD72  |. |40            ||inc     eax
0044BD73  |. |84D2          ||test    dl, dl
0044BD75  |.^|75 F9         |\jnz     short 0044BD70
0044BD77  |. |8DBC24 200100>|lea     edi, dword ptr [esp+120]
0044BD7E  |. |2BC1          |sub     eax, ecx
0044BD80  |. |8BF1          |mov     esi, ecx
0044BD82  |. |4F            |dec     edi
0044BD83  |> |8A4F 01       |/mov     cl, byte ptr [edi+1]
0044BD86  |. |47            ||inc     edi
0044BD87  |. |84C9          ||test    cl, cl
0044BD89  |.^|75 F8         |\jnz     short 0044BD83
0044BD8B  |. |8BC8          |mov     ecx, eax
0044BD8D  |. |C1E9 02       |shr     ecx, 2
0044BD90  |. |F3:A5         |rep     movs dword ptr es:[edi], dword >
0044BD92  |. |8BC8          |mov     ecx, eax
0044BD94  |. |A1 4C104700   |mov     eax, dword ptr [47104C]
0044BD99  |. |83E1 03       |and     ecx, 3
0044BD9C  |. |F3:A4         |rep     movs byte ptr es:[edi], byte pt>
0044BD9E  |. |8B0D 58104700 |mov     ecx, dword ptr [471058]
0044BDA4  |. |83C0 2C       |add     eax, 2C
0044BDA7  |. |3BC1          |cmp     eax, ecx
0044BDA9  |. |A3 4C104700   |mov     dword ptr [47104C], eax
0044BDAE  |.^\75 90         \jnz     short 0044BD40
0044BDB0  |>  8B45 0C       mov     eax, dword ptr [ebp+C]
0044BDB3  |.  68 00000400   push    40000                            ; /Style = MB_OK|MB_APPLMODAL|40000
0044BDB8  |.  68 F46B4000   push    00406BF4                         ; |cave 信息                        从这个title我们也可以猜到,这个MessageBoxA函数的调用就是我们输出我们想要的结果的
0044BDBD  |.  8D9424 280100>lea     edx, dword ptr [esp+128]         ; |
0044BDC4  |.  52            push    edx                              ; |Text
0044BDC5  |.  50            push    eax                              ; |hOwner
0044BDC6  |.  FF15 70134000 call    dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA

sub_436FB0比较长,而且对PE文件做了很多安全检查,包括各种size大小是否正确,文件类型是否正确,target machine字段是否正确等,这里只对部分关键代码进行分析,其他部分则是通过查找然后cmp目标值进行判断的。

00437016  |> /8B8C24 A40000>/mov     ecx, dword ptr [esp+A4]
0043701D  |. |8D49 00       |lea     ecx, dword ptr [ecx]
00437020  |> |8B01           mov     eax, dword ptr [ecx]            ;  eax == 文件映射基地址
00437022  |. |8B7D 00       |mov     edi, dword ptr [ebp]            ;  RawOffset / PointToRawData
00437025  |. |03F8          |add     edi, eax                        ;  获取文件映射内存处该section的起始地址
00437027  |. |8B4424 14     |mov     eax, dword ptr [esp+14]
0043702B  |. |50            |push    eax
0043702C  |. |E8 4FC30100   |call    00453380                        ;  在VirtualSize、RawDataSize、FileSize-PointToRawData三个量之间计算得到最小值
00437031  |. |8BF0          |mov     esi, eax
00437033  |. |3BF3          |cmp     esi, ebx
00437035  |. |0F84 C9010000 |je      00437204
0043703B  |. |8B8C24 A40000>|mov     ecx, dword ptr [esp+A4]
00437042  |. |8B41 04       |mov     eax, dword ptr [ecx+4]
00437045  |. |3945 00       |cmp     dword ptr [ebp], eax            ;  判断SizeOfRawData与FileSize的大小,如果FileSize 小,则跳过该section
00437048  |. |0F83 B6010000 |jnb     00437204
0043704E  |. |8B49 14       |mov     ecx, dword ptr [ecx+14]
00437051  |. |8B41 24       |mov     eax, dword ptr [ecx+24]         ;  FileAlignment的值
00437054  |. |8D4C30 FF     |lea     ecx, dword ptr [eax+esi-1]
00437058  |. |48            |dec     eax
00437059  |. |F7D0          |not     eax
0043705B  |. |23C8          |and     ecx, eax                        ;  SizeOfRawData 以 FileAlignment值 向上对齐,比如 .text 的大小为9411, 处理之后为9600
0043705D  |. |8D49 00       |lea     ecx, dword ptr [ecx]
00437060  |> |385C37 FF     |/cmp     byte ptr [edi+esi-1], bl       ;  从section的尾部(section_start + section_size - 1)开始寻找,直到找到第一个0值,或者找到section头部位置
00437064  |. |75 03         ||jnz     short 00437069
00437066  |. |4E            ||dec     esi
00437067  |.^|75 F7         |\jnz     short 00437060
00437069  |> |8B9424 A80000>|mov     edx, dword ptr [esp+A8]         ;  [esp+A8] is a constant, pushed in 44BCE8 to call sub_436FB0
00437070  |. |8BF9          |mov     edi, ecx
00437072  |. |2BFE          |sub     edi, esi                        ;  这里就是我们的关键点了,将对齐后的SizeOfRawData 与上面寻找到的最尾部的0做差,就是cave的大小了,结果放在edi寄存器中作为直到后面处理,以及输出
00437074  |. |83C2 08       |add     edx, 8
00437077  |. |3BFA          |cmp     edi, edx
00437079  |. |0F86 85010000 |jbe     00437204

上面通过计算得到的值,在后面又做了一个-8操作,才是最终真正输出的cave size,至此也弄清楚了整个cave 查找的方法了,CCDebuger前辈的PEid中汉化的注释并不正确,不是所谓的搜索全0处,而是搜索section的0结束处,一直到section最后文件块的结束处的大小。

附件是分析的样本PEid。

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 3
支持
分享
最新回复 (11)
雪    币: 44229
活跃值: (19965)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
2
感谢分享,建议图片放到论坛本地。
2016-6-17 16:42
0
雪    币: 144
活跃值: (178)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
这么低调
2016-6-17 20:17
0
雪    币: 16161
活跃值: (1345)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
论坛传图 和 贴子编辑 费了洋劲儿
建议找个 像CSDN 或 51cto  那样的博客 用windows live writer 写好后 外链!
毕竟不是DZ类型的。
老的opera论坛也比看雪的论坛贴子编辑好使啊。
2016-6-17 21:12
0
雪    币: 31
活跃值: (44)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
5
虽然注册账号好久了,可是最近才开始发帖,真的不知道怎么上图片,挂CSDN外链的方法还是从别的帖子上看来的。
2016-6-17 22:13
0
雪    币: 10867
活跃值: (17252)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
多谢楼主分享的好工具PEid啊,确实好用
2016-6-20 09:05
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
写的挺详细的
2016-6-25 09:40
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
感谢分享,确定是菜鸟?哈哈
2016-6-27 21:21
0
雪    币: 76
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
感谢分享,确定是菜鸟?哈哈
2016-7-1 17:56
0
雪    币: 9
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
感谢,十分有帮助
2016-7-9 16:01
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
门外汉来学习,请多多关照,谢谢各位。
2017-3-21 21:05
0
雪    币: 57
活跃值: (73)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
好评了啊,继续学习
2017-7-13 21:58
0
游客
登录 | 注册 方可回帖
返回
//