CLR:通用語言運行時(Common Language Runtime)的簡稱,CLR是.NET框架的核心內容之一,能夠把它看爲一套標準資源,能夠唄任何.NET程序使用。它包括:面向對象的編程模型、安全模型、類型系統(CTS)、全部.NET基類、程序執行及代碼管理等。html
咱們能夠這樣理解,CLR是託管程序運行的環境,就像Windows是普通的PE程序的運行環境同樣。
在Windows中,整個CLR系統的實現基本其實就是幾個關鍵的DLL,好比mscorwks.dll、mscorjit.dll,它們共同的特色就是前綴均爲mscor。編程
在win32中,可執行文件在開始運行時,有操做系統載入到內存中,而後運行文件中的.text代碼,結束時有操做系統負責卸載。而在.NET下,這個過程卻不大同樣。用PE結構查看工具(這裏使用PEiD)載入一個實例文件,觀察導入表,能夠發現整個表只引入了一個mscoree.dll中的一個方法:_CorExeMain。而這個方法,真是該可執行文件在win32意義上的入口點。安全
和win32程序同樣,.NET可執行程序在運行初始,首先有Windows將PE載入內存,而後跳至_CorExeMain中執行。分水嶺就在這,當代碼跳至_CorExeMain中以後,程序運行進入了.NET的初始化階段,通過一番準備工做,.NET框架便正式接管程序的運行了。框架
*********************************************************************ide
JIT:即時編譯(Just In-Time compile),這是.NET運行可執行程序的基本方式,也就是在須要運行的時候,纔將對應的IL代碼編譯爲本機指令。傳入JIT的是IL代碼,輸出的是本機代碼,因此部分加密軟件經過掛鉤JIT來進行IL加密,同時又保證程序正常運行。同解釋執行的代碼相比,JIT的執行效率要高不少。工具
說到這,咱們先來了解下IL代碼是從哪個步驟獲得的。post
MSIL是將.NET代碼轉化爲機器語言的一箇中間過程。它是一種介於高級語言和基於Intel的彙編語言的僞彙編語言。當用戶編譯一個.NET程序時,編譯器將源代碼翻譯成Microsoft 中間語言 (MSIL),它是一組能夠有效地轉換爲本機代碼且獨立於CPU的指令。當執行這些指令時,實時(JIT)編譯器將它們轉化爲CPU特定的代碼。學習
也就是說,MSIL是一箇中間語言,是由編譯器編譯而來的,屬於第一個步驟(編譯)的產物。加密
而當咱們須要執行時,再將MSIL經過JIT即時編譯成所需的機器指令來執行。spa
下面咱們來看看MSIL的樣子:
咱們先用vs2012編寫一個簡單的控制檯程序,hello world。
而後打開ildasm,具體步驟是這樣的
輸入命令後出現
咱們將編譯好的exe程序拖拽進ildasm中。
咱們將程序進行轉儲,也就是傳說中的dump
選擇一些選項,而後保存
咱們用記事本將保存的il文件打開,文件內容以下:
MSIL:微軟中間語言(Microsoft Intermediate Language),也被稱做MSIL彙編。別看.NET框架很智能,其實它只認IL。無亂程序採用什麼高級語言編寫,都將被編譯器編譯爲IL並保存在PE文件中。雖被稱做彙編,但相比win32彙編語言,IL可謂是名副其實的高級語言:它支持面向對象,一般不直接操做內存地址,以堆棧機的方式運行。因爲運行徹底受.NET監控,所以IL屬於託管(Managed)代碼,與之對應的是本機代碼,被稱爲非託管代碼。
元數據:描述.NET程序運行說必需的一切信息的數據,包括版本、類型的各個成員(方法、字段、屬性、事件)等。一個文件要稱爲有效的.NET可執行程序,必須包含正確的元數據定義。
咱們來看看對應的hello world對應的元數據
// =============== CLASS MEMBERS DECLARATION ===================
.class private auto ansi beforefieldinit '觀察導入表'.Program extends [mscorlib]System.Object { .method private hidebysig static void Main(string[] args) cil managed { .entrypoint // 代碼大小 17 (0x11) .maxstack 8 .language '{3F5162F8-07C6-11D3-9053-00C04FA302A1}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' .line 13,13 : 13,47 'd:\\Pro\\CLR和JIT的理解\\觀察導入表\\Program.cs' IL_0000: ldstr "hello world!" IL_0005: call void [mscorlib]System.Console::WriteLine(string) .line 14,14 : 13,31 '' IL_000a: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey() IL_000f: pop .line 15,15 : 9,10 '' IL_0010: ret } // end of method Program::Main .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 } // end of class '觀察導入表'.Program // =============================================================
上面的代碼中,首先經過.class關鍵字定義了Program類,因而編譯器會在PE文件中保存Program類的元數據。接着,定義了Program類的兩個方法.ctor和Main,元數據中也會體現這種隸屬關係。
public hidebysig static void 限定了Main方法中的執行方式爲公共、靜態、無返回值(hidebysig暫時不討論),這些限定也將被保存在元數據中。
Main方法中調用了System.Console的靜態方法WirteLine用於輸出字符串,元數據中必須體現這種調用。
以上內容來自:《微軟.NET程序的加密與解密》,學習這些內容只是爲了能更好的理解所學的C#內容,暫時不涉及逆向的問題。
原文;http://www.cnblogs.com/tk091/archive/2012/09/01/2666810.html