利用Mono.Cecil動態修改程式集來破解商業組件(僅用於研究學習)

來源:互聯網
上載者:User

標籤:

原文:利用Mono.Cecil動態修改程式集來破解商業組件(僅用於研究學習)

     Mono.Cecil是一個強大的MSIL的注入工具,利用它可以實現動態建立程式集,也可以實現攔截器橫向切入動態方法,甚至還可以修改已有的程式集,並且它支援多個運行時架構上例如:.net2.0/3.5/4.0,以及silverlight程式

官方地址:http://www.mono-project.com/Cecil

     首先,我先假想有一個這樣的商業組件,該組件滿足了以下條件:

1. 該程式集的代碼被混淆過了

2. 該程式集被強命名簽名過了

3. 該程式集的UI介面被加上了著作權資訊,例如浮水印等等

     這裡我引用的是之前寫的一篇文章中的使用者登入的組件(http://www.cnblogs.com/liping13599168/archive/2010/05/07/1729357.html),並將其進行改造成一個Silverlight組件,項目結構

其中BusinessComponent類庫作為選定的”商業組件",這裡編寫一個CopyRight類,作為浮水印的列印資訊:

internal sealed class Copyright 

    internal void SetRightInfo(TextBlock textBlock) 
    { 
        textBlock.Text = "This is a watermark."; 
    } 
}

運行效果為:

可以看到組件上面附帶一個著作權資訊效果

      接著,要對BusinessComponent進行強命名簽名,選擇項目右鍵,如下設定:

建立一個snk檔案,這個檔案利用RSA加密包含著公開金鑰和私密金鑰的資訊,對該組件編譯會把它編譯進去了。

這個snk到底做什麼用的呢?一會兒大家看著就知道了。

      最後,我要利用Dotfuscator混淆工具,對於BusinessComponent.dll進行代碼混淆

由於我這裡的Dotfuscator使用的老版本的4.2,所以不支援對於Sliverlight程式集的混淆,有興趣的朋友可以自己下載試試,官方地址是:http://www.preemptive.com

 

      好了,到這裡,一個BusinessComponent商業組件的雛形設計好了。現在拿起手上的工具——Mono.Cecil去改造它了。

首先官方下載了一個mono.cecil的項目,開啟工程主動去編譯一下,在目錄Silverlight_Release就能夠擷取Mono.Cecil.dll

      那麼,把它引入到項目中來,在頁面中加入一個按鈕,點擊觸發事件程式:

var entryPointPart = Deployment.Current.Parts.First(asmPart => asmPart.Source == "BusinessComponent.dll"); 
var entryPointResourceInfo = Application.GetResourceStream(new Uri(entryPointPart.Source, UriKind.Relative)); 
var module = ModuleDefinition.ReadModule(entryPointResourceInfo.Stream);
var type = module.Types.FirstOrDefault(o => o.Name == "Copyright"); 
var method = type.Methods.FirstOrDefault(o => o.Name == "SetRightInfo"); 
Instruction instruction = method.Body.Instructions[2]; 
instruction.Operand = ""; 
module.Write("C:\\BusinessComponent.dll"); 

      其中module擷取程式集中的Module模組,module.Types可以得到程式集中的所有類型:

選擇Type的類型名稱為Copyright,通過type.Methods可以得到該類型得到的所有方法:

選擇Method的名稱為SetRightInfo,method.Body.Instructions可以得到該方法裡面的IL堆棧調用資訊:

我們看到索引2這行的資訊,ldstr是定義一個字串常量的方式,而索引3通過索引2行的值,賦值給TextBlock中,請查看Copyright的代碼就可以知道。於是:

Instruction instruction = method.Body.Instructions[2]; 
instruction.Operand = "";

這樣就可以把該浮水印資訊去除了,是不是很簡單呢:)

最後一行module.Write("C:\\BusinessComponent.dll");就是將修改過後的程式集重新寫入到一個新的程式集中;

執行程式,在C盤就得到一個BusinessComponent的新程式集了。

