脱壳-MoleBox(2.0.0-2.3.0)

来源:互联网 发布:找工作可靠的软件 编辑:程序博客网 时间:2024/05/22 06:42

前言

练习了MoleBox(2.0.0-2.3.0)的脱壳, 记录一下脱壳流程点.
找到OEP后, 去看IAT项, 系统DLL地址被换成了壳函数的地址(API redirection).
如果不使IAT项为系统API地址, 运行时闪退.

记录

查壳

Detect It Easy 1.01  => MoleBox(2.0.0-2.3.0)[-]

找OEP

---------------------------Compressed code?---------------------------Quick statistical test of module 'API_Redi' reports that its code section is either compressed, encrypted, or contains large amount of embedded data. Results of code analysis can be very unreliable or simply wrong. Do you want to continue analysis?---------------------------是(Y)   否(N)   ---------------------------

选No, 不分析代码.

0044CB58 >  60              pushad             ; EP0044CB59    E8 4F000000     call    0044CBAD   ; ESP定律, 对ESP对应的内存地址下硬件访问断点(DWORD)
0044C731    58              pop     eax        ; F9后, ESP定律第一次被触发时, 到达这里0044C732    58              pop     eax0044C733    FFD0            call    eax        ; F7去OEP
004331B8    55              push    ebp        ; OEP004331B9    8BEC            mov     ebp, esp004331BB    6A FF           push    -1004331BD    68 00A34300     push    0043A300004331C2    68 1C334300     push    0043331C   ; jmp to msvcrt._except_handler3

观察API的IAT表项值

从OEP往下翻, 随便找一个系统API.

004332BC    FF15 84814300   call    dword ptr [438184]      ; kernel32.GetStartupInfoA

去438184去看IAT表项是否正常, 如果被API地址重定向, 表项值就不是系统API原始地址, 而是壳地址.
全部翻看一遍, 看看有没有IAT表项被API重定向

00438184  7C801EF2  kernel32.GetStartupInfoA00438188  7C835EA7  kernel32.MoveFileA0043818C  7C813841  kernel32.GetFileAttributesExA00438190  7C80E87C  kernel32.FileTimeToSystemTime00438194  7C80A164  kernel32.WideCharToMultiByte00438198  00459254  API_Redi.00459254 // 发现了API重定向0043819C  7C80E8F6  kernel32.FileTimeToLocalFileTime

在Memory中, 看API实现在壳里.

Memory mapAddress    Size       Owner      Section    Contains      Type   Access    Initial   Mapped as00400000   00001000   API_Redi              PE header     Imag   R         RWE00401000   00037000   API_Redi   0          code          Imag   R         RWE00438000   0000A000   API_Redi   1          data          Imag   R         RWE00442000   00005000   API_Redi   2                        Imag   R         RWE00447000   00004000   API_Redi   3          resources     Imag   R         RWE0044B000   00011000   API_Redi   4          SFX           Imag   R         RWE // API重定向的实现在壳里0045C000   00001000   API_Redi   5          imports       Imag   R         RWE0045D000   00008000   API_Redi   6                        Imag   R         RWE00470000   00003000                                       Map    R E       R E00530000   00002000                                       Map    R E       R E

对重定向的IAT表项下硬件断点

目的:找出壳中API重定向的代码实现.

00438198  00459254  API_Redi.00459254

挑一个被API重定向的表项地址, 下硬件写断点(DWORD).
重新跑程序.

转到Memory窗口看00438198啥时候写入系统API地址, 按下F9观察.

00451B35    66:8901         mov     word ptr [ecx], ax      ; 再写0043819800451B38    8B45 F8         mov     eax, dword ptr [ebp-8]  ; API_Redi.00438198

可以取消此处的硬件写断点.
在写00438198, F8跟出去, 看函数调用点

00451BAA   /EB 07           jmp     short 00451BB3            ; do-while00451BAC   |8B45 F8         mov     eax, dword ptr [ebp-8]    ; do00451BAF   |40              inc     eax00451BB0   |8945 F8         mov     dword ptr [ebp-8], eax00451BB3   \8B45 F8         mov     eax, dword ptr [ebp-8]00451BB6    3B45 0C         cmp     eax, dword ptr [ebp+C]    ; 下硬件执行断点00451BB9    7D 20           jge     short 00451BDB            ; 判断:是否要API重定向00451BBB    8B45 F4         mov     eax, dword ptr [ebp-C]00451BBE    83C0 68         add     eax, 6800451BC1    50              push    eax00451BC2    FF75 FC         push    dword ptr [ebp-4]00451BC5    FF75 FC         push    dword ptr [ebp-4]00451BC8    8B4D F4         mov     ecx, dword ptr [ebp-C]00451BCB    E8 9CF9FFFF     call    0045156C                  ; API重定向00451BD0    8B45 FC         mov     eax, dword ptr [ebp-4]    ; API_Redi.0043819800451BD3    83C0 08         add     eax, 800451BD6    8945 FC         mov     dword ptr [ebp-4], eax00451BD9  ^ EB D1           jmp     short 00451BAC            ; continue00451BDB    C9              leave00451BDC    C2 0800         retn    8

在00451BB6下硬件执行断点, 重新跑程序.
断点命中在00451BB6, 取消硬件执行断点.
此时00438198处还不是系统API断点

00451BCB    E8 9CF9FFFF     call    0045156C                  ; 写IAT项, 还不是API地址或壳内的函数地址

在00451BDB处F4, 让壳写完.

00451BDB    C9              leave

F8跟出去, 看看哪里写系统API地址.

004537E2    8B45 F0         mov     eax, dword ptr [ebp-10]   ; 循环开始004537E5    83C0 01         add     eax, 1004537E8    8945 F0         mov     dword ptr [ebp-10], eax004537EB    8B4D F0         mov     ecx, dword ptr [ebp-10]004537EE    3B4D FC         cmp     ecx, dword ptr [ebp-4]004537F1    0F83 9E000000   jnb     00453895004537F7    8B55 F0         mov     edx, dword ptr [ebp-10]004537FA    6BD2 28         imul    edx, edx, 28004537FD    A1 1CF64500     mov     eax, dword ptr [45F61C]00453802    03C2            add     eax, edx00453804    8945 E4         mov     dword ptr [ebp-1C], eax00453807    8B4D E4         mov     ecx, dword ptr [ebp-1C]0045380A    8379 0C 00      cmp     dword ptr [ecx+C], 00045380E    75 02           jnz     short 0045381200453810  ^ EB D0           jmp     short 004537E200453812    837D F0 20      cmp     dword ptr [ebp-10], 2000453816    73 21           jnb     short 0045383900453818    BA 01000000     mov     edx, 10045381D    8B4D F0         mov     ecx, dword ptr [ebp-10]00453820    D3E2            shl     edx, cl00453822    A1 04F64500     mov     eax, dword ptr [45F604]00453827    8B48 10         mov     ecx, dword ptr [eax+10]0045382A    23CA            and     ecx, edx0045382C    85C9            test    ecx, ecx0045382E    74 09           je      short 0045383900453830    C745 D8 0100000>mov     dword ptr [ebp-28], 100453837    EB 07           jmp     short 0045384000453839    C745 D8 0000000>mov     dword ptr [ebp-28], 000453840    8B55 D8         mov     edx, dword ptr [ebp-28]00453843    8955 E0         mov     dword ptr [ebp-20], edx00453846    837D F0 20      cmp     dword ptr [ebp-10], 200045384A    73 22           jnb     short 0045386E0045384C    B8 01000000     mov     eax, 100453851    8B4D F0         mov     ecx, dword ptr [ebp-10]00453854    D3E0            shl     eax, cl00453856    8B0D 04F64500   mov     ecx, dword ptr [45F604]0045385C    8B51 14         mov     edx, dword ptr [ecx+14]0045385F    23D0            and     edx, eax00453861    85D2            test    edx, edx00453863    74 09           je      short 0045386E00453865    C745 D4 0100000>mov     dword ptr [ebp-2C], 10045386C    EB 07           jmp     short 004538750045386E    C745 D4 0000000>mov     dword ptr [ebp-2C], 000453875    8B45 D4         mov     eax, dword ptr [ebp-2C]00453878    8945 DC         mov     dword ptr [ebp-24], eax0045387B    8B4D EC         mov     ecx, dword ptr [ebp-14]0045387E    51              push    ecx0045387F    8B55 E4         mov     edx, dword ptr [ebp-1C]00453882    52              push    edx00453883    8B45 DC         mov     eax, dword ptr [ebp-24]00453886    50              push    eax00453887    8B4D E0         mov     ecx, dword ptr [ebp-20]0045388A    51              push    ecx0045388B    E8 B0000000     call    0045394000453890  ^ E9 4DFFFFFF     jmp     004537E2                  ; 一个循环写IAT项,但还不是API地址00453895    8B15 04F64500   mov     edx, dword ptr [45F604]   ; 写完了会到这里, F4等着来

F8往下走, 可以看到经过一个CALL时, IAT表项中有系统API地址, 也有壳函数地址.
在这个函数调用点下硬件执行断点, 重新跑程序.

004538C3    50              push    eax                       ; 下硬件执行断点004538C4    E8 D7FBFFFF     call    004534A0                  ; IAT表项 API重定向

F7跟进004534A0去看API重定向的判断, 观察00438198内容

004536E5    8B0D C0EB4500   mov     ecx, dword ptr [45EBC0]   ; API_Redi.0045EBC4004536EB    51              push    ecx004536EC    8B55 E0         mov     edx, dword ptr [ebp-20]004536EF    52              push    edx ; 下硬件执行断点等着004536F0    E8 9B070000     call    00453E90                  ; 这个CALL写IAT表项004536F5    83C4 0C         add     esp, 0C004536F8  ^ E9 3EFFFFFF     jmp     0045363B                  ; 循环004536FD    8B45 E8         mov     eax, dword ptr [ebp-18]00453700    A3 C0EB4500     mov     dword ptr [45EBC0], eax00453705    8B4D F8         mov     ecx, dword ptr [ebp-8]00453708    6BC9 14         imul    ecx, ecx, 140045370B    8B55 08         mov     edx, dword ptr [ebp+8]0045370E    C7440A 04 FEFFF>mov     dword ptr [edx+ecx+4], -200453716  ^ E9 98FDFFFF     jmp     004534B3                  ; 循环0045371B    8A45 FC         mov     al, byte ptr [ebp-4]0045371E    8BE5            mov     esp, ebp00453720    5D              pop     ebp00453721    C3              retn                              ; IAT写完了

