有關VB程式P-CODE程式碼逆向工程入門淺說
有關VB程式P-CODE程式碼逆向工程入門淺說
對於破解初學者來說,可能在除錯VB(P-CODE)編寫的程式時感到難於分析和跟蹤,特別是查詢和定位“註冊碼比較”關鍵點,以及修補程式碼等。小弟對VB程式內部構造同樣也是一塌糊塗,對破解更是一知半解,和各位初學者一樣,只是感興趣而已。偶爾嘗試除錯,跟蹤個VB程式玩玩,沒什麼目的。閒著沒事,我們就隨便扯點個人淺顯的經驗,僅供和我一樣的菜鳥同道參考,讓各位高手見笑了。
特別宣告:本文僅僅服務於對VB P-CODE程式破解感興趣的初學者,絕非專業學術研究,不提供任何有關研究分析的科學方法和步驟。
注:如果您僅僅對OLLYDBG除錯VB P-CODE感興趣,請直接參考第4部分。
1.緣起
有天,您正在網上溜達,忽然發現一個感興趣的共享小程式,想拿來用用,可還沒怎麼試,它就跟您較勁兒,老是讓您註冊,煩不煩?我們能受這個限制嗎?… 既然玩保護,那我們們就幫作者測試測試保護的強度,呵呵,考驗我們們的時候又到了。。。3下5/2, 經過您的火眼金睛一看,原來是個VB(P-CODE)捏把的東東。怎麼看出是P-CODE? 方法很多,比如拿WKTVBDE要是能LOAD,我想它就是了,什麼?不知道WKTVBDE是什麼?那用Exdec反一下,什麼,這個也沒聽說過?那我們們先別往下繼續了,您最好先了解一下有關的預備知識,也可以在本論壇搜尋相關vb p-code破解案例分析。擅自推薦您參考“FLY”大俠的破解例項。
對手出現了,怎麼辦?要是我,可能準備如下工具:
VBExplorer (靜態分析P-CODE的好東西,又免費,建議作者繼續完善,堅持不收費政策50年不變 ^&^ )
WKTVBDE (VB P-CODE動態跟蹤偵錯程式,在下一般用它來動態修改程式碼,判斷分析的效果。要想用它真正搞清楚程式的細節,小弟還沒有發現好辦法,但作為粗略的分析工具,檢視程式分支判斷,迴圈次數,它還是蠻好用的。對於分析VB P-CODE,它有如一個大砂輪,先用它磨一磨,精細加工,那是下一個將介紹的工具)
Ollydbg(很不錯的偵錯程式,我用1.09D。好在它的相容性和便捷性,在我的WIN2003 sever上表現很穩定,跟蹤,除錯VB P-CODE再合適不過了,只可惜不是我們們中國人的產品。在本短文稍後,我們們主要就討論如何用它跟蹤分析VB P-CODE,因為這個步驟也算蠻重要嘛)
還有其它一些可以選擇的工具,就看您的個人愛好了,比如:
Exdec vb p-code程式碼反編譯器,不錯的工具
Vbparser 1.2 同樣是 vb p-code反編譯器,不過我用的版本不能反VB 5, 有些vb 6的也不行,不知道是怎麼回事。
還有什麼好工具希望您告訴我。
2.鬼窮三技
聊齋上說,小鬼兒也沒什麼可怕的,也就有3招,你知道了,對付它就心裡有了底,有了戰勝它的信心。話說VB P-CODE程式,我們們這些新手外行如何搞定它呢?我們們也來個3招克敵:
a.靜態分析:粗略搞清楚目標程式的大致流程,分支,憑分析結果和程式設計,破解的經驗,判斷和假設目標程式的設計思路
b.程式碼還原:根據p-code虛擬碼,大致可以還原出VB源程式程式碼(針對關鍵和重要的部分,對於破解,就是還原判斷有關的和比較註冊碼前後部分的VB程式碼)
c.動態跟蹤:應用原始碼級偵錯程式(例如olldbg)跟蹤程式的執行細節,發現重要資料,甚至註冊碼等資訊
空口無憑,我們們還是透過一個簡單案例來演示一下整個的VB P-CODE逆向過程,如何?
3.循序漸進
為了演示方便,我們們先寫一個簡單的VB註冊小程式,原始碼如下(程式未經任何最佳化,僅用於演示):
Private Sub Text1_Change()
Dim i As Byte
For i = 1 To Len(Text1.Text)
If Mid(Text1.Text, i, 1) > "9" Or Mid(Text1.Text, i, 1) < "0" Then
Text2.Text = "Please enter 0-9, try again"
GoTo final_end
End If
Next
If Len(Text1.Text) >= 3 Then
get_1 = CInt(Mid(Text1.Text, 1, 1))
get_2 = CInt(Mid(Text1.Text, 2, 1))
get_3 = CInt(Mid(Text1.Text, 3, 1))
get_4 = get_2 + get_3
If get_1 = get_4 Then
Text2.Text = "good"
Else
Text2.Text = "bad"
End If
End If
final_end:
End Sub
程式僅僅根據使用者輸入的數字判斷是否符合內定的規則,如果是,顯示:good,錯誤,則提示:bad。程式很簡單,您自己看一下就明白了,我們們就不再詳細解釋了,不耽誤您的時間了。
這段小程式對應的P-CODE程式碼如下(使用VBExplorer獲得,相關程式可以從本論壇得到,或聯絡作者):
[Text1.Change]
:00401B9C F401 LitI2_Byte ;Push 01
:00401B9E FC0D CUI1I2 ;
:00401BA0 047AFF FLdRfVar ;Push LOCAL_0086
:00401BA3 0470FF FLdRfVar ;Push LOCAL_0090
:00401BA6 21 FLdPrThis ;[SR]=[stack2]
:00401BA7 0F0003 VCallAd ;Return the control index 02
:00401BAA 1974FF FStAdFunc ;
For i = 1 To Len(Text1.Text)
:00401BAD 0874FF FLdPr ;[SR]=[LOCAL_008C]
***********Reference To:[propget]TextBox.Text
:00401BB0 0DA0000000 VCallHresult ;Call ptr_004016B8
:00401BB5 6C70FF ILdRf ;Push DWORD [LOCAL_0090]
:00401BB8 4A FnLenStr ;取得輸入串的長度,作為迴圈的引數
:00401BB9 FC0E CUI1I4 ;
:00401BBB 2F70FF FFree1Str ;SysFreeString [LOCAL_0090];
:00401BBE 1A74FF FFree1Ad ;Push [LOCAL_008C];
:00401BC1 FE626CFFD900 ForUI1 ; 迴圈開始
:00401BC7 0470FF FLdRfVar ;Push LOCAL_0090
:00401BCA 21 FLdPrThis ;[SR]=[stack2]
:00401BCB 0F0003 VCallAd ;Return the control index 02
:00401BCE 1974FF FStAdFunc ;
:00401BD1 0874FF FLdPr ;[SR]=[LOCAL_008C]
***********Reference To:[propget]TextBox.Text ;出現這個提示,說明程式中參照了輸入框內容
:00401BD4 0DA0000000 VCallHresult ;Call ptr_004016B8
If Mid(Text1.Text, i, 1) > "9" Or Mid(Text1.Text, i, 1) < "0" Then
:00401BD9 0404FF FLdRfVar ;Push LOCAL_00FC
:00401BDC 21 FLdPrThis ;[SR]=[stack2]
:00401BDD 0F0003 VCallAd ;Return the control index 02
:00401BE0 1908FF FStAdFunc ;
:00401BE3 0808FF FLdPr ;[SR]=[LOCAL_00F8]
***********Reference To:[propget]TextBox.Text
:00401BE6 0DA0000000 VCallHresult ;Call ptr_004016B8
:00401BEB 283CFF0100 LitVarI2 ;Push 數字 1
:00401BF0 FCE07AFF FLdUI1 ;
:00401BF4 E7 CI4UI1 ;Push 變數 i
:00401BF5 3E70FF FLdZeroAd ;
:00401BF8 465CFF CVarStr ;
:00401BFB 042CFF FLdRfVar ;
**********Reference To->msvbvm60.rtcMidCharVar ;呼叫了Mid 函式,一般相關的引數在呼叫前已經入棧,注意上邊兩個PUSH指令,引數入棧順序是從右到左,對於MID,既是壓入1,i。意思是取從第i個開始的字元,總共取1個。
:00401BFE 0A01001000 ImpAdCallFPR4 ;Call ptr_00401020;
:00401C03 042CFF FLdRfVar ;Push LOCAL_00D4
******Possible String Ref To->"9" ;表示”9”這個文字字元被引用
:00401C06 3A1CFF0200 LitVarStr ;PushVarString ptr_004016CC
:00401C0B 5D HardType ;
:00401C0C FB700CFF GtVar ;
:00401C10 28D4FE0100 LitVarI2 ;Push 數字 1
:00401C15 FCE07AFF FLdUI1 ;
:00401C19 E7 CI4UI1 ;Push 變數 i
:00401C1A 3E04FF FLdZeroAd ;
:00401C1D 46F4FE CVarStr ;
:00401C20 04C4FE FLdRfVar ;
**********Reference To->msvbvm60.rtcMidCharVar
:00401C23 0A01001000 ImpAdCallFPR4 ;Call ptr_00401020;
:00401C28 04C4FE FLdRfVar ;Push LOCAL_013C
******Possible String Ref To->"0"
:00401C2B 3AB4FE0300 LitVarStr ; 表示”0”文字字串被引用
:00401C30 5D HardType ;
:00401C31 FB63A4FE LtVar ;
:00401C35 FB1F94FE OrVar ; or 另一個條件
:00401C39 FF1B CBoolVarNull ;vbaBoolVarNull
:00401C3B 29040074FF08FF FFreeAd ;
:00401C42 360C005CFF3CFF2C FFreeVar ;Free 000C/2 variants
:00401C51 1CD000 BranchF ;比較指令,
******Possible String Ref To->"Please enter 0-9, try again"
Text2.Text = "Please enter 0-9, try again" ;如果輸入字元無效,提示重新輸入
:00401C54 1B0400 LitStr ;Push ptr_004016DC
:00401C57 21 FLdPrThis ;[SR]=[stack2]
:00401C58 0F0803 VCallAd ;Return the control index 04
:00401C5B 1974FF FStAdFunc ;
:00401C5E 0874FF FLdPr ;[SR]=[LOCAL_008C]
***********Reference To:[propput]TextBox.Text
:00401C61 0DA4000000 VCallHresult ;Call ptr_004016B8
:00401C66 1A74FF FFree1Ad ;
GoTo final_end
:00401C69 1E1002 Branch ;ESI=00401DAC
:00401C6C 047AFF FLdRfVar ;Push LOCAL_0086
Next
:00401C6F FE786CFF2B00 NextUI1 ; 迴圈部分中止
:00401C75 0470FF FLdRfVar ;Push LOCAL_0090
:00401C78 21 FLdPrThis ;[SR]=[stack2]
:00401C79 0F0003 VCallAd ;Return the control index 02
:00401C7C 1974FF FStAdFunc ;
If Len(Text1.Text) >= 3 Then
:00401C7F 0874FF FLdPr ;[SR]=[LOCAL_008C]
***********Reference To:[propget]TextBox.Text
:00401C82 0DA0000000 VCallHresult ;Call ptr_004016B8
:00401C87 6C70FF ILdRf ;Push DWORD [LOCAL_0090]
:00401C8A 4A FnLenStr ; 輸入字串長度
:00401C8B F503000000 LitI4 ;常數3用於比較
:00401C90 E0 GeI4 ;
:00401C91 2F70FF FFree1Str ;SysFreeString [LOCAL_0090];
:00401C94 1A74FF FFree1Ad ;Push [LOCAL_008C];
:00401C97 1C1002 BranchF ;比較判斷
get_1 = CInt(Mid(Text1.Text, 1, 1))
:00401C9A 0470FF FLdRfVar ;Push LOCAL_0090
:00401C9D 21 FLdPrThis ;[SR]=[stack2]
:00401C9E 0F0003 VCallAd ;Return the control index 02
:00401CA1 1974FF FStAdFunc ;
:00401CA4 0874FF FLdPr ;[SR]=[LOCAL_008C]
***********Reference To:[propget]TextBox.Text
:00401CA7 0DA0000000 VCallHresult ;
:00401CAC 283CFF0100 LitVarI2 ; Push 1 引數,用於MID函式 取幾個字元
:00401CB1 F501000000 LitI4 ;Push 1 引數,用於MID函式
;表示 從哪個字元位置開始取
:00401CB6 3E70FF FLdZeroAd ;Push DWORD [LOCAL_0090];
:00401CB9 465CFF CVarStr ;
:00401CBC 042CFF FLdRfVar ;Push LOCAL_00D4
**********Reference To->msvbvm60.rtcMidCharVar ;mid函式呼叫
|
:00401CBF 0A01001000 ImpAdCallFPR4 ;Call ptr_00401020; check stack 0010; Push EAX
:00401CC4 042CFF FLdRfVar ;Push LOCAL_00D4
:00401CC7 FC45 FnCIntVar ;vbaI2ErrVar
:00401CC9 441CFF CVarI2 ;
:00401CCC FCF684FE FStVar ;
:00401CD0 1A74FF FFree1Ad ;Push [LOCAL_008C]; Call
:00401CD3 3608005CFF3CFF2C FFreeVar ;Free 0008/2 variants
get_2 = CInt(Mid(Text1.Text, 2, 1))
:00401CDE 0470FF FLdRfVar ;Push LOCAL_0090
:00401CE1 21 FLdPrThis ;[SR]=[stack2]
:00401CE2 0F0003 VCallAd ;Return the control index 02
:00401CE5 1974FF FStAdFunc ;
:00401CE8 0874FF FLdPr ;[SR]=[LOCAL_008C]
***********Reference To:[propget]TextBox.Text
:00401CEB 0DA0000000 VCallHresult ;Call ptr_004016B8
:00401CF0 283CFF0100 LitVarI2 ;PushVarInteger 0001
:00401CF5 F502000000 LitI4 ;Push 00000002
:00401CFA 3E70FF FLdZeroAd ;Push DWORD [LOCAL_0090];
:00401CFD 465CFF CVarStr ;
:00401D00 042CFF FLdRfVar ;Push LOCAL_00D4
**********Reference To->msvbvm60.rtcMidCharVar
:00401D03 0A01001000 ImpAdCallFPR4 ;Call ptr_00401020;
:00401D08 042CFF FLdRfVar ;Push LOCAL_00D4
:00401D0B FC45 FnCIntVar ;vbaI2ErrVar
:00401D0D 441CFF CVarI2 ;
:00401D10 FCF674FE FStVar ;
:00401D14 1A74FF FFree1Ad ;Push [LOCAL_008C]; Call
:00401D17 3608005CFF3CFF2C FFreeVar ;Free 0008/2 variants
get_3 = CInt(Mid(Text1.Text, 3, 1))
:00401D22 0470FF FLdRfVar ;Push LOCAL_0090
:00401D25 21 FLdPrThis ;[SR]=[stack2]
:00401D26 0F0003 VCallAd ;Return the control index 02
:00401D29 1974FF FStAdFunc ;
:00401D2C 0874FF FLdPr ;[SR]=[LOCAL_008C]
***********Reference To:[propget]TextBox.Text
:00401D2F 0DA0000000 VCallHresult ;Call ptr_004016B8
:00401D34 283CFF0100 LitVarI2 ;PushVarInteger 0001
:00401D39 F503000000 LitI4 ;Push 00000003
:00401D3E 3E70FF FLdZeroAd ;Push DWORD [LOCAL_0090];
:00401D41 465CFF CVarStr ;
:00401D44 042CFF FLdRfVar ;Push LOCAL_00D4
**********Reference To->msvbvm60.rtcMidCharVar
:00401D47 0A01001000 ImpAdCallFPR4 ;Call ptr_00401020; check stack 0010; Push EAX
:00401D4C 042CFF FLdRfVar ;Push LOCAL_00D4
:00401D4F FC45 FnCIntVar ;vbaI2ErrVar
:00401D51 441CFF CVarI2 ;
:00401D54 FCF664FE FStVar ;
:00401D58 1A74FF FFree1Ad ;Push [LOCAL_008C]; Call
:00401D5B 3608005CFF3CFF2C FFreeVar ;Free 0008/2 variants
get_4 = get_2 + get_3
:00401D66 0474FE FLdRfVar ;Push 變數1 用於相加
:00401D69 0464FE FLdRfVar ;Push 變數2 用於相加
:00401D6C FB945CFF AddVar ;
:00401D70 FCF654FE FStVar ;
If get_1 = get_4 Then
:00401D74 0484FE FLdRfVar ;Push 變數1 用於比較
:00401D77 0454FE FLdRfVar ;Push 變數2 用於比較
:00401D7A FB33 EqVarBool ;
:00401D7C 1CFB01 BranchF ;比較判斷結果
******Possible String Ref To->"good"
Text2.Text = "good" ;正確
:00401D7F 1B0500 LitStr ;Push ptr_00401718
:00401D82 21 FLdPrThis ;[SR]=[stack2]
:00401D83 0F0803 VCallAd ;Return the control index 04
:00401D86 1974FF FStAdFunc ;
:00401D89 0874FF FLdPr ;[SR]=[LOCAL_008C]
***********Reference To:[propput]TextBox.Text
:00401D8C 0DA4000000 VCallHresult ;Call ptr_004016B8
:00401D91 1A74FF FFree1Ad ;Push [LOCAL_008C]; Call
Else
Text2.Text = "bad"
:00401D94 1E1002 Branch ;ESI=00401DAC
******Possible String Ref To->"bad"
:00401D97 1B0600 LitStr ;Push ptr_00401728
:00401D9A 21 FLdPrThis ;[SR]=[stack2]
:00401D9B 0F0803 VCallAd ;Return the control index 04
:00401D9E 1974FF FStAdFunc ;
:00401DA1 0874FF FLdPr ;[SR]=[LOCAL_008C]
***********Reference To:[propput]TextBox.Text
:00401DA4 0DA4000000 VCallHresult ;Call ptr_004016B8
:00401DA9 1A74FF FFree1Ad ;Push [LOCAL_008C]; Call
:00401DAC 13 ExitProcHresult ;
:00401DAD 0000 LargeBos ;IDE beginning of line
注意:以上偽碼中提示的VB原始碼行,可能並不是精確的定位,僅是小弟憑經驗加入的,僅供參考。由於在下對P-CODE以及VBExplorer都不甚瞭解,許多虛擬碼的含義,以及其在VBExplorer中給出的註釋,都不能明瞭箇中的含義,還望瞭解者指點,多謝。
不論如何,根據P-CODE程式碼,我們可以大致分析出粗略的程式流程,變數的使用和定位並不一定精確,許多還要憑您的破解經驗和程式設計經驗。但是,這個粗略的分析可以幫助我們模擬出大致的VB原始碼。
在反向出粗略的VB原始碼的過程中,您要不斷將您寫出的VB程式碼編譯後P-CODE程式碼與源程式反編譯後的P-code程式碼進行比對,儘量使其一致,至少看上去相似。這個過程需要您花些時間了,您要假設,如果你就是作者,你會如何寫,特別是變數的運用,型別的定義,程式設計的習慣以及經驗等。這個過程在不斷的進行中,會使你逐漸積累更多有益的經驗,不知不覺中,你就會有一種“感覺”,以前,那個臺灣寫破解教程的老兄說這個叫“觸機”,大概對應的英文詞是“sense”。總之,您就是知道了,似乎一下就明白了,原來做這個程式的老兄是這樣的,是這個意思。好了,下一步就是驗證我們的思路是否真的就是對的了。
4.著法寶
通常,我們可以用WKTVBDE跟蹤程式P-CODE,看看它在關鍵部分的迴圈,分支走向,在某些關節點(P-CODE虛擬碼,或者是某個VB函式呼叫上)設斷點,這樣,基本上可以將我們模擬出來的VB原始碼中大的框架構造搞清楚,設定好基本的分支條件。那麼,到底在程式的細節實現上,哪裡使用了哪些變數,關鍵的比較點,比較的變數值是怎樣計算得到的,還有什麼隱藏的花招,以及一些細節的東西?為了快速獲得有益的資訊,我們還是應該透過OLLDBG這樣的實時偵錯程式去觀察分析。
在應用OLLDBG除錯VB P-CODE程式碼時,我們應該注意幾點:
一般VB中的使用的區域性變數位置在記憶體中是不確定的,這次除錯和上次除錯的同一變數位置基本是不同的,是動態產生的,所以,不要象除錯其他C編譯或彙編程式那樣,下一個固定的記憶體斷點去發現某些變數的變化(僅僅是個人意見,不一定對)。
VB P-CODE編譯的程式執行時,在主要流程中,通常ESI暫存器指向相應的VB p-code虛擬碼。 所以,除錯時,最好同時開啟相應程式的P-CODE虛擬碼(例如執行VBExplorer,並開啟相應的程式。為了便於分析,可以是同樣程式的複製副本),以供參考,檢視程式的實際流程。
通常,vb 程式執行在虛擬機器(MSVBVM60.DLL)中 ,因此,當您使用OLLDBG開啟一個vb p-code程式後,應該在選單中選擇“view”選項,然後再進入選擇“Executable modules”, 並在其中的“MSVBVM60”行上,點選滑鼠右鍵,然後選“view name”。如此,可以直接檢視VB執行庫中的函式名,查詢有關的函式名,在常用的函式名上點選,並設定斷點。
例如:在rtcMidCharVar上設定斷點:
在我得機器上是:7352B403 > 55 PUSH EBP
例如:設定條件斷點 esi = = 401BEF ;ESI指向的P-CODE程式碼,應該是你在分析目標程式後,認為重要的呼叫了MID函式的位置。參考上面的演示程式,我們假定要檢視兩個MID函式被呼叫的位置,這兩個位置可能是:
語句If Mid(Text1.Text, i, 1) > "9" Or Mid(Text1.Text, i, 1) < "0" 中的兩個呼叫了MID的地方(p-code程式碼的相對位置):00401BFE 和 00401C23(VBExplorer 中看到的)
當程式中斷在您設定的斷點後,你可以逐步跟蹤程式了,為了把握住程式的流向,您要時刻關注ESI值的變化,它通常在40xxxx範圍內,它明確地指向VB P-CODE虛擬碼的流向,你不用擔心不知道自己所在的位置。你可以隨時切換到VBExplorer中,看看程式到底跑到哪裡去了。
在您除錯的過程中,您會發CALL AX,應該單步跟進去,它通常會帶你返回那個正被除錯的VB程式主域(或叫“領空”,學臺灣人的說法),一般附近是一些JMP長跳轉,這些是程式中需要呼叫函式,應該給予重視,可以嘗試在相關函式上下斷點。
當您看到call bx時,通常程式要呼叫真正的函式執行功能,你應該跟進去,一般在執行P-CODE比較偽指令的過程中,你會發現一個call bx,一定要跟進去,通常會它引導你看到真正的註冊碼以及你輸入的假註冊碼進行比較。透過觀察堆疊的顯示,你就可以看到他們,兩個可愛的字串(通常出現在OLLYDBG的除錯視窗的右下方)。
跟蹤VB程式時,通常會看到如下的程式碼:
7353F7B7 3BFC CMP EDI,ESP
7353F7B9 0F85 D67D0000 JNZ MSVBVM60.73547595
7353F7BF 33C0 XOR EAX,EAX
7353F7C1 8A06 MOV AL,BYTE PTR DS:[ESI]
7353F7C3 46 INC ESI
7353F7C4 FF2485 58FA5373 JMP DWORD PTR DS:[EAX*4+7353FA58]
7353F7CB 0FB70E MOVZX ECX,WORD PTR DS:[ESI]
7353F7CE 0FB77E 02 MOVZX EDI,WORD PTR DS:[ESI+2]
7353F7D2 83C6 04 ADD ESI,4
7353F7D5 03FC ADD EDI,ESP
7353F7D7 8B55 AC MOV EDX,DWORD PTR SS:[EBP-54]
7353F7DA 8B048A MOV EAX,DWORD PTR DS:[EDX+ECX*4]
7353F7DD 0BC0 OR EAX,EAX
7353F7DF 90 NOP
7353F7E0 0F84 027F0000 JE MSVBVM60.735476E8
7353F7E6 803D B4115573 00 CMP BYTE PTR DS:[735511B4],0
7353F7ED 0F85 037F0000 JNZ MSVBVM60.735476F6
7353F7F3 FFD0 CALL EAX
7353F7F5 3BFC CMP EDI,ESP
7353F7F7 0F85 987D0000 JNZ MSVBVM60.73547595
7353F7FD 50 PUSH EAX
7353F7FE 33C0 XOR EAX,EAX
7353F800 8A06 MOV AL,BYTE PTR DS:[ESI]
7353F802 46 INC ESI
7353F803 FF2485 58FA5373 JMP DWORD PTR DS:[EAX*4+7353FA58]
7353F80A 0FB706 MOVZX EAX,WORD PTR DS:[ESI]
其中:
7353F7BF 33C0 XOR EAX,EAX
7353F7C1 8A06 MOV AL,BYTE PTR DS:[ESI]
7353F7C3 46 INC ESI
7353F7C4 FF2485 58FA5373 JMP DWORD PTR DS:[EAX*4+7353FA58]
既是虛擬碼的執行模板。JMP指令轉入偽指令的執行,不斷按下“F8”,盯著esi暫存器的變化,參照vbexplorer中提示的p-code,你就不會迷失方向(通常是這樣。當然,如果你按錯了鍵,那就是你自己的事了,別怪我沒提醒你)
大結局
關於最後的修改VB P-CODE程式碼,暴力破解法,據我所知一般只要能將重要的轉移指令改變就可以了。無非是在您選好的比較指令的位置將BranchF(虛擬碼1c)BranchT(1d) 或者Branch(1e)改來改去。別的好招我還不會呢,等著我們們繼續切磋。
有空的朋友,還可以分析程式中的演算法,只要花功夫,沒什麼看不懂的。除非程式設計序的那位憋著勁和我們們作對,不怕,我們不用他的軟體了還不行?我是菜鳥,我怕誰?
夠了,說了一堆有用沒用的廢話,您自己看著辦8,您也聽累了,我手也酸了。總之,vb p-code畢竟是由高階語言轉換來的,應該不難分析和跟蹤,只是特點不同,掌握了基本的要點,用OLLDBG跟蹤沒什麼難的。現在又有WKTVBDE 和vbexplorer助陣,一邊捏著P-CODE,一邊瞄著ESI, 祭起OLLYDBG,一手按著F8,您說,我們還怕誰呀?
什麼逆向工程,什麼VB, V JQK,誰是破解高手?不就是花時間嘛。
唉,所以高手都不來發言了,所以,您和我,還是菜鳥。苦惱中。。。。
要是那位高手作個OLLDBG的VB P-CODE外掛,一遇到VB p-code中JMP DWORD PTR DS:[EAX*4+&*%$@$^] 就顯示相關的P-CODE指令就更方便了,尤其期待中。。。。
相關文章
- 淺談VB6逆向工程(1)2004-12-22
- 淺談VB6逆向工程(2)2004-12-23
- 淺談VB6逆向工程(3)2004-12-25
- 淺談VB6逆向工程(4)2004-12-27
- 淺談VB6逆向工程(5)2004-12-27
- mybatis入門基礎(九)----逆向工程2015-07-16MyBatis
- iOS 逆向程式設計(入門條件)2020-12-12iOS程式設計
- 關於破解以p-code方式編譯的VB程式一例 (2千字)2002-04-01編譯
- idea 中使用Mybatis Generator逆向工程生成程式碼2020-12-14IdeaMyBatis
- 翻譯 | 一行 JavaScript 程式碼的逆向工程2017-08-07JavaScript
- 【原創】VB
P-code -- 虛擬碼的奧祕2004-12-26
- 入門程式碼程式設計2023-12-14程式設計
- 如何製作VB的P-Code偵錯程式(譯自:WKTVBDE的作者)2015-11-15
- 回顧一下MyBatis逆向工程——自動生成程式碼2018-07-10MyBatis
- 從 Java 程式碼逆向工程生成 UML 類圖和序列圖2009-04-14Java
- Gerrit程式碼Review入門2017-10-22View
- C#入門程式碼2006-04-23C#
- 關於VB P-CODE的一些總結 (10千字)2015-11-15
- iOS逆向 程式碼注入+Hook2019-12-04iOSHook
- iOS逆向之 程式碼注入2018-05-15iOS
- 逆向常用python程式碼2024-03-26Python
- 淺談軟體工程中的程式碼評審2018-10-14軟體工程
- 淺談軟體工程師的程式碼素養2018-05-18軟體工程工程師
- 【倉頡】入門文件程式碼圓周率估算程式碼更正2024-08-04
- iOS逆向入門解析2018-05-09iOS
- 逆向破解js程式碼加密,程式碼混淆不是難事2019-05-12JS加密
- 淺談前端/軟體工程師的程式碼素養2018-05-08前端軟體工程工程師
- iOS逆向——Method Swizzle及WeChat註冊、登入程式碼示例2019-10-17iOS
- java中是否有控制程式碼的說?2009-02-23Java
- 程式碼審計入門總結2020-08-19
- Java程式碼混淆工具入門——Allatori~2021-08-19Java
- Java程式碼審計入門篇2018-06-28Java
- VB 螢幕融化超級惡搞程式程式碼2013-07-01
- App加固中的程式碼混淆功能,讓逆向工程師很頭疼2023-11-16APP工程師
- Get_Next的VB程式碼2015-10-05
- 想用就用,VB基礎程式碼 (轉)2007-08-17
- iOS彙編入門教程(二)在Xcode工程中嵌入彙編程式碼2018-03-23iOSXCode
- MSIL入門(一)C#程式碼與IL程式碼對比2020-07-05C#