.NET體系中的源程序安全問題(3)
發(fā)布時間:2008-08-07 閱讀數(shù): 次 來源:網(wǎng)樂原科技
三、反向工程
當(dāng)程序集以MSIL而不是機(jī)器代碼的形式發(fā)布時,最令人關(guān)心的問題應(yīng)該就是安全。正如前面所介紹的,程序集包含了關(guān)于包里面所有模塊的manifest以及詳細(xì)描述各個模塊的元數(shù)據(jù)。.NET SDK 提供了一個名為ILDASM的工具,它是一個IL反匯編程序,能夠從模塊反匯編出IL代碼以及應(yīng)用程序中各個模塊的元數(shù)據(jù)說明。從Listing 1可以看出,利用ILDASM對代碼實施反向工程是極為方便的。
【Listing 1】下面是IL反匯編程序ILDASM輸出的部分結(jié)果。
它顯示的是應(yīng)用中一個名為LeavingMessage的私有方法,后
面部分是調(diào)用LeavingMessage方法的代碼。CLR把參數(shù)壓入
棧,執(zhí)行調(diào)用,然后恢復(fù)棧為下一個操作做好準(zhǔn)備。
.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)認(rèn)識到了這個問題,一個常見的反駁意見是:在現(xiàn)實中,應(yīng)用的規(guī)模很大,IL反匯編輸出結(jié)果的規(guī)模將超過可以忍受的限度。但是,它可能使一個業(yè)余愛好者望而卻步,卻不能阻止一個真正對代碼感興趣的人。實際情況是:與機(jī)器代碼的反匯編結(jié)果相比,ILDASM的反匯編結(jié)果要容易閱讀得多,任何對此感興趣的組織都能夠從IL反匯編結(jié)果了解到大量有關(guān)應(yīng)用的信息。
按照Microsoft的意見,要保證企業(yè)機(jī)密安全,我們應(yīng)該把所有包含企業(yè)機(jī)密的模塊放到受保護(hù)的服務(wù)器上。對于ASP.NET客戶機(jī)/服務(wù)器應(yīng)用來說這沒問題,但對于標(biāo)準(zhǔn)的桌面應(yīng)用來說它行不通。那么,如何才能對知識產(chǎn)權(quán)進(jìn)行保護(hù)呢?MSIL匯編程序文檔提到了一個命令行參數(shù)/owner:
ilasm ... /owner
ilasm ... /owner=fergus
這個選項用密碼加密代碼,防止代碼被反匯編。問題在于Microsoft準(zhǔn)備取消這個選項,因為它看起來不是一種好方法。這樣,對于用受管理的C++、C#或VB為.NET Beta 1編寫的桌面應(yīng)用來說,要保護(hù)知識產(chǎn)權(quán)將非常困難。
但希望仍舊存在。在.NET最終發(fā)布之前,Microsoft可能提供一個模糊器(Obfuscator)程序,它能夠修改MSIL的私有方法,使得除CLR JIT編譯器之外沒有人能夠閱讀這些私有方法。但是,它不會隱藏應(yīng)用的公用(全局)方法以及對外部庫的調(diào)用,這是因為:如果修改全局調(diào)用的名字或者隱藏這些調(diào)用,CLR將不能再鏈接到外部函數(shù)。因此,黑客們?nèi)耘f能夠通過查看IL代碼,找出應(yīng)用調(diào)用系統(tǒng)DLL的各種信息。這樣,現(xiàn)在我們只能用一種方法對桌面應(yīng)用的知識產(chǎn)權(quán)進(jìn)行保護(hù),即用非受管理的C++編寫關(guān)鍵性代碼,然后從VB.NET通過為訪問非受管理代碼提供的交互機(jī)制訪問它。當(dāng)然,對于VB開發(fā)者來說,這可能比較困難。
由于所有受管理代碼必須以MSIL形式發(fā)布,所以在發(fā)布之前代碼不能進(jìn)行JIT編譯。但是,在目標(biāo)機(jī)器上安裝應(yīng)用的時候,我們可以把代碼編譯成匯編形式。從表面上看來這很不錯,但代碼在安裝盤上仍舊是IL形式,我們可以手工從安裝盤提取出代碼,然而分別對它們進(jìn)行反匯編。由于應(yīng)用安裝完成后以編譯代碼而不是IL的形式存在,除了安全之外,它還能夠少量地提高應(yīng)用運(yùn)行的速度,因為此時我們不再需要JIT編譯器編譯IL代碼。