天天看點

VM(虛拟機技術)保護

1.VM技術介紹

我發現論壇上每當談到虛拟機技術時,鮮有幾人參與讨論,因為虛拟機技術還沒有普及到大家的心中。VM 其實就是Virtual Machine(虛拟機)的縮寫,這裡說的VM并不是像VMWare那樣的虛拟機,而是将一系列的指令解釋成bytecode(位元組碼)放在一個解釋引擎中執行。

2.目前現狀的VM應用

VM技術最早的應用我想應該是VB(PCode)吧(瞎猜的),時至今日才被人們廣泛用于安全技術中。

如今已經将虛拟機應用到商業中的保護殼現有三款:Vmprotect,themida和 execrypt,

Themida是一款綜合型強殼,資源加密、代碼變形和虛拟機技術用得是面面俱到。

Execrypt 比Themida遜色一點,不過我沒研究過。

Vmprotect是一款專門對代碼加VM的加殼軟體,其保護強度是3款當中最強的,最早由2005年問世起,至今尚無人公開宣稱能還原其原彙編代碼,可見其強度,是以VMP已逐漸被人們用來保護其産品,使Cracker們對于這個看起來毛茸茸的刺猬毫無辦法。

3.VM的一些原理

一個虛拟機引擎由編譯器、解釋器和VPU Context(虛拟CPU環境)組成,再配上一個或多個指令系統。

編譯器:将一條條X86指令解釋成自己的指令系統。

解釋器:解釋器附加在被加殼的軟體中,用來解釋這些自定義的指令。

指令系統:一套或多套自己定義的指令系統,用來虛拟執行這些bytecode。

在設計VM時提幾個建議:

1:設計一個好的、簡潔的指令系統是很有必要的,寫出越少卻能執行最全的指令,就說明這些指令複用性越高。

2:在分析X86指令時最好為它們分類,注意流程指令、不可模仿指令的處理。

3:解釋器的代碼設計得越少越好,換來的速度可以變形一下。

現在講講虛拟機是如何運作的,首先加殼程式先把已知的X86指令解釋成了位元組碼,放在PE檔案中,然後将原處代碼删掉,

改成類似的代碼進入虛拟機執行循環。

push bytecode

jmp VstartVM

VstartVM是進入虛拟機的函數,它的代碼大概類似這樣的

// 進入虛拟機函數,我的最初版本是寫死在成種VC環境下的,不過這樣處理起來很麻煩。

void _declspec(naked) VStartVM()

{

_asm

{

// 将寄存器壓入堆棧,由僞指令取出存放到VMReg中

//可以考慮為壓棧時加入一些随機性

push eax

push ebx

push ecx

push edx

push esi

push edi

push ebp

pushfd

mov esi,[esp+0x20]

mov ebp,esp

sub esp,0x200

mov edi,esp  

sub esp,0x40

Next:

movzx eax,byte ptr [esi]

lea esi,[esi+1]

jmp dword ptr [eax*4+JUMPADDR] ;跳到Handler執行處,由加殼引擎填充

VM_END ;VM結束标記

}

}

然後每讀一個byte跳到目标處模拟執行代碼。  

JUMPADDR就是一張函數表(讓我想到了VTBL),每次從記憶體裡讀出一個command code(其實就是偏移),然後轉向那個過程,如vEnter的代碼:

// enter和執行下列代碼用途相同

//push ebp

//mov ebp,esp

//sub esp,(L - 1) * 4 ; L > 0才有這步操作,用來存儲嵌套的L - 1個子過程的棧架構指針(注意是指針)

//push ebp ; 目前過程的棧架構指針

//sub esp,N

mov edx,[edi+Ebp]

sub ebp,4

mov dword ptr [ebp],edx

mov edx,ebp

mov [edi+Esp],edx

mov edx,ebp

lea ecx,[ecx*4];ecx是從記憶體讀出的opcode

sub edx,ecx

sub edx,4

test ecx,ecx

cmovne ebp,edx

mov edx,[edi+Ebp]

sub ebp,4

mov dword ptr [ebp],edx

sub ebp,eax

//。。一些修正堆棧的工作

jmp next  

以上代碼就是模拟一個enter指令的代碼,我不會彙編,就隻能寫成這樣了。

現在再來看看它們的執行過程:

1.首先進入虛拟機,壓入寄存器,然後設計一些僞指令來将寄存器儲存到虛拟機環境中去。

2.一切工作就緒,真實寄存器存放的值是什麼已經不重要了,因為我們将它存放到了虛拟環境中去了,自己可以随便使用而不用怕影響到原來的代碼。

3.這時從那句jmp table看起,從[esi]得到一個偏移,它指向的就是vEnter的位址,于是它來到了vEnter處

4.vEnter又從記憶體中得到opcode,模拟出這句代碼,并存放到堆棧。

5.注意有時要修正虛拟堆棧寄存器的值,否則會挂得很慘。

6.Jmp 到 next,這時轉向第2步。

其他指令如同vEnter一樣。。。發揮你的想像力了。

2-6就是一個虛拟機的執行過程,如果你曾經調試過VM,是否會對jmp [table+x]似曾相識呢?

一個簡單的VM引擎就是這個樣子,不過一個專業化、商業化的引擎可不僅是這個樣子,還要注重很多東西,比如多線程、流程化指令,虛拟-現實之間的轉換,支援SEH異常(包括VB、VC的異常)。

看到這裡,你可以發現,虛拟機就是一層複雜的殼子,把原來的代碼藏得毫無蹤影,如果你想還原出原來的代碼(基于更進階的理論來說,暫時已經不可能了),那麼你需要先複習一下IA64,然後仔細研究VM執行體,逆向出Table中用到的函數,得出它正在執行哪一條語句的哪一“部分”。。。除非你要研究的程式達到了一定的價值,不然我想等你弄清楚這個程式如何執行的時候,意義已經不大了。

4.VM的一些資料(感謝笨笨雄的整理)

遊戲維護上不去,介紹一下虛拟機技術。

http://bbs.pediy.com/showthread.php?threadid=20792

【原創】Asprotect 中的 X86 的VM分析

http://bbs.pediy.com/showthread.php?threadid=36245

Asprotect 中的 X86 虛拟機代碼分析【原創】

http://bbs.pediy.com/showthread.php?threadid=34135  

ExeCryptor v2.X.X虛拟機不完全補完(處女帖)

http://bbs.pediy.com/showthread.php?threadid=29537  

Themida的VM分析--變形代碼清理

http://bbs.pediy.com/showthread.php?threadid=34555  

Themida虛拟機簡單介紹

http://www.pediy.com/bbshtml/bbs8/pediy8-598.htm

Themida v1.8.0.0 Demo虛拟機分析  

http://bbs.pediy.com/showthread.php?threadid=36453  

寂寞轟炸:再次小窺 VMProtect 虛拟機

http://bbs.pediy.com/showthread.php?threadid=37293  

【原創】VMCrackME----A Preliminary Virtual Machine From Top To Bottom  

http://bbs.pediy.com/showthread.php?...viewgoodnees=1 (http://bbs.pediy.com/showthread.php?t=40854&viewgoodnees=1)

Defeating HyperUnpackMe2 With an IDA Processor Module

http://www.openrce.org/articles/full_view/28

繼續閱讀