程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C# IL DASM 使用,

C# IL DASM 使用,

編輯:C#入門知識

C# IL DASM 使用,


IL DASM反編譯工具

  使用C#的猿人或多或少都會對微軟的IL反編譯工具(ildasm.exe)有所認識。我最早接觸到這工具是公司同事使用他反編譯exe程序,進行研讀和修改。感覺他還是很強大。
  IL是微軟平台上的一門中間語言,我們常寫的C#代碼在編譯器中都會自動轉換成IL,然後在由即時編譯器(JIT Compiler)轉化機器碼,最後被CPU執行。ildasm.exe反編譯工具將IL匯編成可跨平台可執行的(pe)文件。可供我們了解別人代碼和修改。有了他我們看待問題可以不用停留在編輯器層面,可深入中間層。

VS中增加IL DASM工具

我們在安裝VS同時都會自動安裝ildasm工具,無需另行安裝。ildasm工具打開方法如下圖:

我們也可以直接wind+R.輸入:C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\ildasm.exe (window 7 64位 操作系統安裝目錄) 同樣可以打開ildasm。
我們也可以把ildasm工具增加到我們常用的VS中。
1.工具(Tools)-->外部工具(External Tools..)

2.添加內容填寫對應信息。命令:C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\ildasm.exe
(window 7 64位 操作系統安裝目錄) 。

已上信息填寫完成後,在“工具”選擇卡中能找到我們剛增加的外部工具名稱(IL_DASM)。增加完成後可以小試一把。
國際慣例來段"Hello World"。代碼編寫完後直接F6生成exe文件,然後工具-->IL_DASM-->確認(無需修改任何參數,默認目標文件路徑)。系統會彈出IL工具,我們雙擊Main方法。

這時可以看到Main方法在IL中編譯的代碼。感覺有點陌生不易看懂。 還有IL編譯出現的三角型,正方型都是啥!

IL DASM 基礎

1.圖標含義

使用IL反編譯出項目代碼

MANIFEST:是一個附加信息列表,主要包含程序集的一些屬性,如程序集名稱、版本號、哈希算法等;
Democode:項目名稱
Democodeing.Common:命名空間
Democodeing.ICar:接口
Democodeing.Program:類,主要查看存類下面的內容。

.class 類信息項代碼:

.class private auto ansi beforefieldinit DemoCoding.Program
       extends [mscorlib]System.Object
{
} // end of class DemoCoding.Program

1).class,表示Program是一個類。並且它繼承自程序集—mscorlib的System.Object類;
2)private,表示訪問權限;
3)auto,表示程序的內存加載全部由CLR來控制;
4)ansi,是為了在沒有托管代碼與托管代碼之間實現無縫轉換。這裡主要指C、C++代碼等;
5)beforefieldinit,是用來標記運行庫(CLR)可以在靜態字段方法生成後的任意時刻,來加載構造器(構造函數);

.ctor 方法代碼:

.method public hidebysig specialname rtspecialname 
        instance void  .ctor() cil managed
{
  // 代碼大小       7 (0x7)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
  IL_0006:  ret
} // end of method Program::.ctor

1)cil managed:表示其中為IL代碼,指示編譯器編譯為托管代碼;
2).maxstack:表示調用構造函數.otor期間的評估堆棧(Evaluation Stack) ;
3)  IL_0000:標記代碼行開頭;
4)ldarg.0:表示轉載第一個成員參數,在實例方法中指的是當前實例的引用;
5)call:call一般用於調用靜態方法,因為靜態方法是在編譯期就確定的。而這裡的構造函數.otor()也是在編譯期就制定的。而另一指令callvirt則表示調用實例方法, 它是在運行時確定的,因為如前述,當調用方法的繼承關系時,就要比較基類與派生類的同名函數的實現方法(virtual和new),以確定調用的函數所屬的Method Table;
6)ret:表示執行完畢,返回;

Main() 靜態方法代碼:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // 代碼大小       19 (0x13)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldstr      "Hello World"
  IL_0006:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_000b:  nop
  IL_000c:  call       string [mscorlib]System.Console::ReadLine()
  IL_0011:  pop
  IL_0012:  ret
} // end of method Program::Main

1) hidebysig:表示當把此類作為基類,存在派生類時,此方法不被繼承,同上構造函數;
2).entrypoint:指令表示CLR加載程序時,是首先從.entrypoint開始的,即從Main方法作為程序的入口函數;
3)nop:為空該指令,主要給外部設備或者指令間隙准備時間;
4)ldstr:創建String對象變量"Hello World." ;
5)pop:取出棧頂的值。當我們不需要把值存入變量時使用;

使用IL DASM 修改EXE程序代碼

1.打開IL工具,選擇所要修改的EXE程序。

2.文件-->轉儲。確定後選擇另存路徑,會生成二個文件:*.il 和 *.res

3.用記事本打開*.il修改裡面的內容:

 .method private hidebysig static void  Main(string[] args) cil managed
  {
    .entrypoint
    // 代碼大小       19 (0x13)
    .maxstack  8
    IL_0000:  nop
    IL_0001:  ldstr      "Hello World-[已使用il工具修改過...]"
    IL_0006:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_000b:  nop
    IL_000c:  call       string [mscorlib]System.Console::ReadLine()
    IL_0011:  pop
    IL_0012:  ret
  } // end of method Program::Main

4.把修改後的代碼編譯成EXE程序。

ilasm /exe /output=C:\CK.exe /Resource=C:\Users\Ck\Desktop\coding.res C:\Users\Ck\Desktop\coding.il

修改就這麼簡單。運行修改後的EXE程序,值已修改。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved