史萊姆論壇

返回   史萊姆論壇 > 專業主討論區 > 程式語言討論區
忘記密碼?
論壇說明

歡迎您來到『史萊姆論壇』 ^___^

您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的!

請點擊這裡:『註冊成為我們的一份子!』

Google 提供的廣告


發文 回覆
 
主題工具 顯示模式
舊 2004-01-28, 12:08 PM   #1
psac
榮譽會員
 
psac 的頭像
榮譽勳章
UID - 3662
在線等級: 級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時
註冊日期: 2002-12-07
住址: 木柵市立動物園
文章: 17381
現金: 5253 金幣
資產: 33853 金幣
預設 關於VB P-CODE的一些總結

關於VB P-CODE的一些總結

前言:到網上查PCODE的資料,到了一個講Fight Against Crack的網站上,那個作者講了許多陰毒的招數後,還特別說明,如果是VB程序,最好把它做成P-CODE,這會大大增加破解的難度。事實真的如此嗎?WKT的一個大俠卻說:We are going to show that protecting a VB application is a very difficult task.The last Microsoft's invention on VB, the 'p-code', it's a delicious bite for reverse engineers. I'll show that a 'p-compiled' application may be easier to crack that a conventional compiled one.
不知是不是我孤陋寡聞,總覺得現在關於VB P-CODE的資料少之又少,不管國內國外只能找到各位老大們為數不多的幾篇教程(很多也是說「我猜想」之類拿不準的話),《加密與解密》上關於這個也是一筆帶過(大概是為續集著想^_^),可能是大俠覺得這個太簡單不屑於講,或是哪裡已經有非常系統全面的介紹。總之以前我是一見是VB就害怕,再見是PCODE就投降,這大概就是人家用P-CODE對付破解的原因。這幾天終於下決心自己寫了幾個程序試驗,再結合各位老大的文章,總結出一點東西,非常不全面,希望大家多多指教,多多補充。

「工欲善其事,必先利其器。」那句古話好像是這麼說的。我們找的工具有:WKTVBDebug(動態破解用,相當於PCODE裡的SOFTICE)EXDEC(靜態分析,相當於W32DASM)SmartCheck(可以作輔助用)

要想破解PCODE程序,關鍵要理解裡面的「助記符」(它又不同於彙編語言的「mnemonics」,我不知道該怎麼表示了)的作用,PCODE的助記符乍看上去很亂,好像比彙編還難,其實它們都是由幾部分組成的。比如CVarStr就是由三部分組成(詳見下文)。VB PCODE中一般的「助記符」如下面所顯示:(只總結出了一點,懇請各位補充)

表示資料類型的:

I2 ---- Integer,佔一個字元的整數(彙編裡的BYTE)
I4 ---- Integer,佔兩個字元的整數(彙編裡的WORD)
I8 ---- Integer,佔四個字元的整數(彙編裡的DWORD)
UI4---- Unsigned Integer,無符號整數
UI8---- Unsigned Integer,無符號整數
R4 ---- Real,單精度實數(Single)
R8 ---- Real,雙精度實數(Double)
Str---- String,字串串類型
Var---- Variant,變數類型。這就是BASIC特殊的地方,它允許用戶在使用變數前不進行聲明,這種不聲明的變數就用這種類型存儲,它可以包括數字、字串等各種類型。我看M$的這個玩意兒沒給用戶帶來方便,只能讓一些初學編程的菜鳥思維混亂,讓咱們破解時也非常鬱悶。它的存儲方式非常奇怪,比方說你看到一個VARIANT類型的資料被放到記憶體裡了,你跟過去找,結果什麼也找不到。看雪書上說應該D *(EAX+8),原來它真正的資料往後挪了8個字元,真不知在搞什麼.....BTW:如果是一個數值類型的資料,它的位址向後移8個字元即為真正的數值,如果是一個字串串型的資料,它的位址向後移8個字元即為指向一個UNICODE字串的游標。

表示堆棧操作的:(PCODE沒有暫存器,全部通過堆棧傳送資料,因此非常重要)

St ---- Store,把當前棧頂的資料放在記憶體裡
Ld ---- Load,把記憶體某處的資料壓入堆棧
Lit---- Literal,把一個「立即數」壓入堆棧

其它重要的:

C ---- Convert,資料轉換。如CI4I2即把BYTE擴充為WORD(I2->I4)
Eq ---- Equal,判斷是否相等,並把結果(0或1)入棧
Lt ---- 判斷是否小於
Gt ---- 判斷是否大於
Len---- 得到字串長度

跳轉指令:

Branch ---- 無條件跳轉
BranchT ---- 棧頂資料為真則跳
BranchF ---- 棧頂資料為假則跳

一些算術運算:

Add , Sub 等等應該都比較好認吧。

從一篇介紹PCODE的文章裡抄來一些,不知有沒有用:

Prefix Control
------------------------------------------------------------------------------------
cbo Combo box
chk Check box
cmd Command Button
dir Directory box
drv Drive list box
fil File list box
fra Frame
frm Form
grd Grid
hsb Horizontal scrollbar
img Image
lbl Label
lin Line
lst List box
mnu Menu
ole OLE client
opt Option button
pic Picture Box
shp Shape
tmr Timer
txt Text box
vsb Vertical scrollbar
-----------------------------------------------------------------------------------------

還有一些不太清楚的,都是我的猜想,希望大俠解釋:

Call ---- 使用程序
Free ---- 釋放記憶體空間
Rf ---- 局部變數????
Pr ---- ????
Ad ---- 是不是Address??
HardType--是幹什麼的?

這些組合在一起就成了多種多樣的指令,很有趣吧。

還有一個要特別強調的是PCODE的堆棧,PCODE幾乎所有的指令都要對堆棧進行操作,有許多指令都是針對棧頂的一個或兩個資料進行操作,因此在動態偵錯PCODE時要十分注意右邊顯示的堆棧區,並經常檢視記憶體,這樣才能理解指令的意義。

下面來實踐一下,執行起塵封已久的VB,在FORM上放一個TEXT1,一個BUTTON1,雙按Button1,在下面輸入:

Private Sub Command1_Click()
st1 = Text1.Text
st2 = ""
m = Len(Text1.Text)
For i = 1 To m
st2 = st2 + Mid$(Text1.Text, m - i + 1, 1)
Next i
MsgBox st2, vbOKOnly, "CRACK"
End Sub

呵呵,很簡單是不是。按一下按鈕就把TEXT裡的文本反過來顯示在訊息框裡。
下面來「產生工程」,注意一定要在「選項」裡選項產生P-CODE文件。然後用Exdec分析一下:

Proc: 401a90
4019B0: 04 FLdRfVar local_008C ;好像是一個指向TEXT的游標
4019B3: 21 FLdPrThis ;先給一個下馬威,前幾句全不太明白!
4019B4: 0f VCallAd text ;用WKTVBDebug過這一句時能看到Form1.text1
4019B7: 19 FStAdFunc local_0088 ;猜想應該是取得關鍵之類的事情
4019BA: 08 FLdPr local_0088 ;
4019BD: 0d VCallHresult get__ipropTEXTEDIT ;使用,從字面上可以看出是GetText
4019C2: 3e FLdZeroAd local_008C ;好像壓入一個指向上面文本的游標,不太清楚,反正上面這個程序很傳統啦,幾乎從文本框讀數都是這樣
4019C5: 46 CVarStr local_00AC ;把上面得到的字串轉為Var格式
4019C8: Lead1/f6 FStVar ;再把這個VAR資料入棧 st1
4019CC: 1a FFree1Ad local_0088 ;釋放前面的空間
4019CF: 3a LitVarStr: ( local_00CC ) ;壓入一個立即數:空字串st2=""
4019D4: Lead2/00 FStVarCopy
4019D8: 04 FLdRfVar local_008C
4019DB: 21 FLdPrThis
4019DC: 0f VCallAd text
4019DF: 19 FStAdFunc local_0088
4019E2: 08 FLdPr local_0088
4019E5: 0d VCallHresult get__ipropTEXTEDIT ;和上面相同,得到字串
4019EA: 6c ILdRf local_008C ;壓入字串
4019ED: 4a FnLenStr ;得到字串的長度m
4019EE: Lead2/69 CVarI4 local_00CC ;轉為VAR類型
4019F2: Lead1/f6 FStVar ;VAR類型的長度入棧
4019F6: 2f FFree1Str local_008C ;釋放記憶體空間
4019F9: 1a FFree1Ad local_0088
4019FC: 28 LitVarI2: ( local_00FC ) 0x1 (1) ;壓入一個立即數0x1
401A01: 04 FLdRfVar local_00EC ;local_00EC是循環變數i
401A04: 04 FLdRfVar local_00DC ;這個是上面得到的長度m
401A07: Lead3/68 ForVar: (when done) 401A67 ;FOR i=1 to m 開始循環
401A0D: 04 FLdRfVar local_008C
401A10: 21 FLdPrThis
401A11: 0f VCallAd text
401A14: 19 FStAdFunc local_0088
401A17: 08 FLdPr local_0088
401A1A: 0d VCallHresult get__ipropTEXTEDIT ;和上面相同的程序,得到字串
401A1F: 04 FLdRfVar local_00BC ;把local_BC壓入,這實際上是st2
401A22: 28 LitVarI2: ( local_013C ) 0x1 (1) ;壓一個0x1,CALL的參數
401A27: 04 FLdRfVar local_00DC ;字串長度m
401A2A: 04 FLdRfVar local_00EC ;循環變數i
401A2D: Lead0/9c SubVar ;相減 m-i
401A31: 28 LitVarI2: ( local_00CC ) 0x1 (1) ;再壓入一個0x1
401A36: Lead0/94 AddVar local_012C ;再加1, m-i+1,CALL的參數
401A3A: Lead1/22 CI4Var ;轉成整數型
401A3C: 6c ILdRf local_008C ;壓入,作為下面CALL的參數
401A3F: 0b ImpAdCallI2 ;這是rtcMidCharBStr,源碼中的Mid$()
401A44: 46 CVarStr local_014C ;把取得的字串轉成Var型
401A47: Lead0/94 AddVar local_015C ;把新取得的字串和上面的401A1F處的st2連起來
401A4B: Lead1/f6 FStVar
401A4F: 2f FFree1Str local_008C
401A52: 1a FFree1Ad local_0088 ;釋放
401A55: 36 FFreeVar
401A5E: 04 FLdRfVar local_00EC ;設好循環變數
401A61: Lead3/7e NextStepVar: (continue) 401A0D ;NEXT i,循環變數+1,直到結束
401A67: 27 LitVar_Missing ;VB裡面那些帶[]的可選參數,如果不加設定
401A6A: 27 LitVar_Missing ;就會變成這種Missing或NULL的形式
401A6D: 3a LitVarStr: ( local_00CC ) CRACK ;壓入字串,MsgBox的標題
401A72: 4e FStVarCopyObj local_00AC ;把剛壓入的字串複製到local_AC
401A75: 04 FLdRfVar local_00AC ;再壓進去一次(???)
401A78: f5 LitI4: 0x0 0 (....) ;訊息框的樣式 vbOKOnly
401A7D: 04 FLdRfVar local_00BC ;這是上面計算得到的反轉字串
401A80: 0a ImpAdCallFPR4: ;這個是rtcMsgBox,共有五個參數
401A85: 36 FFreeVar
401A8E: 13 ExitProcHresult ;結束程序

我盡量想把分析寫得明白一些,但還是有幾句解釋不清,希望精通PCODE的大俠解釋一下,小弟代表廣大菜鳥同胞感激不盡。
psac 目前離線  
送花文章: 3, 收花文章: 1631 篇, 收花: 3205 次
回覆時引用此帖
發文 回覆



發表規則
不可以發文
不可以回覆主題
不可以上傳附加檔案
不可以編輯您的文章

論壇啟用 BB 語法
論壇啟用 表情符號
論壇啟用 [IMG] 語法
論壇禁用 HTML 語法
Trackbacks are 禁用
Pingbacks are 禁用
Refbacks are 禁用


所有時間均為台北時間。現在的時間是 08:45 PM


Powered by vBulletin® 版本 3.6.8
版權所有 ©2000 - 2024, Jelsoft Enterprises Ltd.


SEO by vBSEO 3.6.1