visual basic & P-code雜談(一)
p-code,可以稱為packed-code(壓縮程式碼),也可叫做pseudo-code(虛擬碼)。其最早起源已經不可考;但據說最早見於一個pascal編譯器使用的編譯技術,以後微軟在basic、c、vb乃至vc中使用了類似的編譯技術。
所謂p-code,其基本工作原理是編譯器先把執行程式編譯為比80X86機器碼緊湊得多的中間程式碼形式,然後在連結時把一個小工作引擎嵌入執行程式中,最後在執行時由此工作引擎把P-CODE解釋為本地機器碼實際執行,所以叫做packed-code;同時又由於此程式碼並不是最終的機器碼形式,實際上是“變形的原始碼”,所以也被稱為pseudo-code。依靠P-code編譯技術,使得程式語言不依賴於機器或照作平臺稱為可能。
雖然目前p-code編譯形式大多見於vb,但java,powerbuilder的編譯實質也是一樣;最新的microsoft
visual studio.net,只是將名稱換成“中間語言(Microsoft Intermediate Language)”,不管怎麼解釋我還是不能理解IL與p-code的不同。(參考http://windows.oreilly.com/news/hejlsberg_0800.html《Deep
Inside C#:
An Interview with Microsoft Chief Architect Anders Hejlsberg》)。
因為vb3、4都是使用P-code編譯形式;也因為p-code編譯的程式碼實際只是“變形的原始碼”,所以只要我們能理解其對應機制,就能做出反編譯器來,所以Dodi's
vb3/4 disassembler來了,java反編譯器來了,對付最新microsoft .net的反編譯程式也可以被得到。
為什麼見不到vb5/6 p-code的反編譯器,現在有了,就是exdec及建立在其基礎上的wkt vb p-code debugger;而且2001年就有人寫出一個vb6
add-in來實現vb6原始碼-> P-code轉換。
第2部分:理解mid()函式
Private
Sub Command1_Click()
Dim a, b As String
a = Text1.Text
b =
Mid(a, 2, 3)
End Sub
將上述程式碼用vb6分別編譯為native code和P-code
函式原型Mid(string, start[, length])
(1)wdasm反彙編native code
:00401D62 C745A403000000 mov [ebp-5C],
00000003
:00401D69 C7459C02000000 mov [ebp-64],
00000002
* Reference To: MSVBVM60.rtcMidCharVar, Ord:0278h
|
:00401D70 FF153C104000
Call dword ptr [0040103C]
(2) exdec反編譯P-code
401A63: 28 LitVarI2: ( local_00E4
) 0x3 (3)
401A68: f5 LitI4:
0x2 2 (....)
401A6D: 04 FLdRfVar
local_0094
401A70: 04 FLdRfVar
local_00F4
401A73: 0a ImpAdCallFPR4:
rtcMidCharVar