国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

MS.Net CLR 擴(kuò)展PE結(jié)構(gòu)分析2

2024-07-10 13:02:14
字體:
供稿:網(wǎng)友
  • 本文來源于網(wǎng)頁設(shè)計(jì)愛好者web開發(fā)社區(qū)http://www.html.org.cn收集整理,歡迎訪問。
  • flier lu <[email protected]>
      
    注意:本系列文章在水木清華bbs(smth.org)之.net版首發(fā),
         轉(zhuǎn)載請保留以上信息,發(fā)表請與作者聯(lián)系
      
    metadata 篇
      
    第一章 metadata 概述
      
    1.1 什么是 metadata
      
        metadata翻譯成中文是“元數(shù)據(jù)”,可以理解為type of type,
    說白了就是描述類型的類型數(shù)據(jù)。從最初級的語言層面支持的rtti
    (“近代”的編程語言基本上都提供了足夠的支持,如c++,delphi等,
    部分較“落伍”的語言也通過不同形式如擴(kuò)展庫提供了模擬支持,
    “現(xiàn)代”的編程語言則提供了強(qiáng)力的支持,如java和c#<本質(zhì)是clr>),
    到后來二進(jìn)制級的com的idl和類型庫(類型庫是idl編譯后的二進(jìn)制形式),
    到現(xiàn)在的metadata,其實(shí)是遵循著相同的設(shè)計(jì)思路。只是出于不同的需求
    設(shè)計(jì)、實(shí)現(xiàn),有這各自的優(yōu)點(diǎn)缺點(diǎn)罷了。但隨著語言的發(fā)展,更多的需求集中在
    靈活性方面,因而語言發(fā)展的趨勢是元數(shù)據(jù)的使用越來越多、支持越來越強(qiáng)。
        舉個(gè)最簡單的例子,在ide中,動(dòng)態(tài)顯示當(dāng)前對象的方法、屬性名列表的功能
    (ms叫intellisense,borland叫codeinsight),就得宜于類型信息
    以前在vc里實(shí)現(xiàn),比較麻煩,得生成專門的符號庫;在vb里強(qiáng)一點(diǎn),可以通過
    com的idispatch,itypeinfo,itypelib等接口動(dòng)態(tài)獲取,但編程麻煩要死;
    到clr,庫一級直接提供支持,可以通過system.reflection完全控制
    甚至比com類型庫更高一級地支持動(dòng)態(tài)創(chuàng)建。
       對用戶來說,可以完全了解當(dāng)前程序接口,有哪些module,哪些class,
    哪些method等等,這給開發(fā)者提供了巨大的創(chuàng)造空間。如dunit(dotnet下
    的xunit單元測試平臺(tái))就大量使用reflection機(jī)制,我們等會(huì)談使用時(shí)再說。
      
    1.2 metadata在clr中的作用
      
        對于clr架構(gòu)來說,metadata可以算是核心操作對象,幾乎絕大多數(shù)功能
    都需要參考其數(shù)據(jù)。從靜態(tài)的il代碼構(gòu)成(二進(jìn)制編碼中直接使用metadata里的token)
    到動(dòng)態(tài)jit編譯器(使用metadata定位il代碼及其關(guān)系);從簡單的代碼載入執(zhí)行
    (class loader通過metadata定位代碼入口、編譯執(zhí)行)到復(fù)雜的不同語言互操作
    (如vb.net繼承c#的類,實(shí)際上是直接繼承clr中metadata中的類);等等……
    幾乎所有地方都能看到metadata的身影。
      
        因?yàn)楸疚牡闹饕康氖墙榻B底層結(jié)構(gòu),這里就不再羅嗦metadata的好處了,
    反正以后文章中大家會(huì)次次看到他,各種優(yōu)點(diǎn)自己慢慢體會(huì)吧 :)
      
    1.3 如何訪問和使用 metadata
      
       做了一通廣告,大家一定很關(guān)心如何使用metadata,聽我慢慢道來
       在clr里使用metadata,可以在三個(gè)層面進(jìn)行操作。
       最簡單的方法是直接通過類庫提供的system.reflection命名空間中的
    若干類進(jìn)行訪問,例如
      
    using system.reflection;
    using system;
      
    public class simple
    {
        public static void main ()
        {
             module mod = assembly.getexecutingassembly().getmodules () [0];
             console.writeline ("module name is " + mod.name);
             console.writeline ("module fullyqualifiedname is " +
    mod.fullyqualifiedname);
             console.writeline ("module scopename is " + mod.scopename);
        }
    }
      
       這種訪問方式使用起來最簡單,功能也足夠強(qiáng)大,能夠完成我們絕大多數(shù)的需要,
    特別是在system.reflection.emit命名空間中,更提供了動(dòng)態(tài)生成、修改的支持
    功能強(qiáng)大得我都想不出能有什么改進(jìn)了 :) (寫.net病毒就靠他了,hoho)
       不過這種方式必須有clr環(huán)境的支持,受到庫功能的限制(后面我們會(huì)看到很多
    在reflection一級里不提供的信息:),因此ms為工具軟件開發(fā)商提供了另一套
    較底層的開發(fā)庫,metadata unmanaged api。這套庫通過一系列com接口,
    提供了直接訪問metadata的強(qiáng)大支持,system.reflection應(yīng)該就是使用它實(shí)現(xiàn)的。
    有興趣的朋友可以參看frameworksdk/tool developers guide/docs
    目錄下的metadata unmanaged api.doc文檔,里面有詳細(xì)的說明。
    如同其名字所示,它必須用unmanaged代碼來使用,如傳統(tǒng)的vc,delphi等。
       可以說99%的工作,都可以通過上面兩套庫來完成,不過總有些象我這樣的人,
    喜歡對技術(shù)追根究底,想把隱藏在美好面紗下的底層架構(gòu)糾出來暴露一把,呵呵
    因此有了第三個(gè)層面,二進(jìn)制層面的逆向工程分析。
       好在ms為了讓其cli(clr的子集)標(biāo)準(zhǔn)化,公開了大量文檔,總算沒要我用上
    softice之類的牛刀,partition ii metadata.doc文檔中對metadata的
    二進(jìn)制格式實(shí)現(xiàn)給出了比較詳盡的說明,加上gnome的mono項(xiàng)目已經(jīng)做了很多工作
    因而對metadata的二進(jìn)制層面分析不是那么困難。
       接下去的文章中,我會(huì)逐漸將metadata在pe中的組織結(jié)構(gòu)逐漸剝離開來,
    讓大家能夠了解這個(gè)神秘的clr核心到底是什么,里面隱藏了些什么,我們能夠通過
    他做什么,為什么要這樣設(shè)計(jì),等等……
      
    1.4 metadata在pe中的組織結(jié)構(gòu)
      
       說了一通廢話后,回到正體上來,談?wù)刴etadata在pe中的組織結(jié)構(gòu)。
      
    注意:這一章里面我只把metadata結(jié)構(gòu)的大概情況介紹一下,下一章會(huì)專門
    針對二進(jìn)制模式分析進(jìn)行詳細(xì)講解。如果你只想了解底層結(jié)構(gòu),可以跳過
    下一章。以后的文章也會(huì)遵循這種方式組織,講一些結(jié)構(gòu)、原理,跟著講
    一些實(shí)際數(shù)據(jù)分析方法。
      
       上次我們提到clr的頭信息里面專門有一個(gè)字段指向metadata數(shù)據(jù)塊,
    實(shí)際上這個(gè)數(shù)據(jù)塊只是metadata的一個(gè)頭結(jié)構(gòu),保存有metadata的信息,
    而metadata的實(shí)際數(shù)據(jù),是通過若干不同的heap或者說stream保存的。
    這里我統(tǒng)一使用stream“流“作為他的名字,但很多文檔中以heap”堆“作為
    其稱呼,我們可以理解他是一個(gè)二進(jìn)制流,其中數(shù)據(jù)以堆的結(jié)構(gòu)進(jìn)行組織。
       metadata里最常見的有五種流,#string, #blob, #guid,
    #us(user string)和#~流("#"是流名字的前綴)
       string流就是一個(gè)字符串堆,metadata內(nèi)部用到的所有字符串如類或方法
    的名字等等都以utf8編碼保存在此堆內(nèi)。而用戶的字符串如字符串常量,
    則以unicode編碼保存在us(user string)堆內(nèi)。值得注意的是,
    us流和string流在二進(jìn)制結(jié)構(gòu)組織上不同,我們后面將分析時(shí)會(huì)詳細(xì)提及。
    guid流是保存程序中使用到的guid的數(shù)組,如assembly中module的mvid。
    blob流是一個(gè)通用存儲(chǔ)空間,除了guid和字符串以外基本上所有
    亂七八糟的東西都放在里面,呵呵,如publickey,常量的值等等。
       最重要的是#~流,這是metadata實(shí)際信息存放的地方。#~流結(jié)構(gòu)上以
    若干張表(table)的形式組織,每張表存儲(chǔ)某一方面的metadata信息,
    如methoddef表存儲(chǔ)所有方法的信息。每張表又由若干的行(row)組成
    每行有n個(gè)列(column),每列代表一種信息,如methoddef表中每一行
    都有一個(gè)方法的rva,類型標(biāo)志,名字,signature等等信息。在其中通過
    各種索引來相互關(guān)聯(lián),整個(gè)組織結(jié)構(gòu)和關(guān)系數(shù)據(jù)庫很相似。
       比較特殊的是,這里所有的表通過一個(gè)64bit的有效位圖來表示其存在與否
    每種類型的表有一個(gè)編號,如methoddef表的編號是6,則第(1<<(6-1))位置1
    因而每個(gè)表的每一行,可以使用一個(gè)唯一的token表示。此token是一個(gè)32bit
    無符號整型數(shù),最高一個(gè)字節(jié)表示表的編號,低三個(gè)字節(jié)表示表中的索引號。
    如0x06000003表示0x06表(methoddef)中第3行(如myapp::add)
    這個(gè)token概念在clr中頻繁使用,如il代碼調(diào)用函數(shù)、使用變量都是使用token。
       與之類似的還有coded index,下次講二進(jìn)制實(shí)現(xiàn)時(shí)再說。 
    發(fā)表評論 共有條評論
    用戶名: 密碼:
    驗(yàn)證碼: 匿名發(fā)表
    主站蜘蛛池模板: 张家口市| 石楼县| 彩票| 台东市| 大悟县| 会昌县| 大同市| 广州市| 望都县| 咸丰县| 乌拉特后旗| 凤城市| 休宁县| 丽水市| 蛟河市| 潢川县| 隆回县| 新化县| 赫章县| 望江县| 秦皇岛市| 瓮安县| 于都县| 柳河县| 平邑县| 环江| 仙桃市| 东安县| 息烽县| 东宁县| 沂源县| 北流市| 扶风县| 油尖旺区| 卢龙县| 巴马| 简阳市| 武宣县| 确山县| 郧西县| 建昌县|