現在,我重新引入該新的程式集,看是否浮水印資訊會被去掉,重新編譯,發現編譯出錯:

      這是為什嗎?這就是我上面提到的利用snk的強命名簽名了,它的目的是為了防止你的程式集被非法篡改而設定的,而需要破解它就需要它的私密金鑰了,可是作為一個真正的商業組件,我們是沒有辦法得到它的私密金鑰,那是不是意味著沒辦法破解了呢。

那麼我重新通過sn.exe進行重新簽名:

sn –R BusinessComponent.dll mykey.snk

顯示公開金鑰不配對。這個是顯然的,因為之前通過VS的Sign標籤人工設定business.snk,它採用的是這個檔案的公開金鑰,而mykey.snk就要採用它自己的公開金鑰了。

既然無法破解,那我就去改掉它的簽名,利用我自訂的公開金鑰和私密金鑰去做簽名,而恰恰好,Mono.Cecil就可以滿足你的需要。

     

開啟VS2010命令提示視窗,在C盤上輸入:

sn -k mykey.snk

這樣就隨機產生了一條包含公開金鑰和私密金鑰的RSA檔案,接著要抽取出它的公開金鑰,輸入:

sn –p mykey.snk mykey.PublicKey

緊接著輸入:

sn –tp mykey.PublicKey

就可以得到公開金鑰的資料,例如publicKey以及publicKeyToken

得到了兩串字串,把它們都複製出來,繼續在剛才的按鈕代碼中補充:

var entryPointPart = Deployment.Current.Parts.First(asmPart => asmPart.Source == "BusinessComponent.dll"); 
var entryPointResourceInfo = Application.GetResourceStream(new Uri(entryPointPart.Source, UriKind.Relative)); 
var module = ModuleDefinition.ReadModule(entryPointResourceInfo.Stream); 
module.Assembly.Name.PublicKey = this.GetPublicKey(); 
module.Assembly.Name.PublicKeyToken = this.GetPubliKeyToken(); 

 

private byte[] GetPublicKey() 

    string s = "0024000004800000940000000602000000240000525341310004000001000100c5f2c7d8057257ea3640b93b7a98b1a5501718196589973b09b94cf47fb246c8ad86ae688caa36959d9793702c27ce198a447d69ba0ddac70075fab16748999f066795de472dfb5cd9347a10f967e750ca388aaa9a66619291003345b0176dec0008d3d88986c4605c0d60e3b6563f96984c6d28aeb4bf2d672e8d2d2123c394";
    return this.StrToHexBytes(s); 

private byte[] GetPubliKeyToken() 

    string s = "d2850434514ae5ca"; 
    return this.StrToHexBytes(s); 

private byte[] StrToHexBytes(string hexString) 

    hexString = hexString.Replace(" ", ""); 
    if ((hexString.Length % 2) != 0) 
        hexString += " "; 
    byte[] returnBytes = new byte[hexString.Length / 2]; 
    for (int i = 0; i < returnBytes.Length; i++) 
        returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); 
    return returnBytes; 
} 其中StrToHexBytes方法,將字串轉換為十六進位的位元組數組

 

重新編譯執行,它的公開金鑰資訊就已經編譯進去了,同樣在C盤產生BusinessComponent.dll新程式集

      這個時候,先不著急引入程式集,先對新程式集通過私密對其進行重新簽名,輸入命令:

sn –R BusinessComponent.dll mykey.snk

OK,現在就可以重新引入了,這個時候再重新編譯代碼:

編譯通過了。

現在運行下程式(這裡要注意,你必須將SilverlightApp程式切換到OOB模式,才可以修改程式集):

浮水印資訊已經被去除了:)

 

      Mono.Cecil還可以用來做很多東西,比如說可以在一個方法中增加其他代碼,能夠細到IL中的每一個執行步驟,所以通過它可以做很多有意思的東西,比如說單元測試中的Mock對象以及效能上更佳的反射功能。

 

附上本文原始碼:SilverlightMonoCecilDemo.rar

利用Mono.Cecil動態修改程式集來破解商業組件(僅用於研究學習)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.