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賦值等等,初始化結(jié)束后,進入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是動態(tài)的,這個位置相當于是ESP寄存器的位置;EFLAGS;內(nèi)存地址[43D289];常量0;一共保存13個數(shù)據(jù)
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 ; *
;結(jié)束,ESI=0042574E,這里就是VM的指令序列
0043E68C |. 8D6C24 34 LEA EBP,[ESP+34]
0043E692 |. 81EC 8C000000 SUB ESP,8C ; *
0043E69C |. 89E7 MOV EDI,ESP ; *
;第一條指令EBP取得的地址是0013F97C的位置,也就是13個保存數(shù)據(jù)的結(jié)束地址,要在這個的基礎(chǔ)上分配VM堆棧
;保存的13個dword=34byte,ESP在執(zhí)行減法前,位于0013F9FC的34個byte位置,減法分配8Cbyte;34+34+8C=F4byte=61dword
;VM堆棧的詳細分析請查閱1.2.VM堆棧
0043E6A9 |. 89F3 MOV EBX,ESI ; *
;EBX是VM解密數(shù)據(jù)的輔運算寄存器,初始化為VM的指令序列地址0042574E
0043E6B8 |. 0375 00 ADD ESI,DWORD PTR SS:[EBP] ; *
;ESI的地址還要和常量0相加,相加會改變VM指令序列的地址,決定VM第一次運行后要執(zhí)行的指令
;常量0可以看作是VM內(nèi)部的一個修正量,在NOTEPAD里它是0
到這里,一切初始化完成,程序已經(jīng)到達Dispatch(調(diào)遣)部份。整個過程概括為:保存數(shù)據(jù)、分配VM堆棧、給ESI賦值。下一條指令就是所有偽指令執(zhí)行完成后的返回地址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 ; *
;結(jié)束,AL=E0,它將用于在DispatchTable(調(diào)遣表)中定位出偽指令地址。
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指令來跳轉(zhuǎn),需要使用到真實堆棧指針ESP,在暫存EDX地址時,VM使用的空間是EDISTACK的上一個位置:
0013F8B8 0043DC0A .C. ; RETURN from NOTEPAD.0043D5C7 to NOTEPAD.0043DC0A
0013F8BC 00953F38 8?. ;這里是EDISTACK的上限
到這里,VM將進入執(zhí)行第一條偽指令。整個過程:初始化、從ESI指針獲得偽指令序列號、從DispatchTable獲得偽指令地址、跳轉(zhuǎn)執(zhí)行偽指令。Dispatch部份是VM中將會不斷重復重復再重復的執(zhí)行,所有的偽指令完畢后,都是返回到這里獲得下一條偽指令。
3.1.3.anti方式初現(xiàn)
通過前面章節(jié)的介紹,在這一節(jié)里,我將對NOTEPAD從TLS回調(diào)函數(shù)到TLS退出進行一次概論。這個過程將不再出現(xiàn)任何的x86指令代碼,前面介紹的偽指令組合和相關(guān)內(nèi)容將會被縮短和鏈接后跳過。
1.初始化(請查閱3.1.初始化)
NOTEPAD在TLS回調(diào)函數(shù)中斷后,經(jīng)過初始化過程后,開始執(zhí)行偽指令。VM將會把所有EBPSTACK中帶過來的13個初始化保留數(shù)據(jù)暫存至EDISTACK。
2.ESI數(shù)據(jù)0000與[00427D51]=0000進行比較+跳轉(zhuǎn)(請查閱2.3.1.判斷相同)
3.VMP將根據(jù)PE文件結(jié)構(gòu)讀取出程序入口的第一個字節(jié)進行CC碼檢測。VM會去到另外的堆?臻g操作整個過程,把ESP指針從0013F994-40=0013F954,在開頭構(gòu)建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
開始從程序的入口地址根據(jù)PE文件格式定位:
VM_PUSHdw_IMMEDIATEdw ;壓入00400000,NOTEPAD程序的文件頭地址,OD數(shù)據(jù)窗口跟蹤
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的數(shù)值,獲取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結(jié)構(gòu)的AddressOfEntryPoint字段,程序執(zhí)行入口RVA00037817
0013F94C 00037817 x.
0013F950 00400000 ..@. ; OFFSET NOTEPAD
VM_ADDdw_EBPSTACK
0013F950 00437817 xC. ; NOTEPAD.
現(xiàn)在已經(jīng)獲得NOTEPAD的程序執(zhí)行入口地址
VM_PUSHw_IMMEDIATEb
0013F950 00CC
0013F94C 7817
0013F950 00CC0043 C..
VM_PUSHw_MEMORYb
0013F950 00CC0068 h..
從執(zhí)行入口地址讀取字節(jié)和CC進行比較,我沒有在入口地址下INT3斷點,取得的字節(jié)是68,接下來VMP進行減法和標志位ZF檢測,這里不再復述,在VM_JMP組合執(zhí)行完畢后,恢復EBPSTACK重新回到0013F994。
4.IF標志位置1
VM使用NAND進行1次AND操作,AND操作數(shù)的一個是700,截取的是DF,IF,TF位,另一個操作數(shù)是246,這樣保留的就是Interrupt Enable Flag(IF)位。最后通過偽指令VM_MOVdw_EFLreg_EBPSTACK把結(jié)果壓入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中返回,我們?nèi)ラ_始地址00437817地址下斷點,在程序執(zhí)行地址攔截下程序。
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