metadata元数据的内幕

10 篇文章 0 订阅
3 篇文章 0 订阅
Metadata在PE中的组织结构

   回到正体上来,谈谈Metadata在PE中的组织结构。
   上章我们提到CLR的头信息里面专门有一个字段指向Metadata数据块,
实际上这个数据块只是Metadata的一个头结构,保存有Metadata的全局信息,
而Metadata的实际数据,是通过若干不同的Heap或者说Stream保存的。
这里我统一使用Stream“流“作为他的名字,但很多文档中以Heap”堆“作为
其称呼,我们可以理解他是一个二进制流,其中数据以堆的结构进行组织。

   Metadata里最常见的有五种流,#String, #Blob, #Guid,
#US(User String)和#~流("#"是流名字的前缀)

   String流就是一个字符串堆,Metadata内部用到的所有字符串如类或方法
的名字等等都以UTF8编码保存在此堆内。而用户的字符串如字符串常量,
则以Unicode编码保存在US(User String)堆内。值得注意的是,
US流和String流在二进制结构组织上不同,我们后面将分析时会详细提及。
    Guid流是保存程序中使用到的Guid的数组,如Assembly中Module的MVID。
    Blob流是一个通用存储空间,除了Guid和字符串以外基本上所有
剩下的东西都以二进制数据形式放在里面,如PublicKey,常量的值等等。
   最重要的是#~流,这是Metadata核心信息存放的地方。#~流物理上以
若干张表(Table)的形式组织,每张表存储某一方面的Metadata信息,
如MethodDef表存储所有方法的信息。每张表又由若干的行(Row)组成
每行有n个列(Column),每列代表一种信息,如MethodDef表中每一行
都有一个方法的RVA,类型标志,名字,Signature等等信息。在其中通过
各种索引来相互关联,整个组织结构和关系数据库很相似。
   比较特殊的是,这里所有的表通过一个64bit的有效位图来表示表存在与否
每种类型的表有一个编号,如MethodDef表的编号是6,则第(1<<(6-1))位置1
因而每个表的每一行,可以使用一个唯一的Token表示。此Token是一个32bit
无符号整型数,最高一个字节表示表的序号,低三个字节表示表中的索引号。
如0x06000003表示0x06表(MethodDef)中第3行(如MyApp::Add)
这个Token概念在CLR中频繁使用,如IL代码调用函数、使用变量都是使用Token。
   与之类似的还有Coded Index,等会讲二进制实现时再说。  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值