直播中
【Listing 1】下面是IL反匯編程序ILDASM輸出的部分結果。
它顯示的是應用中一個名為LeavingMessage的私有方法,后
面部分是調(diào)用LeavingMessage方法的代碼。CLR把參數(shù)壓入
棧,執(zhí)行調(diào)用,然后恢復棧為下一個操作做好準備。
.method private instance void LeavingMessage(class System.String& strText) il managed
{
// Code size 10 (0xa)
.maxstack 8
//000059: Private Sub LeavingMessage(ByRef strText As String)
IL_0000: nop
.line 60
//000060: debug.Write(strText)
IL_0001: ldarg.1
IL_0002: ldind.ref
IL_0003: call void [System]System.Diagnostics.Debug::
Write(class System.String)
.line 61
//000061: End Sub
IL_0008: nop
IL_0009: ret
} // end of method Form1::LeavingMessage
Code to call LeavingMessage Sub
finally
{
IL_002d: nop
.line 73
//000073: LeavingMessage("Goodbye Dear Friend")
IL_002e: ldarg.0
IL_002f: ldstr "Goodbye Dear Friend"
IL_0034: stloc.3
IL_0035: ldloca.s _Vb_t_string_0
IL_0037: callvirt instance void
GoodbyeVB6.Form1::LeavingMessage(class System.String&)
IL_003c: endfinally
.line 74
//000074: End Try
} // end handler
人們已經(jīng)認識到了這個問題,一個常見的反駁意見是:在現(xiàn)實中,應用的規(guī)模很大,IL反匯編輸出結果的規(guī)模將超過可以忍受的限度。但是,它可能使一個業(yè)余愛好者望而卻步,卻不能阻止一個真正對代碼感興趣的人。實際情況是:與機器代碼的反匯編結果相比,ILDASM的反匯編結果要容易閱讀得多,任何對此感興趣的組織都能夠從IL反匯編結果了解到大量有關應用的信息。
按照Microsoft的意見,要保證企業(yè)機密安全,我們應該把所有包含企業(yè)機密的模塊放到受保護的服務器上。對于ASP.NET客戶機/服務器應用來說這沒問題,但對于標準的桌面應用來說它行不通。那么,如何才能對知識產(chǎn)權進行保護呢?MSIL匯編程序文檔提到了一個命令行參數(shù)/owner:
ilasm ... /owner
ilasm ... /owner=fergus
這個選項用密碼加密代碼,防止代碼被反匯編。問題在于Microsoft準備取消這個選項,因為它看起來不是一種好方法。這樣,對于用受管理的C++、C#或VB為.NET Beta 1編寫的桌面應用來說,要保護知識產(chǎn)權將非常困難。
但希望仍舊存在。在.NET最終發(fā)布之前,Microsoft可能提供一個模糊器(Obfuscator)程序,它能夠修改MSIL的私有方法,使得除CLR JIT編譯器之外沒有人能夠閱讀這些私有方法。但是,它不會隱藏應用的公用(全局)方法以及對外部庫的調(diào)用,這是因為:如果修改全局調(diào)用的名字或者隱藏這些調(diào)用,CLR將不能再鏈接到外部函數(shù)。因此,黑客們?nèi)耘f能夠通過查看IL代碼,找出應用調(diào)用系統(tǒng)DLL的各種信息。這樣,現(xiàn)在我們只能用一種方法對桌面應用的知識產(chǎn)權進行保護,即用非受管理的C++編寫關鍵性代碼,然后從VB.NET通過為訪問非受管理代碼提供的交互機制訪問它。當然,對于VB開發(fā)者來說,這可能比較困難。
由于所有受管理代碼必須以MSIL形式發(fā)布,所以在發(fā)布之前代碼不能進行JIT編譯。但是,在目標機器上安裝應用的時候,我們可以把代碼編譯成匯編形式。從表面上看來這很不錯,但代碼在安裝盤上仍舊是IL形式,我們可以手工從安裝盤提取出代碼,然而分別對它們進行反匯編。由于應用安裝完成后以編譯代碼而不是IL的形式存在,除了安全之外,它還能夠少量地提高應用運行的速度,因為此時我們不再需要JIT編譯器編譯IL代碼。