3.NOTEPAD全程跟踪
在这一章里,我们将全过程浏览NOTEPAD.EXE文件。本章显示的代码,外壳的花指令将全部跳过,VM的伪指令则部份跳过。
3.1.TLS
3.1.1.到达Dispatch部份
VMProtect2.04加壳程序是从TLS开始运行的,我们首先点击OD的options菜单,修改Startup and exit选项,让OD中断在TLS callback里。载入NOTOPAD.EXE后,程序停在这里:
004253CD $ 68 9AA597B7 PUSH B797A59A ; TLS callback function
当前的寄存器值:
EAX 004253CD NOTEPAD.004253CD
ECX 00000020
EDX 000359F4
EBX 00000000
ESP 0013F9B0
EBP 0013F9CC
ESI 0013F9C0
EDI 00400000 NOTEPAD.
进入VM之前,VMP要保存当前的各个寄存器值,VM堆栈要分配,同时给伪指令指针寄存器ESI赋值等等,初始化结束后,进入Dispatch部份VM开始运行。F7单步下去:
0043BD02 . C74424 40 0A4 MOV DWORD PTR SS:[ESP+40],2EF6420A ; |*
00429088 |> \C74424 44 19C MOV DWORD PTR SS:[ARG.17],C456C619 ; *
;压入VM的两个定量。
0043DCD2 |. 893424 MOV DWORD PTR SS:[ESP],ESI ; *
0043CF0D . 57 PUSH EDI ; *
0043CF17 . 891424 MOV DWORD PTR SS:[ESP],EDX ; *
0043CF1D . 50 PUSH EAX ; *
0043E17A |. 896C24 04 MOV DWORD PTR SS:[ARG.1],EBP ; *
0043D741 |> /871C24 XCHG DWORD PTR SS:[ESP],EBX ; *
0043D746 |. 894C24 20 MOV DWORD PTR SS:[ESP+20],ECX ; *
;7个寄存器保存完毕
0043D750 |. 875424 40 XCHG DWORD PTR SS:[ESP+40],EDX ; |Arg17, *
0043E62E /$ 9C PUSHFD ; *
0043E62F |. 8F4424 40 POP DWORD PTR SS:[ESP+40] ; *
0043E636 |. FF35 89D24300 PUSH DWORD PTR DS:[43D289] ; *
0043E63C |. 8F4424 3C POP DWORD PTR SS:[ESP+3C] ; *
0043E646 |. C74424 38 000 MOV DWORD PTR SS:[ESP+38],0 ; *
;多保存1个寄存器,由于ESP是动态的,这个位置相当于是ESP寄存器的位置;EFLAGS;内存地址[43D289];常量0;一共保存13个数据
0013F97C 00000000 .... ;常量0 20
0013F980 00000000 .... ;[43D289] 24 8121D2F0相加
0013F984 00000246 F.. ;EFLAGS 0C
0013F988 000359F4 Y. ;EDX(给ESP寄存器的位置) 00
0013F98C 00000020 ... ;ECX 08
0013F990 00000000 .... ;EBX 1C
0013F994 0013F9CC . ;EBP 28
0013F998 004253CD SB. ;EAX 10
0013F99C 000359F4 Y. ;EDX 2C
0013F9A0 00400000 ..@. ;EDI 30
0013F9A4 0013F9C0 . ;ESI 38
0013F9A8 C456C619 V ;常量B 3C
0013F9AC 2EF6420A .B. ;常量A 18
0013F9B0 7C92118A | ; RETURN to ntdll.7C92118A
0043E65B |. 8B7424 68 MOV ESI,DWORD PTR SS:[ESP+68] ; *
;这里读取的是常量A=2EF6420A,以下是解密2EF6420A的过程:
0043E665 |. 0FCE BSWAP ESI ; *
0043E66E |. 4E DEC ESI ; *
0043E67D |. 81F6 63A1000A XOR ESI,0A00A163 ; *
;结束,ESI=0042574E,这里就是VM的指令序列
0043E68C |. 8D6C24 34 LEA EBP,[ESP+34]
0043E692 |. 81EC 8C000000 SUB ESP,8C ; *
0043E69C |. 89E7 MOV EDI,ESP ; *
;第一条指令EBP取得的地址是0013F97C的位置,也就是13个保存数据的结束地址,要在这个的基础上分配VM堆栈
;保存的13个dword=34byte,ESP在执行减法前,位于0013F9FC的34个byte位置,减法分配8Cbyte;34+34+8C=F4byte=61dword
;VM堆栈的详细分析请查阅1.2.VM堆栈
0043E6A9 |. 89F3 MOV EBX,ESI ; *
;EBX是VM解密数据的辅运算寄存器,初始化为VM的指令序列地址0042574E
0043E6B8 |. 0375 00 ADD ESI,DWORD PTR SS:[EBP] ; *
;ESI的地址还要和常量0相加,相加会改变VM指令序列的地址,决定VM第一次运行后要执行的指令
;常量0可以看作是VM内部的一个修正量,在NOTEPAD里它是0
到这里,一切初始化完成,程序已经到达Dispatch(调遣)部份。整个过程概括为:保存数据、分配VM堆栈、给ESI赋值。下一条指令就是所有伪指令执行完成后的返回地址0043E6BB。
0043E6BB |> >66:0FA5FA SHLD DX,DI,CL ; Dispatch 花指令,没有什么意义
3.1.2.Dispatch部份解析
下面是第1条伪指令的获取过程:
0043E6BF |. 8A46 FF MOV AL,BYTE PTR DS:[ESI-1] ; *
;开始读取伪指令序列号,以下是解密伪指令序列号C0的过程:
0043E6C4 |. 30D8 XOR AL,BL
0043E6CE |. F6D0 NOT AL ; *
0043E6D6 |. FEC8 DEC AL ; *
0043E6DA |. C0C8 07 ROR AL,7 ; *
;结束,AL=E0,它将用于在DispatchTable(调遣表)中定位出伪指令地址。
0043E6E1 |. 83EE 01 SUB ESI,1 ; *
0043E6ED |. 30C3 XOR BL,AL ; *
;指令序列减1,计算好下一次BL的值
0043D02F |. 0FB6C0 MOVZX EAX,AL ; *
0043F124 |. 8B1485 DBE143 MOV EDX,DWORD PTR DS:[EAX*4+43E1DB] ; *
;取出伪指令地址49C4C29F,以下是解密49C4C29F的过程:
;DispatchTable的详细分析请查阅1.3.伪指令汇总
0043E100 |> /81C2 6B197FB6 ADD EDX,B67F196B ; *
;只有1条解密指令,加上常量B67F196B,EDX=0043DC0A
0043E10A |. 895424 3C MOV DWORD PTR SS:[ESP+3C],EDX ; *
0043E11B |. FF7424 4C PUSH DWORD PTR SS:[ESP+4C] ; *
0043E11F |. C2 5000 RETN 50 ; Enter
;由于是使用RET指令来跳转,需要使用到真实堆栈指针ESP,在暂存EDX地址时,VM使用的空间是EDISTACK的上一个位置:
0013F8B8 0043DC0A .C. ; RETURN from NOTEPAD.0043D5C7 to NOTEPAD.0043DC0A
0013F8BC 00953F38 8?. ;这里是EDISTACK的上限
到这里,VM将进入执行第一条伪指令。整个过程:初始化、从ESI指针获得伪指令序列号、从DispatchTable获得伪指令地址、跳转执行伪指令。Dispatch部份是VM中将会不断重复重复再重复的执行,所有的伪指令完毕后,都是返回到这里获得下一条伪指令。
3.1.3.anti方式初现
通过前面章节的介绍,在这一节里,我将对NOTEPAD从TLS回调函数到TLS退出进行一次概论。这个过程将不再出现任何的x86指令代码,前面介绍的伪指令组合和相关内容将会被缩短和链接后跳过。
1.初始化(请查阅3.1.初始化)
NOTEPAD在TLS回调函数中断后,经过初始化过程后,开始执行伪指令。VM将会把所有EBPSTACK中带过来的13个初始化保留数据暂存至EDISTACK。
2.ESI数据0000与[00427D51]=0000进行比较+跳转(请查阅2.3.1.判断相同)
3.VMP将根据PE文件结构读取出程序入口的第一个字节进行CC码检测。VM会去到另外的堆栈空间操作整个过程,把ESP指针从0013F994-40=0013F954,在开头构建2个0013F954进行NAND(A,A)中,和前面稍有不同,这里不再详述。过程:
0013F994-40=0013F954
MOV EBP,0013F954
0013F988 0013F994 .
0013F98C 0013F994 .
0013F990 00000040 @...
0013F994 0013F9C0 . ;计算前的EBP指针
VM_NANDdw
0013F98C FFEC066B k
0013F990 00000040 @...
0013F994 0013F9C0 .
VM_ADDdw_EBPSTACK
0013F990 FFEC06AB
0013F994 0013F9C0 .
VM_PUSHdw_EBP
VM_COPYw_EBPSTACK
0013F98C FFEC06AB
0013F990 FFEC06AB
0013F994 0013F9C0 .
VM_NANDdw
0013F990 0013F954 T.
0013F994 0013F9C0 .
VM_MOVdw_EBPreg_EBPSTACK
EBP 0013F954
堆栈移动到0013F954后,
VM_PUSHdw_IMMEDIATEdw ;压入00427D51
开始从程序的入口地址根据PE文件格式定位:
VM_PUSHdw_IMMEDIATEdw ;压入00400000,NOTEPAD程序的文件头地址,OD数据窗口跟踪
00400000 4D 5A 90 00|03 00 00 00|04 00 00 00|FF FF 00 00| MZ.........
00400010 B8 00 00 00|00 00 00 00|40 00 00 00|00 00 00 00| .......@.......
00400020 00 00 00 00|00 00 00 00|00 00 00 00|00 00 00 00| ................
00400030 00 00 00 00|00 00 00 00|00 00 00 00|80 00 00 00| ...............
00400040 0E 1F BA 0E|00 B4 09 CD|21 B8 01 4C|CD 21 54 68| ..!L!Th
00400050 69 73 20 70|72 6F 67 72|61 6D 20 63|61 6E 6E 6F| is program canno
00400060 74 20 62 65|20 72 75 6E|20 69 6E 20|44 4F 53 20| t be run in DOS
00400070 6D 6F 64 65|2E 0D 0D 0A|24 00 00 00|00 00 00 00| mode....$.......
00400080 50 45 00 00|4C 01 09 00|65 91 46 35|00 00 00 00| PE..L..eF5....
00400090 00 00 00 00|E0 00 0F 01|0B 01 03 0A|00 F0 03 00| .....
004000A0 00 74 00 00|00 00 00 00|17 78 03 00|00 10 00 00| .t......x....
004000B0 00 50 00 00|00 00 40 00|00 10 00 00|00 10 00 00| .P....@.......
004000C0 04 00 00 00|00 00 00 00|04 00 00 00|00 00 00 00| ..............
004000D0 00 50 04 00|00 04 00 00|CE 59 03 00|02 00 00 00| .P....Y....
004000E0 00 00 10 00|00 10 00 00|00 00 10 00|00 10 00 00| ............
004000F0 00 00 00 00|10 00 00 00|FC 1D 02 00|50 0C 00 00| ........P...
00400100 18 66 03 00|A0 00 00 00|00 00 04 00|00 50 00 00| f........P..
00400110 00 00 00 00|00 00 00 00|00 00 00 00|00 00 00 00| ................
00400120 00 00 00 00|00 00 00 00|00 00 00 00|00 00 00 00| ................
00400130 00 00 00 00|00 00 00 00|00 00 00 00|00 00 00 00| ................
00400140 F4 59 03 00|20 00 00 00|00 00 00 00|00 00 00 00| Y. ...........
00400150 00 00 00 00|00 00 00 00|B0 7D 03 00|4C 00 00 00| ........}.L...
00400160 00 00 00 00|00 00 00 00|00 00 00 00|00 00 00 00| ................
00400170 00 00 00 00|00 00 00 00|2E 74 65 78|74 00 00 00| .........text...
00400180 9C 3E 00 00|00 10 00 00|00 00 00 00|00 00 00 00| >.............
00400190 00 00 00 00|00 00 00 00|00 00 00 00|20 00 00 60| ............ ..`
004001A0 2E 64 61 74|61 00 00 00|4C 08 00 00|00 50 00 00| .data...L...P..
004001B0 00 00 00 00|00 00 00 00|00 00 00 00|00 00 00 00| ................
004001C0 00 00 00 00|40 00 00 C0|2E 69 64 61|74 61 00 00| ....@...idata..
004001D0 E8 0D 00 00|00 60 00 00|00 00 00 00|00 00 00 00| ....`..........
004001E0 00 00 00 00|00 00 00 00|00 00 00 00|40 00 00 40| ............@..@
004001F0 2E 76 6D 70|31 00 00 00|B8 4F 00 00|00 70 00 00| .vmp1...O...p..
00400200 00 50 00 00|00 10 00 00|00 00 00 00|00 00 00 00| .P.............
00400210 00 00 00 00|60 00 00 60|2E 76 6D 70|30 00 00 00| ....`..`.vmp0...
00400220 9C 0A 00 00|00 C0 00 00|00 00 00 00|00 00 00 00| ..............
00400230 00 00 00 00|00 00 00 00|00 00 00 00|60 00 00 60| ............`..`
00400240 2E 76 6D 70|32 00 00 00|A0 FD 00 00|00 D0 00 00| .vmp2........
00400250 00 00 00 00|00 00 00 00|00 00 00 00|00 00 00 00| ................
00400260 00 00 00 00|20 00 00 20|2E 74 6C 73|00 00 00 00| .... .. .tls....
00400270 18 00 00 00|00 D0 01 00|00 10 00 00|00 60 00 00| .........`..
00400280 00 00 00 00|00 00 00 00|00 00 00 00|00 00 00 C0| ...............
00400290 2E 76 6D 70|33 00 00 00|85 11 02 00|00 E0 01 00| .vmp3......
004002A0 00 20 02 00|00 70 00 00|00 00 00 00|00 00 00 00| . ..p..........
004002B0 00 00 00 00|20 00 00 E2|2E 72 73 72|63 00 00 00| .... ...rsrc...
004002C0 B0 4F 00 00|00 00 04 00|00 50 00 00|00 90 02 00| O......P....
004002D0 00 00 00 00|00 00 00 00|00 00 00 00|40 00 00 40| ............@..@
004002E0 00 00 00 00|00 00 00 00|00 00 00 00|00 00 00 00| ................
004002F0 00 00 00 00|00 00 00 00|00 00 00 00|00 00 00 00| ................
00400300 00 00 00 00|00 00 00 00|00 00 00 00|00 00 00 00| ................
00400310 00 00 00 00|00 00 00 00|00 00 00 00|00 00 00 00| ................
00400320 00 00 00 00|00 00 00 00|00 00 00 00|00 00 00 00| ................
00400330 00 00 00 00|00 00 00 00|00 00 00 00|00 00 00 00| ................
00400340 00 00 00 00|00 00 00 00|00 00 00 00|00 00 00 00| ................
..........................................................................
0013F94C 0000003C <...
0013F950 00400000 ..@. ; OFFSET NOTEPAD. ;DOS_header_addr
VM_ADDdw_EBPSTACK
0013F950 0040003C <.@. ;e_magic
VM_PUSHdw_MEMORYdw
0013F950 00000080 ...
取得e_magic的数值,获取PE文件头位置
0013F94C 00000080 ...
0013F950 00400000 ..@. ; OFFSET NOTEPAD
VM_ADDdw_EBPSTACK
0013F950 00400080 .@. ; ASCII "PE" ;IMAGE_NT_HEADERS
0013F94C 00400080 .@. ; ASCII "PE"
0013F950 00000028 (...
VM_ADDdw_EBPSTACK
0013F950 004000A8 .@. ;AddressOfEntryPoint
VM_PUSHdw_MEMORYdw
0013F950 00037817 x.
PE文件头28偏移量的位置是属于IMAGE_OPTIONAL_HEADER32结构的AddressOfEntryPoint字段,程序执行入口RVA00037817
0013F94C 00037817 x.
0013F950 00400000 ..@. ; OFFSET NOTEPAD
VM_ADDdw_EBPSTACK
0013F950 00437817 xC. ; NOTEPAD.
现在已经获得NOTEPAD的程序执行入口地址
VM_PUSHw_IMMEDIATEb
0013F950 00CC
0013F94C 7817
0013F950 00CC0043 C..
VM_PUSHw_MEMORYb
0013F950 00CC0068 h..
从执行入口地址读取字节和CC进行比较,我没有在入口地址下INT3断点,取得的字节是68,接下来VMP进行减法和标志位ZF检测,这里不再复述,在VM_JMP组合执行完毕后,恢复EBPSTACK重新回到0013F994。
4.IF标志位置1
VM使用NAND进行1次AND操作,AND操作数的一个是700,截取的是DF,IF,TF位,另一个操作数是246,这样保留的就是Interrupt Enable Flag(IF)位。最后通过伪指令VM_MOVdw_EFLreg_EBPSTACK把结果压入EFlags寄存器。
0013F9A8 00000246 F..
0013F9AC 00000246 F..
0013F9B0 7C92118A | ; RETURN to ntdll.7C92118A
VM_NANDdw
0013F9AC FFFFFDB9
0013F9B0 7C92118A | ; RETURN to ntdll.7C92118A
VM_PUSHdw_IMMEDIATEw
0013F9A8 000008FF ..
0013F9AC FFFFFDB9
0013F9B0 7C92118A | ; RETURN to ntdll.7C92118A
VM_NANDdw
0013F9AC 00000200 ...
0013F9B0 7C92118A | ; RETURN to ntdll.7C92118A
VM_MOVdw_EFLreg_EBPSTACK
3.1.4.TLS退出
0013F990 8021D2F0 !
0013F994 8021D2F0 !
0013F998 00000246 F..
0013F99C F6F93A39 9:
0013F9A0 00000020 ...
0013F9A4 00000000 ....
0013F9A8 0013F994 .
0013F9AC 004253CD SB. ; RETURN from NOTEPAD.004255DB to NOTEPAD.004253CD
0013F9B0 000359F4 Y.
0013F9B4 00400000 ..@. ; OFFSET NOTEPAD.B
0013F9B8 0013F9C0 .
0013F9BC 7C92118A | ; RETURN to ntdll.7C92118A
VM_EXIT
程序返回进入7C92118A,程序要从TLS中返回,我们去开始地址00437817地址下断点,在程序执行地址拦截下程序。
7C92118A 8BE6 MOV ESP,ESI
7C92118C 5B POP EBX
7C92118D 5F POP EDI
7C92118E 5E POP ESI
7C92118F 5D POP EBP
7C921190 C2 1000 RETN 10