现在除了硬件断点(ESP定律地址 +004536EF )没有其他断点.
F7进入00453E90, 看写IAT实现.

有点跟蒙了, 对00438198下硬件写入断点, 再看看谁在写IAT.
写IAT的代码就在这个函数中.

0045369B         FF15 A8F64500   call    dword ptr [45F6A8]                     ; kernel32.GetProcAddress004536A1         8B4D E0         mov     ecx, dword ptr [ebp-20]004536A4         8901            mov     dword ptr [ecx], eax                   ; 这里在写IAT, 第一次写的是系统API地址
00438198  7C80B731  kernel32.GetModuleHandleA

重新跑程序, 2个硬件断点都在(ESP定律地址, 写00438198).
翻IAT表项, 发现前面已经将IAT API重定向了

00438040  00458C35  API_Redi.00458C35

最上面被改的内存地址是00438040.
对00438040做内存写入硬件断点, 取消对00438198的硬件写入断点.
重新跑程序, 2个硬件断点都在(ESP定律地址, 写00438040).
在Memory窗口定位00438040, 看着写的内容.
F9继续, 当第三次F9时, 发现写入了系统API地址

004536A4                              8901            mov     dword ptr [ecx], eax                   ; 这里再写IAT, 第一次写的是系统API地址004536A6                              EB 2C           jmp     short 004536D4
00438040  7C80EE67  ASCII "j$h"
7C80EE67 kernel32.FindClose           6A 24           push    24

现在F7往下走, 看看谁在API重定向.

004536DD                              85D2            test    edx, edx004536DF                              74 17           je      short 004536F8                         ; 要跳,否则API重定向004536E1                              8B45 DC         mov     eax, dword ptr [ebp-24]                ; API重定向004536E4                              50              push    eax004536E5                              8B0D C0EB4500   mov     ecx, dword ptr [45EBC0]                ; API_Redi.0045EBC4004536EB                              51              push    ecx004536EC                              8B55 E0         mov     edx, dword ptr [ebp-20]004536EF                              52              push    edx                                    ; 下硬件执行断点等着004536F0                              E8 9B070000     call    00453E90                               ; 这个CALL写IAT表项004536F5                              83C4 0C         add     esp, 0C004536F8                            ^ E9 3EFFFFFF     jmp     0045363B                               ; 循环

修改代码, 不让API重定向

004536DF                             /EB 17           jmp     short 004536F8                         ; 要跳,否则API重定向

F9, 走到OEP

0044C731                              58              pop     eax                                    ; F9后, ESP定律第一次被触发时, 到达这里0044C732                              58              pop     eax0044C733                              FFD0            call    eax                                    ; F7去OEP

到达OEP

004331B8                              55              push    ebp                                    ; OEP004331B9                              8BEC            mov     ebp, esp004331BB                              6A FF           push    -1004331BD                              68 00A34300     push    0043A300004331C2                              68 1C334300     push    0043331C                               ; jmp to msvcrt._except_handler3

查看IAT是否全部正常

00438000  77DAE9E4  ADVAPI32.RegCreateKeyExA00438004  77DA6C17  ADVAPI32.RegCloseKey00438008  77DB54A4  ADVAPI32.GetUserNameA0043800C  77DA7AAB  ADVAPI32.RegQueryValueExA00438010  77DA7842  ADVAPI32.RegOpenKeyExA00438014  77DAEAD7  ADVAPI32.RegSetValueExA00438018  000000000043801C  77EFBA3F  GDI32.TextOutA00438020  77EF5B70  GDI32.SelectObject00438024  77F0C63D  GDI32.GetTextExtentPoint32A00438028  77EF8D16  GDI32.GetObjectA0043802C  77EF9410  GDI32.SetMapMode00438030  77EF5D77  GDI32.SetTextColor00438034  77F1BC60  GDI32.CreateFontA00438038  000000000043803C  7C80BCF9  kernel32.SizeofResource00438040  7C80EE67  ASCII "j$h"00438044  7C80BB31  kernel32.lstrcmpiA00438048  7C834DB9  kernel32.GlobalSize0043804C  7C80BE46  kernel32.lstrlenA00438050  7C80236B  kernel32.CreateProcessA00438054  7C82134B  kernel32.GetWindowsDirectoryA00438058  7C814F7A  kernel32.GetSystemDirectoryA

将IAT表项从上到下扫了一遍, IAT表项地址全部是系统API地址.
可以脱壳了.
在OEP处, 用ollyDump脱壳(选择默认的导入表修复选项).
运行脱壳后的程序, 已经可以正常跑了.

0 0
原创粉丝点击