首页
社区
课程
招聘
[原创]第十六题 CrackMe逆向分析
发表于: 2016-12-6 12:48 3054

[原创]第十六题 CrackMe逆向分析

2016-12-6 12:48
3054
首先说明一下,还原虚拟机需要一套复杂的流程和巨大的工作量,具体还原程度视目标而定。

由于该题有反调试措施,所以使用OD附加过掉反调试还是比较方便的。另外作者提供了32位修补bug的方法,在32位下使用SOD也可以过掉反调试。
Crackme除了采用虚拟机外还使用了自修改SMC技术,只有跑过壳的shellcode才能见识到真正有用的代码。

虚拟机为栈式虚拟机,下面是虚拟机的结构
EDI  指向 cpu context
ESI  指向 vm_code
EBP  指向 vm_stack
vm_handler表在 42271B,且没有加密
vm_code 没有加密

主要逆向流程如下:
输入序列号后来到程序空间,如下:
0040140D  /.  55            push    ebp
0040140E  |.  8BEC          mov     ebp, esp
00401410  |.  6A 00         push    0
00401412  |.  FF75 0C       push    dword ptr [ebp+C]
00401415  |.  FF75 08       push    dword ptr [ebp+8]
00401418  |.  E8 D8FDFFFF   call    004011F5
0040141D  |.  83C4 0C       add     esp, 0C
00401420  |.  5D            pop     ebp
00401421  \.  C3            retn
该函数为“gets”,为获取控制台输入的序列号

通过runtrace 很容易找到vm_loop,如下:
004210BD         主        xor     ax, 0BF77        FL=S, EAX=0000E851
004210C2         主        jmp     short 004210C6
004210C6         主        lea     eax, dword ptr [edi+40]        EAX=0012FAF8
004210C9         主        jmp     short 004210CC
004210CC         主        cmp     ebp, eax        FL=PA
004210CE         主        jmp     short 004210D1
004210D1         主        ja      00421208
00421208         主        movzx   eax, byte ptr [esi]        EAX=0000001B
0042120B         主        jmp     0042123A
0042123A         主        lea     esi, dword ptr [esi+1]        ESI=0043E5D9
0042123D         主        jmp     0042121E
0042121E         主        popfd        FL=A, ESP=0012FA78
0042121F         主        jmp     short 00421224
00421224         主        jmp     dword ptr [eax*4+42271B] ;这里跳转到每个handler

对00421224下断,分析每个handler(这里也可以静态分析)
1B  vm_push_imm32
1C  vm_jcc
27  vm_push_reg32
26  vm_imul
01  vm_add_stk
17  vm_add_32
1D  vm_pop_mem32
0B  vm_push_mem32
05  vm_set_eflags
16  vm_get_eflags
17  vm_copy_stk
14  vm_copy_stk32
19  vm_nand32
02  vm_shr_32
09  vm_sub_32
06  vm_push_eflags
22  vm_pop_eflags
11  vm_pop_reg32
24  vm_nop
08  vm_exit
0D  vm_push_stk
0F  vm_push_imm8
12  vm_exts8_32
22  vm_push_stk
18  vm_push_esp
0E  vm_copy_stk8
1E  vm_pop_reg8
10  vm_push_reg8
1F  vm_push_mem
1D  vm_pop_mem32
如果算法不够复杂,则不需要完全逆向虚拟机,只需要分析出部分有用的handler进行动态跟踪即可。

因为cmp指令在虚拟机中都是通过减法模拟的,所以在vm_sub 的handler处下断,会发现
004213EB    2945 00         sub     dword ptr [ebp], eax
004213EE  ^ E9 78FEFFFF     jmp     0042126B
这里将我们输入的序列号长度n与0d进行了减法,说明序列号长度为0d。而操作码0F vm_push_imm8,将8bit立即数0d加载到栈顶。

由于vm_code没有加密,所以可以直接对vm_code 进行解析
0043E600 0F 0D 12 05 09 16 01 04 00 1B 26 E6 43 00 1B D5  ...&鍯.?
0043E610  EA 43 00 27 00 14 19 1B 40 00 00 00 14 19 19 1B  闏.'.@...
0043E620  06 00 00 00 02 1C 1B 01 00 00 00 1B 00 00 00 00  ..........
0043E630  26 01 04 00 18 1B 00 00 00 00 17 17 0E 1E F4 10  &.....?
0043E640  F4 12 14 19 0F 57 12 14 19 19 10 F4 12 0F 57 12  ?W?W
0043E650  19 05 19 16 1E F4 01 03 00 10 F4 12 0F 1B 12 05  ?.?
0043E660  09 16 01 04 00 1B 82 E6 43 00 1B D5 EA 43 00 27  ..傛C.贞C.'
0043E670  00 14 19 1B 40 00 00 00 14 19 19 1B 06 00 00 00  .@......
0043E680  02 1C 1B 01 00 00 00 1B 00 00 00 00 26 01 04 00  .......&.
0043E690  18 1B 01 00 00 00 17 17 0E 1E FC 10 FC 12 14 19  ...??
0043E6A0  0F 6F 12 14 19 19 10 FC 12 0F 6F 12 19 05 19 16  o?o

通过分析大致流程如下(一般是通过脚本自动分析的)
0F  vm_push_imm8                                'W'
...
19  vm_nand32(nand(sn), nand(W))         xor
...
0F  vm_push_imm8                                 1B
...
09  vm_sub_32
...

通过vm_code 不断定位 0F可
最后得出 (sn) xor (WoJiuShiZheMe) == 1B0602081C1F0D3E352C000A00
sn=LiHaiLeWoDeGe

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

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回