日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

元数据与IL简介

發(fā)布時(shí)間:2024/4/15 编程问答 60 豆豆
生活随笔 收集整理的這篇文章主要介紹了 元数据与IL简介 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?

文/玄魂

1.3.2 ????? 元數(shù)據(jù)

元數(shù)據(jù)是描述數(shù)據(jù)的數(shù)據(jù)。在CLR的上下文中,元數(shù)據(jù)表示由描述符組成的一套體系,這些操作符包括了在一個(gè)模塊中被聲明或引用的所有項(xiàng)。由于CLR模型是面向?qū)ο蟮?#xff0c;因此在元數(shù)據(jù)中描述的項(xiàng)是類和它們的成員,以及它們伴隨著的特性、屬性和關(guān)聯(lián)。本節(jié)簡單地介紹元數(shù)據(jù),與原數(shù)據(jù)安全相關(guān)的內(nèi)容會在后續(xù)章節(jié)中繼續(xù)講解,元數(shù)據(jù)的詳細(xì)內(nèi)容不在本書的論述范圍之內(nèi)。

元數(shù)據(jù)實(shí)際上是一塊二進(jìn)制數(shù)據(jù),包含了三種表:定義表、引用表和清單表。

元數(shù)據(jù)定義表主要是模塊定義、類型定義、方法定義、字段定義、事件定義、參數(shù)定義、屬性定義等一系列定義表的集合。當(dāng)編譯器編譯代碼時(shí),所有定義的內(nèi)容都會生成對應(yīng)的定義表。

元數(shù)據(jù)引用表用于記錄編譯器中源代碼引用的類型、方法、字段、事件。常用的引用表如:AssemblyRef(程序集引用表)、ModuleRef(模塊引用表)、TypeRef(類型引用表)等。

元數(shù)據(jù)清單表包含了組成程序集所需要的所有信息,同時(shí)包含了對其他程序集的引用信息。它明確地指出了哪些條目可以對外開放,哪些條目只可以在程序集內(nèi)部進(jìn)行訪問。

下面通過經(jīng)典的HelloWorld程序簡要分析其中的元數(shù)據(jù)信息,如代碼清單1-7所示。

代碼清單1-7 HelloWorld程序代碼

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace HelloWorld{class Program{static void Main(string[] args){Console.WriteLine("Hello World!");Console.Read();}}}

?

下面使用反匯編工具ILDasm打開HelloWorld.exe,雙擊MANIFEST,圖1-7為查看清單信息的截圖。ILDasm的使用方法和參數(shù)說明請讀者參考MSDN文檔。

?

圖1-7? 查看程序清單信息

詳細(xì)的清單信息如代碼清單1-8所示。

代碼清單1-8 HelloWorld.EXE的清單信息

// Metadata version: v4.0.21006.assembly extern mscorlib{.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4...ver 4:0:0:0}.assembly HelloWorld{......}.hash algorithm 0x00008004.ver 1:0:0:0.module HelloWorld.exe// MVID: {B8EB35DD-5AD2-402C-B422-AA63B0AACCFA}.imagebase 0x00400000.file alignment 0x00000200.stackreserve 0x00100000.subsystem 0x0003 // WINDOWS_CUI.corflags 0x00000003 // ILONLY 32BITREQUIRED// Image base: 0x05C40000

?

程序比較簡單,代碼中包含了版本、外部引用等簡單的信息。表1-2描述了示例中所使用的 HelloWord.exe 程序集的程序集清單中的各項(xiàng)指令。

表1-2 HelloWorld.exe指令說明

指令

說明

.assembly extern < assembly name >

指定包含當(dāng)前模塊所引用項(xiàng)目的另一程序集(在此示例中為 mscorlib)

.publickeytoken < token >

指定所引用程序集的實(shí)際密鑰的標(biāo)記

.ver < version number >

指定引用程序集的版本號

.assembly < assembly name >

指定程序集名稱

.hash algorithm < int32 value >

指定使用的哈希算法

.module < file name >

指定組成程序集的模塊名稱,在此示例中,程序集只包含一個(gè)文件

.subsystem < value >

指定程序要求的應(yīng)用程序環(huán)境。在此示例中,值 3 表示該可執(zhí)行文件從控制臺運(yùn)行

.corflags

當(dāng)前是元數(shù)據(jù)中的一個(gè)保留字段

根據(jù)程序集的內(nèi)容,程序集清單可包含許多不同的指令。有關(guān)程序集清單中指令的完整列表請讀者參考相關(guān)文檔,本例旨在拋磚引玉。若要查看完整的元數(shù)據(jù)信息,可以使用快捷鍵“Ctlr+M”,如圖1-8所示。

?

圖1-8 查看元數(shù)據(jù)信息

1.3.3 ????? IL常用指令

為方便起見,還是以HelloWorld.exe為例講解IL的相關(guān)內(nèi)容。由于篇幅所限,關(guān)于IL的詳細(xì)內(nèi)容還請各位讀者參考相關(guān)資料。圖1-9為Main方法的IL代碼。

?

圖1-9 HelloWorld.exe Main方法的IL代碼

在一個(gè)中間語言程序中,如果某一行以“.”開始,代表這是一個(gè)傳輸給匯編工具的指令;而沒有以“.”開始的行是中間語言的代碼。上圖中.method是方法定義指令,定義了Main方法,參數(shù)在“()”中,IL代碼在“{}”中。.entrypoint是入口指令,表明該方法是入口方法。.maxstack指定了最大棧的深度為8。下面的IL_n是代碼標(biāo)簽,后面是IL代碼。nop是空指令;ldstr指令向棧中壓入字符串“Hello World!”;call指令調(diào)用靜態(tài)方法Console.WriteLine(string)和Console.read();pop彈出棧頂?shù)闹?#xff1b;ret指令表示方法體的結(jié)束。IL支持“//”和“/* */”的注釋方法。

提示? 在中間語言中,如果需要調(diào)用一個(gè)方法,需要指定方法的全名,包括它的名稱域(namespace)、類名、返回值類型和參數(shù)的數(shù)據(jù)類型。

表1-3列舉了IL的其他一些常用指令,更多的指令可以查看IL指令表。

表1-3 IL常用指令

指令

描述

.assembly <程序集名稱> {}

設(shè)置程序集

ldc.i4.n

把一個(gè) 32位的常量(n從0到8)裝入堆棧

stloc.n

把一個(gè)從堆棧中返回的值存入第n(n取0~8)個(gè)局部變量

add

2個(gè)值相加。命令的參數(shù)必須在調(diào)用前裝入堆棧,該函數(shù)從堆棧中移除參數(shù)并把運(yùn)算后的結(jié)果壓入堆棧

sub

2個(gè)值相減

mul

2個(gè)值相乘

newarr type

生成一個(gè)元素類型為type 的數(shù)組。數(shù)組的大小必須在調(diào)用該命令前裝入堆棧。該命令會把一個(gè)數(shù)組的引用裝入堆棧

stelem.i4

給一個(gè)數(shù)組成員賦值。數(shù)組的引用、下標(biāo)和值必須在調(diào)用該命令前裝入堆棧

ldelema type

把數(shù)組元素的地址裝入堆棧。數(shù)組的引用和下標(biāo)必須在調(diào)用該命令前裝入堆棧。地址用來調(diào)用非靜態(tài)函數(shù)

ldlen

把數(shù)組的長度裝入堆棧。數(shù)組的引用必須在調(diào)用該命令前裝入堆棧

ldloca.s variable

把變量的地址裝入堆棧

ldc.i4.s value

把一個(gè)Int32的常量裝入堆棧(用于大于8位的數(shù))

conv.i4

把堆棧中值轉(zhuǎn)換成Int32類型

call instance function(arguments)

調(diào)用類的非靜態(tài)函數(shù)

bge.s label

跳轉(zhuǎn)至label 如果value1≥value 2. Values 1和 2 必須在調(diào)用本命令前裝入堆棧

br.s label

跳轉(zhuǎn)至label

box value type

把一個(gè)值類型轉(zhuǎn)成一個(gè)Object,并把該Object的引用裝入堆棧

blt.s label

跳轉(zhuǎn)至label 。如果value 1小于 value 2. Values 1 和 2 必須在調(diào)用本命令之前裝入堆棧

ldelem.i4

把一個(gè)數(shù)組元素裝入堆棧。數(shù)組引用和下標(biāo)必須在調(diào)用本命令之前裝入堆棧

ldarga.s argument

把函數(shù)參數(shù)的地址裝入堆棧

dup

在堆棧上復(fù)制一個(gè)值

stind.i4

存儲值的地址。地址和值必須在調(diào)用本命令之前裝入堆棧

.field

定義類成員。和關(guān)鍵字public、private、static等一起使用

stsfld static field

用堆棧中的值替換靜態(tài)字段的值

ldfld field

把一個(gè)非靜態(tài)字段裝入堆棧。類實(shí)例的地址必須在調(diào)用本命令之前裝入堆棧

ldarg.n

把第n個(gè)參數(shù)裝入堆棧。在非靜態(tài)函數(shù)中,第0個(gè)參數(shù)是一個(gè)隱含的參數(shù),代表this

newobj constructor

用構(gòu)造函數(shù)constructor生成一個(gè)類的實(shí)例。構(gòu)造函數(shù)的參數(shù)必須在調(diào)用本函數(shù)之前先裝入堆棧。一個(gè)類的實(shí)例會被生成并裝入堆棧

callvirt instance function

調(diào)用一個(gè)對象的后期綁定方法

?

1.3.4 ????? IL與代碼驗(yàn)證

在將MSIL編譯為本機(jī)代碼的過程中,MSIL代碼必須通過驗(yàn)證過程,除非管理員已經(jīng)建立了允許代碼跳過驗(yàn)證的安全策略。驗(yàn)證過程檢查MSIL和元數(shù)據(jù)以確定代碼是否是類型安全的,這意味著它僅訪問已被授權(quán)訪問的內(nèi)存位置。類型安全幫助將對象彼此隔離,因而可以保護(hù)它們免遭無意或惡意的破壞。它還提供了對代碼可以可靠地強(qiáng)制安全限制的保證。

運(yùn)行庫使用下列條件來驗(yàn)證代碼是否為類型安全:

q? 對類型的引用與被引用的類型嚴(yán)格兼容。

q? 在對象上只調(diào)用正確定義的操作。

q? 標(biāo)識與聲稱的要求一致。

驗(yàn)證過程中檢查 MSIL 代碼,嘗試確認(rèn)該代碼只能通過正確定義的類型訪問內(nèi)存位置和調(diào)用方法。例如,代碼不允許以超出內(nèi)存范圍的方式來訪問對象。另外,驗(yàn)證過程檢查代碼以確定 MSIL 是否已正確生成,這是因?yàn)椴徽_的 MSIL 會導(dǎo)致違反類型安全規(guī)則。驗(yàn)證過程通過正確定義的類型安全代碼集,并且它只通過類型安全的代碼。然而,由于驗(yàn)證過程存在一些限制,某些類型安全代碼可能無法通過驗(yàn)證,而某些語言在設(shè)計(jì)上并不產(chǎn)生可驗(yàn)證的類型安全代碼。如果安全策略要求提供類型安全代碼,而該代碼不能通過驗(yàn)證,則在運(yùn)行該代碼時(shí)將引發(fā)異常。

-------------------------注:本文摘抄自《.NET 安全揭秘》1.3節(jié)

總結(jié)

以上是生活随笔為你收集整理的元数据与IL简介的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。