软件分析的敲门砖VM技术入门

现在的软件除了加上加密狗外,在加加密狗前还加了一层保护壳,如果想对加密狗分析,就得清楚这层壳的分析,不然对有壳的软件很难进行下去。加壳程序是从TLS开始运行的,我们首先点击OD的options菜单,修改Startup and exit选项,让OD中断在TLS callback里。加壳程序运行后,VMP初始化VM,并进入DISPATCH部分。这里我们就以初始化后的堆栈为例。
VM的堆栈一共使用61个DWORD,上下分别有2个堆栈指针,下面为EBP指针,上面为EDI指针。下面是VM初始化时,给EDI和EBP指针赋值后的堆栈。
EDI=0013F8BC
EBP=0013F9B0
CPU Stack
Locked    Value      ASCII Comments
0013F8BC   009539E8  9.                                        ;这里是EDI指向
0013F8C0   00950000  …
0013F8C4   00150000  …
0013F8C8   00000080  …
0013F8CC   019314D6  
0013F8D0   0013F8A8  .
0013F8D4   7C92E920   |
0013F8D8   00000000  ….
0013F8DC   00000000  ….
0013F8E0   00000000  ….
0013F8E4   FFFFFFFF
0013F8E8   7C98FEFF  |     
0013F8EC   7C00ADE7  .|
0013F8F0   00000000  ….
0013F8F4   00150000  …
0013F8F8   0013F6F0  .
0013F8FC   0013F940  @.
0013F900   0013F944  D.
0013F904   7C92E920   |
0013F908   7C9301E0  |
0013F90C   FFFFFFFF
0013F910   7C9301DB  |    
0013F914   7C9314D6  |    
0013F918   7C931514  |   
0013F91C   7C99E120   |
0013F920   7C9314EA  |    
0013F924   5ADF1158  XZ
0013F928   00000001  …
0013F92C   00000000  ….
0013F930   7FFDA000  .
0013F934   7FFDF000  .
0013F938   00158070  p.
0013F93C   0013F890  .
0013F940   00000000  ….
0013F944   0043D759  YC.   
0013F948   0000E9ED  ..
0013F94C   409B0002  .@
0013F950   00000020   …
0013F954   0013F9CC  .
0013F958   0013F96C  l.
0013F95C   0043E9ED  C.    
0013F960   000359F4  Y.
0013F964   00000020   …
0013F968   004253CD  SB.   
0013F96C   409B0000  ..@
0013F970   00000020   …
0013F974   0013F9CC  .
0013F978   0013F98C  .
0013F97C   00000000  ….                                        ;这里是EBP指向
0013F980   00000000  ….                                        ;这里是VM初始化保存的各个寄存器
0013F984   00000246  F..
0013F988   000359F4  Y.
0013F98C   00000020   …
0013F990   00000000  ….
0013F994   0013F9CC  .
0013F998   004253CD  SB.   
0013F99C   000359F4  Y.
0013F9A0   00400000  ..@.  
0013F9A4   0013F9C0  .
0013F9A8   C456C619  V                                        ;这里是VMP的2个加密数据
0013F9AC   2EF6420A  .B.
0013F9B0   7C92118A  |    ; RETURN to ntdll.7C92118A        ;这里是TLS进来时的栈顶
关于2个加密数据和初始化的过程我们后续来说,这里我们主要关注VM的堆栈划分。
我把上面的EDI指向的堆栈称为EDISTACK,把EBP指向的堆栈称为EBPSTACK。在VM中,EBPSTACK是运算区,各类数据的运算操作在这里完成;EDISTACK是存储区包括长期存储数据和临时存储EBPSTACK的运算数。
下面我们来看一条数据移动伪指令:
命名:
VM_MOVdw_EDISTACKdw_EBPSTACKdw
代码:
0043DC19  |.  F6D8          NEG AL                                   ; *
0043DC26  |.  C0C8 07       ROR AL,7                                 ; *
0043DC34  |.  2C 20         SUB AL,20                                ; *
0043DC41  |.  24 3C         AND AL,3C                                ; *

0043E080  |$  8B55 00       MOV EDX,DWORD PTR SS:[EBP]               ; *
0043E086  |.  83C5 04       ADD EBP,4                                ; *

0043D3D7  /> /891438        MOV DWORD PTR DS:[EDI+EAX],EDX           ; *
功能:
把1个dword的数据从EBPSTAK栈顶移动到EDISTACK,使用EAX作为偏移量

在EDISTACK的数据移动中,使用[EDI+EAX]的方式来存储与获取各个值。通过计算不同的EAX的值,可以到达EDISTACK中不同位置。在计算EAX值时,实际真正计算的是AL的值,我们来考虑一下AL的最小值和最大值,AL=00时[EDI+EAX]=[0013F8BC+00000000]=0013F8BC,AL=FF时[EDI+EAX]=[0013F8BC+000000FF]=0013F9BB,这是使用[EDI+EAX]可以读取的上下限。但是,在VM的AL值计算过程中,最后有一条AND AL,0x3C指令,0x3C=00111100bit由于这条指令的限制,无论AL为任何值(从00000000bit到11111111bit),通过AND操作,只能有1111bit的活动空间大小,1111bit相当于16,所以EDISTACK最多可以读取16个dword;由于00111100bit最后两个00位的限制,任何数字与它AND后,后两位都必然为0,变成与4对齐的值,说明VM都是按照0013F8BC 0013F8C0 0013F8C4 0013F8C8这样的4对齐来读取。在读取时,VM可以读取byte word dword,但是VM将不会去读取0013F8BE。
由于EDISTACK堆栈向下发展,EBPSTACK堆栈向上发展,EDISTACK有0x3C控制着范围,而EBPSTACK是操作区,没有硬性的范围控制。为了预防两个空间相撞,在每次往EBPSTACK移动数据后,VM都有相应的边界检测指令如下:
0043CE5A  |.  8D47 50       LEA EAX,[EDI+50]                         ; *
0043EE5D  |.  39C5          CMP EBP,EAX                              ; *
0043F08C  |.^\0F87 29F6FFFF JA 0043E6BB                              ; * 
比较结果 大于 ,这个正常的情况,在这个VM跟踪过程中,我没有发现一次小于的情况。如果小于,也就是EBPSTACK栈顶已经到达[EDI+50]位置,VM将会重新分配堆栈空间。0x50的偏移量比0x3C的偏移量多5个dword的缓冲区。我们来手动修改EBP指针,看看VM的对于两个堆栈空间即将相撞的处理情况:
CPU Disasm
Address   Hex dump          Command                                  Comments
0043F092  |.  52            PUSH EDX                                 ; 
0043D6C1  |.  8D5424 08     LEA EDX,[ARG.2]                          ; *EDX获得的是原来EDI指针地址0013F8BC
0043DF38  |.  8D4F 40       LEA ECX,[EDI+40]                         ; *0x40的偏移量是0x3C的偏移量数据1个dword结束后的位置
0043DF46  |.  29D1          SUB ECX,EDX                              ; *减法计算出数据存储量
0043DF4B  |.  8D45 80       LEA EAX,[EBP-80]                         ; *增加0x80的空间
0043DF5C  |.  24 FC         AND AL,FC                                ; *按4对齐
0043DF68  |.  29C8          SUB EAX,ECX                              ; *在增加原来数据大小的堆栈空间
0043DF6E  |.  89C4          MOV ESP,EAX                              ; *
0043DF7E  |.  56            PUSH ESI                                 ; |Arg1 = NOTEPAD.425748, *
0043DF87  |.  89D6          MOV ESI,EDX                              ; |*
0043DB3A  /$  8D7C01 C0     LEA EDI,[EAX+ECX-40]                     ; *
0043EC1E   .  89C7          MOV EDI,EAX                              ; *
0043EEED  |.  F3:A4         REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ ; *移动原来EDISTACK中存储的数据
0043EEF7  |.  8B7C24 10     MOV EDI,DWORD PTR SS:[ESP+10]            ; *
0043EEFF  |.  8B7424 10     MOV ESI,DWORD PTR SS:[ESP+10]            ; *
这里我们可以看到,每次发现两个堆栈空间即将相撞,VM都重新给EBP分配堆栈,并把原来EDISTACK存储的数据移动到新的空间内。
下面是使用OD跟踪VM堆栈的几个小技巧:
在OD中跟踪VM数据移动时,双击0013F8BC地址,OD将会以0013F8BC为基址,显示上下各个地址与它的偏移量,如图:
CPU Stack
Locked    Value      ASCII Comments
$-C        759D0000  ..u
$-8        00000001  …
$-4        0013F8FC  .
$ ==>      009539E8  9.                                        ;这里是0013F8BC,双击后的效果
$+4        00950000  …
$+8        00150000  …
$+C        00000080  …
$+10       019314D6  
   在跟踪VM时,在数据移动伪指令中的AND AL,0x3C的下一条指令下断点,这样每次进行数据移动,你都可以在这个断点看到,数据的去向和来源,这是极其有用的。在很多复杂的运算地方,你需要在草稿纸上记下,EDISTACK中一些空间的数据时来自于什么时候?比如标志位ZF检测+跳转是VM的一个重要操作,而EFLAGS标志数都是相差不多或类似的00000286 00000246等等,如果你不能准确知道[EDI+EAX]存储或读取的位置,你将无法理解VM的操作。这非常的重要,请牢记!必要时连OD得数据窗口也一起配合显示VM堆栈把OD里的堆栈窗口拉高,让它竟可能多的显示数据,在高分辨率的电脑上,最好是能够显示出整个VM的堆栈。默认情况下,堆栈窗口是随着ESP指针的变化而自动显示的,这对于我们要时刻盯着VM堆栈的需求不相符,在堆栈窗口–>右键–>Lock address 打钩,这样OD就会锁定堆栈窗口。

这些基本的操作在对加密狗破解是非常用的,有时对加密狗复制都需要用到,所以学好OD软件是非常好的一件事情。

相关推荐

发表评论

您的电子邮箱地址不会被公开。

QQ点我咨询