初识Ildasm.exe——IL反编译的实用工具(转自Youngman)
Ildasm.exe 概要:
?
一.前言:
? ?? 微軟的IL反編譯實(shí)用程序——Ildasm.exe,可以對(duì)可執(zhí)行文件(ex,經(jīng)典的控制臺(tái)Hello World 的 exe 可執(zhí)行文件)抽取出 IL 代碼,并且給出命名空間以及類的視圖。在講述如何反編譯之前,有必要從虛擬CPU的角度來(lái)看CLR,這樣有助于先從正面了解代碼執(zhí)行過(guò)程。
虛擬CPU:?
? ? .NET 程序,其核心皆為 CLR ,而同時(shí)CLR的功能卻與CPU非常相近,其中CLR執(zhí)行IL代碼(或叫做,IL指令)、操作數(shù)據(jù),只不過(guò)操作的代碼不同:CPU操作機(jī)器語(yǔ)言,而CLR操作IL代碼。
由上,上述講解的是從IL--機(jī)器語(yǔ)言的過(guò)程,而Ildasm則可以實(shí)現(xiàn)將可執(zhí)行程序(機(jī)器語(yǔ)言)--IL代碼,這就是Ildasm的主要功能。?
? ? 在Anytao的《你必須知道的.NET》中對(duì)IL代碼專門做了說(shuō)明,雖然暫時(shí)悟不透其"深遠(yuǎn)意義",但我還是愿意去開(kāi)始我的IL之旅的,呵呵~。 在此我們先看,Anytao對(duì)于掌握(或者了解) IL代碼的重要性:
1.通用的語(yǔ)言基礎(chǔ)是.NET運(yùn)行的基礎(chǔ),當(dāng)我們對(duì)運(yùn)行結(jié)果有異議的時(shí)候,如何透過(guò)表面看本質(zhì),IL是必須的基礎(chǔ);?
2. IL也是更好理解、認(rèn)識(shí)CLR的基礎(chǔ);
3.大量的實(shí)例分析是以IL為基礎(chǔ)的,所以了解IL,是讀懂他人代碼的必備基礎(chǔ),同時(shí)自己也可以獲得潛移默化的提高;?
??? 有上述3條影響,足以讓任何一個(gè)有追求的人都鼓足勁,去開(kāi)始IL之旅了(自然包括我,呵呵~)。
?
二 .Ildasm.exe 的使用方法:
在應(yīng)用Ildasm.exe具體反編譯代碼之前,先附上MSDN對(duì)于用Ildasm.exe反編譯的經(jīng)典幫助示例:?
?
然后我們用Ildasm.exe具體反編譯經(jīng)典的"Hello World"控制臺(tái)程序的可執(zhí)行文件,展現(xiàn)出來(lái)的視圖為:
?
?
分析具體IL代碼:
1.MANIFEST清單:
? ?? MANIFEST是一個(gè)附加信息列表,主要包含程序集的一些屬性,如程序集名稱、版本號(hào)、哈希算法等;
2.ConsoleApplication1.Program類:
? ? 這才是我們介紹的主角。?
首先是Program類: 代碼為
.class?private?auto?ansi?beforefieldinit?ConsoleApplication1.Program???????extends?[mscorlib]System.Object
{
}?//?end?of?class?ConsoleApplication1.Program
1).class,表示Program是一個(gè)類。并且它繼承自程序集—mscorlib的System.Object類;
2)private,表示訪問(wèn)權(quán)限;
3)auto,表示程序的內(nèi)存加載全部由CLR來(lái)控制;
4)ansi,是為了在沒(méi)有托管代碼與托管代碼之間實(shí)現(xiàn)無(wú)縫轉(zhuǎn)換。這里主要指C、C++代碼等;
5)beforefieldinit,是用來(lái)標(biāo)記運(yùn)行庫(kù)(CLR)可以在靜態(tài)字段方法生成后的任意時(shí)刻,來(lái)加載構(gòu)造器(構(gòu)造函數(shù));
?
其次是 .otor方法,代碼為:
.method?public?hidebysig?specialname?rtspecialname?????????instance?void??.ctor()?cil?managed
{
??//?Code?size???????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:表示調(diào)用構(gòu)造函數(shù).otor期間的評(píng)估堆棧(Evaluation Stack) ;
3)IL_0000:標(biāo)記代碼行開(kāi)頭;
4)ldarg.0:表示轉(zhuǎn)載第一個(gè)成員參數(shù),在實(shí)例方法中指的是當(dāng)前實(shí)例的引用;
5)call:call一般用于調(diào)用靜態(tài)方法,因?yàn)殪o態(tài)方法是在編譯期就確定的。而這里的構(gòu)造函數(shù).otor()也是在編譯期就制定的。而另一指令callvirt則表示調(diào)用實(shí)例方法, 它是在運(yùn)行時(shí)確定的,因?yàn)槿缜笆?#xff0c;當(dāng)調(diào)用方法的繼承關(guān)系時(shí),就要比較基類與派生類的同名函數(shù)的實(shí)現(xiàn)方法(virtual和new),以確定調(diào)用的函數(shù)所屬的Method Table;
6)ret:表示執(zhí)行完畢,返回;
?
最后是Main()方法,代碼為:
.method?private?hidebysig?static?void??Main()?cil?managed{
??.entrypoint
??//?Code?size???????13?(0xd)
??.maxstack??8
??IL_0000:??nop
??IL_0001:??ldstr??????"Hello?world"
??IL_0006:??call???????void?[mscorlib]System.Console::WriteLine(string)
??IL_000b:??nop
??IL_000c:??ret
}?//?end?of?method?Program::Main
?
1) .entrypoint指令表示CLR加載程序時(shí),是首先從.entrypoint開(kāi)始的,即從Main方法作為程序的入口函數(shù);
2)ldstr:表示將字符串壓棧,在這里就是將"Hello World."?壓棧;
3)hidebysig:表示當(dāng)把此類作為基類,存在派生類時(shí),此方法不被繼承,同上構(gòu)造函數(shù);
?
?? 至此,我們對(duì)IL代碼的一些指令有了了解,也縱觀了IL世界里的概況,呵呵~
?
常用IL指令擴(kuò)展:?
?
一:創(chuàng)建對(duì)象實(shí)例的IL指令
關(guān)于創(chuàng)建對(duì)象的在內(nèi)存分配的機(jī)制,在《內(nèi)存探尋1之——值類型和引用類型的內(nèi)存分配機(jī)制》 里有了詳細(xì)的介紹。而常用的創(chuàng)建對(duì)象的IL指令使我們更好理解對(duì)象的步驟。其主要有4種:
1.newobj: 用于創(chuàng)建引用類型的對(duì)象;
2:ldstr:用于創(chuàng)建String對(duì)象變量;
3.newarr:用于創(chuàng)建數(shù)組型對(duì)象;
4:box:在值類型轉(zhuǎn)換為引用類型的對(duì)象時(shí),將值類型拷貝紙托管堆上分配內(nèi)存;?
?
二:通過(guò)IL代碼,更好地理解屬性?
我們?cè)贑++中,在典型的類中,都會(huì)定義用于控制有效性輸入的Set()函數(shù),以及用于不同方式顯示的Get()函數(shù)。然而在C#中,它將Get()函數(shù)和Set()結(jié)合在一起,剛開(kāi)始難免會(huì)為之混淆。然而若通過(guò) Ildasm.exe對(duì)程序反編譯后觀察屬性的本質(zhì),即可看到其執(zhí)行機(jī)制,如下圖示(注:選自互聯(lián)網(wǎng)):
?
?
由我們前面的分析IL代碼的方法,以及上圖的展示,我們可以看到屬性被重新分為Get()函數(shù)和Set()函數(shù)。ex,屬性Name,被分解為get_Name()函數(shù)和set_Name(String s)函數(shù)。這樣我們對(duì)其本質(zhì)就一目了然了!至于其屬性的特殊表示形式,只看做是Set()函數(shù)和Get()函數(shù)的完美結(jié)合體就可以了,這也是C#語(yǔ)言的優(yōu)美體現(xiàn)啊,呵呵~
?
綜述之,我們對(duì)反編譯工具Ildasm.exe有了一定認(rèn)識(shí),最主要的,我們通過(guò)它反編譯的IL代碼,對(duì)基本的IL指令有了一定的了解,也對(duì)以后的在把IL代碼作為有力工具?使用的過(guò)程中,更向前了一步!然而,這些都還只是IL的基礎(chǔ),需要繼續(xù)深入
轉(zhuǎn)載于:https://www.cnblogs.com/zhcw/archive/2013/02/20/2919747.html
總結(jié)
以上是生活随笔為你收集整理的初识Ildasm.exe——IL反编译的实用工具(转自Youngman)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 广义积分1
- 下一篇: Console-算法-递归算法示例