原創|其它|編輯:郝浩|2012-11-07 17:06:33.000|閱讀 1153 次
概述:VMProtect的VM是基于堆棧的虛擬家,理解好VM的堆棧空間劃分和操作,是理解整個VM運行的基礎。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關鏈接:
代碼保護利器VMProtect在線訂購315特惠,個人授權專享折扣立即購買>>
VMProtect的VM是基于堆棧的虛擬家,理解好VM的堆棧空間劃分和操作,是理解整個VM運行的基礎。VMProtect2.12加殼程序是從TLS開始運行的,首先點擊OD的options菜單,修改Startup and exit選項,讓OD中斷在TLS callback里。加殼程序運行后,VMP初始化VM,并進入DISPATCH部分。這里就以初始化后的堆棧為例。
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進來時的棧頂)
VM的堆棧一共使用61個DWORD,上下分別有2個堆棧指針,下面為EBP指針,上面為EDI指針。下面是VM初始化時,給EDI和EBP指針賦值后的堆棧。
在這里把上面的EDI指向的堆棧稱為EDISTACK,把EBP指向的堆棧稱為EBPSTACK。在VM中,EBPSTACK是運算區,各類數據的運算操作在這里完成;EDISTACK是存儲區包括長期存儲數據和臨時存儲EBPSTACK的運算數。
接下來來看一條數據移動偽指令:
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最小值: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
執行此指令后得到的結果是“>”,如果是“<”, 也就是EBPSTACK棧頂已經到達[EDI+50]位置,VM將會重新分配堆棧空間。0x50的偏移量比0x3C的偏移量多5個dword的緩沖區。
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn