轉帖|使用教程|編輯:胡濤|2022-04-12 14:44:52.467|閱讀 291 次
概述:本文主要向您介紹VMProtect虛擬機保護分析入門,歡迎查閱!
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
虛擬機入口
00952380 | 68 95514200 | push 425195 | 00952385 | E8 FC220100 | call testvmp.vmp.964686 |
經過對后面的流程進行分析,得知這里的425195在虛擬機跳轉銜接上起到了關鍵的作用。VMP為了防止逆向分析的一個重要的干擾就是亂序,運行幾行匯編就各種jump,VMP使用的jump方法是JXX指令和CALL,RET來進行。
如下代碼使用了push和ret組合實現跳轉:
00963A35 | FF7424 34 | push dword ptr ss:[esp+34] | 00963A39 | C2 3800 | ret 38 |
上面的這段代碼,假如不知道[esp+34]的值,不知道會跳轉到哪里。所以靜態分析工具例如ida是就無法分析。然而425195這個值充當了一個Key的作用。VMP巧妙的運用這個值來進行實時計算要跳轉的地方。
單步進入就會看到虛擬機初始化的代碼。
初始化充斥著許多垃圾指令,注意看注釋。
push 45FFB40D mov byte ptr ss:[esp],C0 call testvmp.vmp.962149 mov dword ptr ss:[esp+4],edx mov byte ptr ss:[esp],22 pushfd mov dword ptr ss:[esp+4],edi jmp testvmp.vmp.9633F4 mov word ptr ss:[esp],cx mov dword ptr ss:[esp],eax pushad jmp testvmp.vmp.9641DB pushfd mov dword ptr ss:[esp+20],esi call <testvmp.vmp.sub_963725> mov dword ptr ss:[esp+20],ebx mov dword ptr ss:[esp+8],5870296F mov dword ptr ss:[esp+1C],eax pushfd push esi 保存寄存器ESI pushfd pop dword ptr ss:[esp+20] push A9CEAE65 pushad push dword ptr ss:[esp+4] mov byte ptr ss:[esp],49 lea esp,dword ptr ss:[esp+48] 彈棧 jmp testvmp.vmp.9636DA bt ax,3 bswap di cmc and dh,dh push ebp 保存寄存器EBP xadd si,di movsx bp,al not edi push ecx 保存寄存器ECX ror esi,5 clc push dword ptr ds:[962430] inc si push 540000 這個值與之前PUSH來的KEY共同計算指令handle下一跳地址 jmp testvmp.vmp.963343 test cl,F7 rcr si,cl pushad mov esi,dword ptr ss:[esp+50] sbb ebp,23A52066 ror di,1 lea ebp,dword ptr ss:[esp+20] sar di,cl bsr dx,bp inc edi sub esp,A0 分配棧空間 shl dh,6 ror dx,cl dec edi mov al,dl mov edi,esp VM寄存器指針 push ebx call testvmp.vmp.964391 bswap edx add esi,dword ptr ss:[ebp] 重定位 add esp,8
經過我對剛才加殼的代碼進行多次單步執行分析,得到被加虛擬機的代碼運行流程如下。
EBP為虛擬機自己的棧頂地址類似x86的esp
EDI為虛擬機寄存器基地址
下面對各個關鍵點通過匯編和數據進行詳細分析
代碼流是通過ESI來進行的
ESI先來自那個Push進來的Key
0096334A | 8B7424 50 | mov esi,dword ptr ss:[esp+50] | var_4 進虛擬機push的Key
再加那個540000的偏移
00964393 | 0375 00 | add esi,dword ptr ss:[ebp] | esi+= 540000
本次VMP版本ESI是每次累減而不是累加
ESI操作完現在是00965195
每次取的是[esi-1],也就是esi所示的前一個字節
0096439B | 8A46 FF | mov al,byte ptr ds:[esi-1] |
al現在就指向這里
每次算完edx(下一跳地址)之后esi還會-1
00964785 | 83EE 01 | sub esi,1 | esi:sub_9650C6+CF
實際上ESI指向的2C是寄存器索引
00964241 | 891407 | mov dword ptr ds:[edi+eax],edx | Handle eax是root esi指的那個字節
2C/4 = B 所以本次VMP指令就是
VMPop Reg11
每次要跳到哪個HANDLE取決于這行匯編代碼
009643B0 | 8B1485 AD3C9600 | mov edx,dword ptr ds:[eax*4+<sub_963cad>] | 這里的EDX決定著后面ret 38 ret到 [963CAD + Index * 4]+540000-1 edx-1+540000
可以看到這里有一個表,那就是963CAD,
這個表里的值是一個偏移。要想跳到實際的HANDLE要把這個值+540000然后再-1
比如,要跳到這個表索引為0的handle就是要跳到[963CAD+0 * 4]+540000-1 = 004246D4+540000-1=009646d3,正好是PopReeg4 handle
乍看這一個表,表里有重復的值,不知道是什么意思。
這個 index剛好就是之前的esi的值。也就是這里
那么說明esi指令的這個地方,有兩個用處?
這看起來很詭異,因為esi所指向的這個字節他即充當了操作數寄存器的索引,又充當了本條指令handle的索引。
除非是這樣:先把流程弄好,再按排好的流程再填充這個963CAD表。
比如說,本條指定是
VMPop Reg12
則在ESI指向的那塊內存里寫入12 * 4 = 0x30,然后再在esi指向的內存里寫入0x30,然后再在963CAD這個表里的0x30索引的位置寫入VMPop 的HANDLE。
第二條指令的時候ESI指向這里
所以索引是0x46
這個指令跳到的handle會讀取[esi-4]的一個DWORD。
讀的位置也就是這里:
轉換成DWORD就是DA94102D,后面又用bswap指令轉成了2D1094DA,所以這個立即數實際上是2D1094DA
執行完又將esi前移4字節
由于這個handel有如下代碼
0096206F | 83ED 04 | sub ebp,4 | 00963B9E | 8945 00 | mov dword ptr ss:[ebp],eax | eax是立即數
所以說這個是將立即數壓棧的handle
所以這個加法的操作是[ebp+4]=[ebp]+[ebp+4]
VMPop Reg11
VMPushDWORD 2D1094DA
VMAdd [EBP+4]=[EBP]+[EBP+4]
VMPop Reg5
VMPop Reg6
VMPop Reg14
VMPop Reg2
VMPop Reg7
VMPop Reg5
VMPop Reg4
VMPop Reg0
VMPop Reg3
VMPop Reg10
VMPop Reg15
VMPop Reg9
VMPop Reg0
VMPush WORD 0x100
VMPUsh WORD 0x1000
VMPop Reg9
VMPop Reg8
VMPush Reg15
VMPhsh Reg9
VMPush Reg8
VmAdd
VMPopReg R13
VMPopReg R12
VMPopReg R10
VmPush Reg3
VmPUsh Reg0
VMPush Reg9
VMPush Reg12
VMPush Reg13
VmPUsh Reg2
VMPush Reg14
VmPUsh Reg3
VmPUsh Reg9
下一步就是要寫腳本對更復雜的代碼進行自動解析。</sub_963cad></testvmp.vmp.sub_963725>
注:本文轉自博客園/ 作者:張東升 / 如涉及侵權,請聯系刪除!
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自: