P-code & visual basic雜談(一) (2千字)

看雪資料發表於2015-11-15

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

相關文章