教你如何制作VB的P-Code調(diào)試器
發(fā)布日期:2021-12-17 00:08 | 文章來源:站長之家
P-Code簡介
術語P-Code既不是一個新名詞也不是Microsoft的發(fā)明,P-Code只是簡單地被解釋執(zhí)行的偽指令。因此,我們并不需要通過什么復雜的專業(yè)詞匯來描述它。P-Code可以被認為是一種普通的機器級代碼(我們的微處理器不能解釋它)。在運行P-Code之前,需要一個解釋器處理它,轉(zhuǎn)換P-Code為CPU可以理解的機器語言。這個過程看起來有點象JAVA, 為了執(zhí)行JAVA語言寫成的應用程序,我們需要一個進行解釋和翻譯的處理程序- 虛擬機“Virtual Machine”。這個負有想象力的術語實際意味著它是一個翻譯的機制,將JAVA編寫的程序轉(zhuǎn)換成我們的CPU可以理解的操作碼(指令)。
P-Code的優(yōu)勢是明顯的。假如我們定義了一組特殊的專屬性指令集,并且不公布它的詳細定義規(guī)范說明,那么一般人很難理解我們生成的程序代碼;另一個優(yōu)勢是減小了執(zhí)行文件的尺寸:通過定義獨特的單字節(jié)操作碼,我們能夠使得某些偽指令執(zhí)行一系列的操作(相當于大量的機器碼完成的工作)。Microsoft的 Visual Basic 包含的P-Code的確是如此:一個VB虛擬機翻譯P-Code到我們本地的機器碼。 虛擬機(以dll形式出現(xiàn)),在P-Code程序執(zhí)行前被調(diào)用,用來解釋相關VB的偽指令。有如你猜測的那樣,那些DLL的名稱是 :
MSVBVM50.DLL MSVBVM60.DLL
文件名稱清晰的表明是Microsoft Visual Basic 虛擬機(Virtual Machine), 后跟不同的版本信息。兩個版本的差異不大:版本6引入了一些新的指令,并采用了更直觀的命名來標注某些版本5中的指令。換句話說,版本6只是改變了版本5中部分指令名稱,而非其內(nèi)在的功能。 虛擬機不僅解釋Visual Basic 的P-Code文件,同時它也被用于執(zhí)行編譯過的機器碼。這是因為VB 虛擬機(DLL文件)同時也包含所有VB程序要調(diào)用的API。 一個例子是rtcMsgBox, 這是個等價于標準Windows API MessageBox 的VB函數(shù)。P-Code代碼被VB虛擬機解釋執(zhí)行,VB中所有的函數(shù)都是以這種間接的方式被提供的。 由于這個原因,當我們跟蹤一個Windows API MessageBox被 P-Code程序時,產(chǎn)生了一個嚴重的問題:我們必須要跟蹤P-Code偽指令。 SoftICE 無法跟蹤P-Code偽指令, 它只能跟蹤VB虛擬機的執(zhí)行過程。更明確地說, SoftICE 只能理解CPU處理器的機器碼,它不能理解任何偽指令。我們將嘗試去跟蹤P-Code(P-Code偽指令將被轉(zhuǎn)換成可被我們的CPU理解和執(zhí)行的機器碼)。 起始表(Beginning of the Tale)
幾乎所有的事情都是如此:好奇心引發(fā)了人們迎接一項新的挑戰(zhàn),我們的故事由此開始。 我記得曾在EFNet網(wǎng)站(論壇)與Green先生討論有關VB P-Code的問題。他那時的工作正好涉及有關VB5編譯的應用程序。他告訴我處理P-Code是非常的困難,所以我們有了制作一個VB P-Code的Debugger程序的想法。 實際上Black先生也認為這是個有意義的思路??紤]到這個項目,我說如果我們沒有任何可用的有關資源,這可不容易實現(xiàn)。而后,我們查找了許多有關信息,但沒有任何有意義的發(fā)現(xiàn),空手而歸。好奇心使得我更加努力去細心地發(fā)掘有用的信息資料。的確是不易呀…我曾和Snow先生探討有關問題,他提供給我一個被Lazarus修改過的 MSVBVM50, 在其中,他描述了VB程序表現(xiàn)的所有可能的串比較。這促使我下決心制作一個VB Debugger。 我認為當MSVBVM50運行時注入代碼是可能的。被注入的代碼能夠調(diào)用我的Debugger, 它在一個DLL中實現(xiàn)。 我決定告訴已加入這個項目的Snow先生, 由他負責制作代碼注入器 (好像一個調(diào)用裝入器Loader) ,我負責Debugger (DLL)編碼,就是那個被裝入的Debugger(DLL) 。 就在我們兩個完成了一些工作后,我們進行了測試,令人振奮的是它真的可以工作!這個 Debugger項目已經(jīng)邁出了它的第一步。 我們可以控制VB虛擬機(截獲有關操作),并且在虛擬機與VB應用程序之間安置我們的Debugger。最大的問題已經(jīng)得到解決,雖然在初始階段,我們采用的解決方案(技術上如你所見)并不是最終我們采用的方法。在我們的大目標和指導思想始終如一的情況下,我們不斷對它進行改進,一直到我們完全避免了對虛擬機本身的修改。 * 第一步 跟蹤分析,控制虛擬機 為使我們的Debugger能夠工作,有一個關鍵性必須解決的問題:發(fā)現(xiàn)P-Code代碼的翻譯轉(zhuǎn)換是什么時候以及如何發(fā)生的。一旦我們認識到這一點,我們注入的代碼將接管對被調(diào)試的VB應用程序的控制,并且發(fā)送有關數(shù)據(jù)到我們的Debugger。Debugger 依次處理操作碼并返回到VB 虛擬機。 我本人以前在有關調(diào)試器Debugger編碼方面的經(jīng)驗幾乎為零。不過不久前我差不多完成了一個x86的反匯編器 , 因此我將那些知識用于我的VB Debugger 開發(fā)工作。我的構思是這樣的: 對于反匯編/解釋這部分代碼包含以下基本原理: - 一個指針(pointer)指向一個緩存區(qū)(buffer),它包含將被轉(zhuǎn)換的數(shù)據(jù)。
- 一個控制程序,它從緩存區(qū)中讀取操作指令(opcodes)并且重定向程序流,使其依據(jù)我們的意圖,指向我們想要它執(zhí)行的程序位置。 這個任務通常表現(xiàn)為兩種形式: 1、一系列控制描述語句(對于每一個操作碼);2、使用一個地址跳轉(zhuǎn)表。 我放棄了第一種選擇。因為P-Code中各不相同的操作碼實在太多,這將需要一個巨大的條件控制結構(處理這樣的工作將變成世界上最慢的事情)。 我猜VB虛擬機對P-Code的翻譯轉(zhuǎn)換過程采用的是地址跳轉(zhuǎn)表方法去解釋那些可能的操作代碼。 這種做法同樣出現(xiàn)在我設計的反匯編器中。 現(xiàn)在,我必須完成以下的工作: - 定位緩存區(qū)中待解釋的操作碼,定位跳轉(zhuǎn)地址表 我設計并且編譯了一個小VB應用程序: Private Sub Form_Load() MsgBox "Hello this is P-Code!!!", VBInformation, "Example" End Sub 我通過SoftICE的符號載入器(symbol loader)調(diào)入MSVBVM60.DLL (VB6虛擬機) ,設置BPX on _rtcMsgBox。 當SoftICE 中斷時,我按 F12返回調(diào)用 _rtcMsgBox 的代碼: call eax // 調(diào)用 rtcMsgBox
cmp edi,esp // 我們在此
jnz 66105595 // 檢查堆棧指針
xor eax,eax // 準備寄存器 eax 去調(diào)用緩存區(qū)中的下一個操作碼
mov al,[ESI] // 在al中裝入待執(zhí)行的操作碼, 上面的演示中,它是36h
inc ESI // 增加指針偏移量(在 ESI 寄存器中)
jmp [eax*4 660FDA58] // 跳轉(zhuǎn)到解釋偽指令操作碼 36h 的處理程序
MSVBVM50.DLL MSVBVM60.DLL
文件名稱清晰的表明是Microsoft Visual Basic 虛擬機(Virtual Machine), 后跟不同的版本信息。兩個版本的差異不大:版本6引入了一些新的指令,并采用了更直觀的命名來標注某些版本5中的指令。換句話說,版本6只是改變了版本5中部分指令名稱,而非其內(nèi)在的功能。 虛擬機不僅解釋Visual Basic 的P-Code文件,同時它也被用于執(zhí)行編譯過的機器碼。這是因為VB 虛擬機(DLL文件)同時也包含所有VB程序要調(diào)用的API。 一個例子是rtcMsgBox, 這是個等價于標準Windows API MessageBox 的VB函數(shù)。P-Code代碼被VB虛擬機解釋執(zhí)行,VB中所有的函數(shù)都是以這種間接的方式被提供的。 由于這個原因,當我們跟蹤一個Windows API MessageBox被 P-Code程序時,產(chǎn)生了一個嚴重的問題:我們必須要跟蹤P-Code偽指令。 SoftICE 無法跟蹤P-Code偽指令, 它只能跟蹤VB虛擬機的執(zhí)行過程。更明確地說, SoftICE 只能理解CPU處理器的機器碼,它不能理解任何偽指令。我們將嘗試去跟蹤P-Code(P-Code偽指令將被轉(zhuǎn)換成可被我們的CPU理解和執(zhí)行的機器碼)。 起始表(Beginning of the Tale)
幾乎所有的事情都是如此:好奇心引發(fā)了人們迎接一項新的挑戰(zhàn),我們的故事由此開始。 我記得曾在EFNet網(wǎng)站(論壇)與Green先生討論有關VB P-Code的問題。他那時的工作正好涉及有關VB5編譯的應用程序。他告訴我處理P-Code是非常的困難,所以我們有了制作一個VB P-Code的Debugger程序的想法。 實際上Black先生也認為這是個有意義的思路??紤]到這個項目,我說如果我們沒有任何可用的有關資源,這可不容易實現(xiàn)。而后,我們查找了許多有關信息,但沒有任何有意義的發(fā)現(xiàn),空手而歸。好奇心使得我更加努力去細心地發(fā)掘有用的信息資料。的確是不易呀…我曾和Snow先生探討有關問題,他提供給我一個被Lazarus修改過的 MSVBVM50, 在其中,他描述了VB程序表現(xiàn)的所有可能的串比較。這促使我下決心制作一個VB Debugger。 我認為當MSVBVM50運行時注入代碼是可能的。被注入的代碼能夠調(diào)用我的Debugger, 它在一個DLL中實現(xiàn)。 我決定告訴已加入這個項目的Snow先生, 由他負責制作代碼注入器 (好像一個調(diào)用裝入器Loader) ,我負責Debugger (DLL)編碼,就是那個被裝入的Debugger(DLL) 。 就在我們兩個完成了一些工作后,我們進行了測試,令人振奮的是它真的可以工作!這個 Debugger項目已經(jīng)邁出了它的第一步。 我們可以控制VB虛擬機(截獲有關操作),并且在虛擬機與VB應用程序之間安置我們的Debugger。最大的問題已經(jīng)得到解決,雖然在初始階段,我們采用的解決方案(技術上如你所見)并不是最終我們采用的方法。在我們的大目標和指導思想始終如一的情況下,我們不斷對它進行改進,一直到我們完全避免了對虛擬機本身的修改。 * 第一步 跟蹤分析,控制虛擬機 為使我們的Debugger能夠工作,有一個關鍵性必須解決的問題:發(fā)現(xiàn)P-Code代碼的翻譯轉(zhuǎn)換是什么時候以及如何發(fā)生的。一旦我們認識到這一點,我們注入的代碼將接管對被調(diào)試的VB應用程序的控制,并且發(fā)送有關數(shù)據(jù)到我們的Debugger。Debugger 依次處理操作碼并返回到VB 虛擬機。 我本人以前在有關調(diào)試器Debugger編碼方面的經(jīng)驗幾乎為零。不過不久前我差不多完成了一個x86的反匯編器 , 因此我將那些知識用于我的VB Debugger 開發(fā)工作。我的構思是這樣的: 對于反匯編/解釋這部分代碼包含以下基本原理: - 一個指針(pointer)指向一個緩存區(qū)(buffer),它包含將被轉(zhuǎn)換的數(shù)據(jù)。
- 一個控制程序,它從緩存區(qū)中讀取操作指令(opcodes)并且重定向程序流,使其依據(jù)我們的意圖,指向我們想要它執(zhí)行的程序位置。 這個任務通常表現(xiàn)為兩種形式: 1、一系列控制描述語句(對于每一個操作碼);2、使用一個地址跳轉(zhuǎn)表。 我放棄了第一種選擇。因為P-Code中各不相同的操作碼實在太多,這將需要一個巨大的條件控制結構(處理這樣的工作將變成世界上最慢的事情)。 我猜VB虛擬機對P-Code的翻譯轉(zhuǎn)換過程采用的是地址跳轉(zhuǎn)表方法去解釋那些可能的操作代碼。 這種做法同樣出現(xiàn)在我設計的反匯編器中。 現(xiàn)在,我必須完成以下的工作: - 定位緩存區(qū)中待解釋的操作碼,定位跳轉(zhuǎn)地址表 我設計并且編譯了一個小VB應用程序: Private Sub Form_Load() MsgBox "Hello this is P-Code!!!", VBInformation, "Example" End Sub 我通過SoftICE的符號載入器(symbol loader)調(diào)入MSVBVM60.DLL (VB6虛擬機) ,設置BPX on _rtcMsgBox。 當SoftICE 中斷時,我按 F12返回調(diào)用 _rtcMsgBox 的代碼: call eax // 調(diào)用 rtcMsgBox
cmp edi,esp // 我們在此
jnz 66105595 // 檢查堆棧指針
xor eax,eax // 準備寄存器 eax 去調(diào)用緩存區(qū)中的下一個操作碼
mov al,[ESI] // 在al中裝入待執(zhí)行的操作碼, 上面的演示中,它是36h
inc ESI // 增加指針偏移量(在 ESI 寄存器中)
jmp [eax*4 660FDA58] // 跳轉(zhuǎn)到解釋偽指令操作碼 36h 的處理程序
版權聲明:本站文章來源標注為YINGSOO的內(nèi)容版權均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復制或仿造本網(wǎng)站,禁止在非maisonbaluchon.cn所屬的服務器上建立鏡像,否則將依法追究法律責任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學習參考,不代表本站立場,如有內(nèi)容涉嫌侵權,請聯(lián)系alex-e#qq.com處理。
相關文章
關注官方微信