轉(zhuǎn)帖|使用教程|編輯:楊鵬連|2021-06-24 10:14:58.927|閱讀 624 次
概述:?看了網(wǎng)上大神們寫了好多的vmp 虛擬代碼的分析 ,但是在對實在項目時,插件總是提示不對或者未知版本,一直對vm代碼的還原有質(zhì)疑,于是就萌發(fā)了具體分析這個vm代碼是怎么回事,若有錯誤,歡迎指出,能力有限只能分析皮毛,只談vm的代碼。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
VMProtect是一種很可靠的工具,可以保護應用程序代碼免受分析和破解,但只有在應用程序內(nèi)保護機制正確構(gòu)建且沒有可能破壞整個保護的嚴重錯誤的情況下,才能實現(xiàn)最好的效果。
VMProtect通過在具有非標準體系結(jié)構(gòu)的虛擬機上執(zhí)行代碼來保護代碼,這將使分析和破解軟件變得十分困難。除此之外,VMProtect還可以生成和驗證序列號,限制免費升級等等。
VMProtect正版授權(quán)在線訂購享受最低價,僅售801元起!還不趕緊加入你的訂購清單?>>更多詳情可點擊咨詢購買
相關鏈接:
代碼保護軟件VMP逆向分析虛擬機指令:初步認識與環(huán)境搭建(一)
代碼保護軟件VMP逆向分析虛擬機指令:VMP代碼的提取(二)
四、分析那4條匯編被VM的VM指令
其他無關的我就不貼上來了,我直接貼上分析出的VM指令,怎么分析出的,和上面的分析VM指令同理
\---------------------------------------------------------------- >>>>>>>>>>>>>>>>>>>>>>>>vm的匯編解析
VM_PushImm32 0x00001111
VM_PopReg32 vm_context->0x1C 0x00001111
VM_PushImm32 0x00003333
VM_PopReg32 vm_context->0x00 0x00003333
VM_PushImm32 0x00002222 執(zhí)行下面的VM_Add后 | dwResult 0x00005555
VM_PushReg32 vm_context->0x00 0x00003333 | eflags 0x00000206
VM_Add
VM_PopReg32 vm_context->0x1C 0x00000206 EFLAGS
VM_PopReg32 vm_context->0x1C 0x00005555
VM_PushImm32 0x00001010
VM_PushReg32 vm_context->0x1C 0x00005555 dwResult 上一次Add的結(jié)果
VM_PushReg32 vm_context->0x1C 0x00005555
VM_Nand 執(zhí)行后 [ESP] = EFLAGS = 0x286 [ESP+4]=0xFFFFAAAA
VM_PopReg32 vm_context->0x00 0x286 彈出這個后 現(xiàn)在棧上應該是[ESP]=0xFFFFAAAA [ESP+4]=0x0x00001010
VM_Add 執(zhí)行這個這里后 [ESP] = EFLAGS = 0x282 [ESP+4]=0xFFFFBABA
VM_PopReg32 vm_context->0x0C 0x282 eflags
VM_PushReg32 vm_esp 現(xiàn)在[ESP] = ESP+4 即保存這個地址 這個地址對應的值是 0xFFFFBABA 沒問題吧
VM_SSReadMemSS 把棧頂?shù)闹诞攎em讀 值返回到自身 [ESP]=[[ESP]] = [ESP + 4] = 0xFFFFBABA
VM_Nand 還沒運行這個指令時[ESP]=0xFFFFBABA [ESP+4]=0xFFFFBABA
VM_PopReg32 vm_context->0x20 0x202 eflags
VM_PopReg32 vm_context->0x10 0x00004545 到這里 可以說這4句匯編已經(jīng)運行完畢了
VM_PushReg32 vm_context->0x0C 0282 但是還要處理這個符號寄存器的值應該是多少
VM_PushImm32 0x815 因為我們是用其他方式去解析這個解法 是吧 那么每一步的eflags的變化
VM_Nor dwResult = 0xFFFFFFFF
VM_PopReg32 vm_context->0x00 0x286 eflags 那么這些每一步eflags的變化怎么轉(zhuǎn)化為減法時產(chǎn)生的eflags一致呢
VM_PushReg32 vm_esp
VM_SSReadMemSS 看到很多vm指令可以合為一個我們認識的指令是吧 比如這里的 壓esp 直接讀[[esp]]值反回[ESP]
VM_Nand 其實就是 VM_Nand(0xFFFFFFFF,0xFFFFFFFF) -> dwResult = 0x00000000
VM_PopReg32 vm_context->0x1C 0x246 eflags
VM_PushReg32 vm_context->0x20 0x202
VM_PushReg32 vm_context->0x20 0x202
VM_Nor ~0x202 & ~0x202 = 0xfffffdfd
VM_PopReg32 vm_context->0x18 0x282
VM_PushImm32 0x815 ---------- 這里應該是提取 OF、ZF 標志 -------------
VM_Nand ----------------------------------------------------
VM_PopReg32 vm_context->0x1C eflags 這里說的是 VM_Nand(0x282,0x815)的eflags
VM_Add 0x202 dwResult
VM_PopReg32 vm_context->0x1C eflags 這里也是一樣 不管是VM_Add還是VM_Nor等 都是讀[ESP]和[ESP+4]值運算
VM_PopReg32 vm_context->0x00 0x202 接上句 結(jié)果放[ESP+4] 影響的符號(或者說運算后符號寄存器)放[ESP]
>>>>>>>>>>>>>>>>>vm的代碼解析完畢
然后我們總結(jié)簡化一下是這樣:
VM_Add (0x00003333,0x00002222) 0x00005555 VM_Nand(0x00005555,0x00005555) 0xFFFFAAAA VM_Add (0xFFFFAAAA,0x00001010) 0xFFFFBABA VM_Nand(0xFFFFBABA,0xFFFFBABA) 0x00004545哦豁!有點東西了是不,與非門。vmp中大名鼎鼎的與非門,傳說中的化簡為繁............
我們把上面的4句vm指令翻譯成數(shù)學表達 /- A = 0x3333 + 0x2222 | A = ~A 因為這里VM_Nand 中and 兩邊的值是一樣的我就不寫成~A & ~A 了 | B = A + 0x1010 - B = ~B 我們知道 int32的X 的 ~X = 0xFFFFFFFF - X 是吧 所以我們在化解 / A = ~0x5555 --> B = 0xFFFFFFFF - (0xFFFFFFFF - 0x5555 + 0x1010) ---> B=0x5555-0x1010 = 0x4545 \ B = ~(A + 0x1010) 這個是數(shù)學上的東西是吧 當然了 這些規(guī)律我們都是可以總結(jié)的我們簡單總結(jié)一下這個與非門變換出的幾種算術推導
1.NOT(A): NAND(A,A) 2.AND(A,B): NAND(NAND(A,A),NAND(B,B)) 3.OR(A,B): NAND(NAND(A,B),NAND(A,B)) 4.XOR(A,B): NAND(NAND(NAND(A,A),NAND(B,B)),NAND(A,B)) 5.SUB(A,B): NAND(NAND(A,A)+B) 6.AND(A,B): NAND(NOR(A,B),NOR(A,B)) 注意這個推導很明顯,我們上面的 0x5555-0x1010用到了 推導5
VM_Add (0x00003333,0x00002222) 0x00005555 eflags 0x206 丟棄 VM_Nand(0x00005555,0x00005555) 0xFFFFAAAA eflags 0x286 vm_context->0x00 VM_Add (0xFFFFAAAA,0x00001010) 0xFFFFBABA eflags 0x282 vm_context->0x0c --有效的eflags VM_Nand(0xFFFFBABA,0xFFFFBABA) 0x00004545 eflags 0x202 vm_context->0x20 --有效的eflags 看到上面 SUB(A,B)-> NAND(NAND(A,A)+B) 而這里有的代碼是先加0x2222 在減0x1010 所以我們 加0x2222得到的符號eflags我們丟棄了 看到下面可以看出是用了之后的進行處理的 也就是說只要模擬出減時的符號變化即可 (我們知道加和減的符號影響是一樣的 在計算機中 加減有什么區(qū)別呢 是吧) imm32 0x815 -> SF、AF、PF、CF ---------------------------------------------------------- VM_Nor (0x282, 0x815) -> dwResult = 0xffffffff---->| VM_Nand(0xffffffff, 0xffffffff) -> dwResult = 0x00000000-----|- 0x282 & 0x815 VM_Nor (0x202, 0x202) -> dwResult = 0xfffffdfd---->| VM_Nand(0xfffffdfd, 0x815) -> dwResult = 0x202--------->|- 0x202 & 0xffff7ea - > (0x202 & ~0x815) VM_Add (0x00000000, 0x202) -> dwResult = 0x202----------|- (0x282 & 0x815) + (0x202 & 0xffff7ea)所以我們只是對兩個eflags的變換就完成了真正的sub影響的符號位。我們知道sub影響的標志位為: 0F SF ZF AF PF CF
-> 公式應該是 : (0x282 & 0x815) + (0x202 & 0xffff7ea)
注意0x815指的是 SF、AF、PF、CF , 而0xffff7ea正好是0x815的反
-> 所以應該是第一個eflagsA 取 OF、AF、PF、CF 。 第二個eflagsB取其他值,
當然這里有意義的就是AF和ZF。
1.eflagsA = 0x282 是 VM_Add (0xFFFFAAAA,0x00001010)來的, 而我們知道add影響的標志位和sub是一樣的,說明這一步后
其實我們就得到了0F SF ZF AF PF CF那么說明我們是不是只要這個eflagsA就可以了呢,但是你別忘了了后面還有個VM_Nand
2.eflagsB = 0x202 是緊跟著的VM_Nand來的,而我們知道and影響的標志位為: 清空OF、CF,設置SF、ZF和PF,AF不影響
我們回過頭來分析
eflagsA -> 0x282 & 0x815 提取的是 OF、AF、PF、CF
eflagsB -> 0x202 & ~0x815 提取的是 SF、ZF
當然標志位的值不只是這些,但是我們只關心目前的sub影響的標志位,其他的我們先不考慮,其他我不知道是什么用的,沒深入分析。
這樣最后 相加(加 或者 或 都可以) 就得到了 0F SF ZF AF PF CF 6個標志位
1.疑問 : 為什么對于eflagsB我們只是提取了SF、ZF 沒有提取OF、CF。首先SUB的計算其實在ADD中就做完了,關于標志的部分(與結(jié)果無關只與過程),
所以eflagsB VM_Nand生成的 and影響清空OF、CF,我們不提eflagsB中的OF、CF做結(jié)果是因為OF、CF是計算的過程中影響的符號,而用了SF、ZF是因
為SF是結(jié)果符號標志(即負數(shù)或者正數(shù)),ZF也是結(jié)果符號標志(結(jié)果是0就激活ZF)。所以用的最后的eflagsB的影響的這兩個標志位,也是VM_Nand后才得
到最后的結(jié)果。
2.那在VM_Nand中我們要考慮Not操作影響的符號標志位嗎? 不需要,因為他不影響標志位
如果您對該加密/解密軟件感興趣,歡迎加入vmpQQ交流群:740060302
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務必注明出處、不得修改原文相關鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自: