2007/10/26
强暴.net程序集 之六 (Assembly表的结构和修改)
警告:本系列文章为本人原创,只作技术研究之用,您可以引用链接传播,禁止其它的转载方式,禁止用于商业或非法目的, 对于造成的一切后果本人概不负责
上回有一个TableRowSizes函数没有说,它是用来得到指定元数据表的行大小
以Assembly表为例,在Partition II Metadata中描述了它的结构:
The Assembly table has the following columns:
• HashAlgId (a 4-byte constant of type AssemblyHashAlgorithm, §23.1.1)
• MajorVersion, MinorVersion, BuildNumber, RevisionNumber (each being 2-byte constants)
• Flags (a 4-byte bitmask of type AssemblyFlags, §23.1.2)
• PublicKey (an index into the Blob heap)
• Name (an index into the String heap)
• Culture (an index into the String heap)
HashAlgId 4个字节
MajorVersion, MinorVersion, BuildNumber, RevisionNumber 共8个字节
Flags 4个字节,指定了在Side By Side模式运行时的限制
PublicKey、Name、Culture、是#Blob heap或#String heap的索引,Public Key是用于assembly的完整性及发布者验证;Name是Assembly的名字;Culture是此Assembly所支持的语言,要注意这几个字段都不是固定大小,而是能过HeapSize推算出来的
对于Blob heap或String heap的大小的值是通过META_COMPOSITE_HEADER的HeapSizes计算出来的
在Partition II Metadata有描述:
The HeapSizes field is a bitvector that encodes the width of indexes into the various heaps. If bit 0 is set, indexes into the “#String” heap are 4 bytes wide; if bit 1 is set, indexes into the “#GUID” heap are 4 bytes wide; if bit 2 is set, indexes into the “#Blob” heap are 4 bytes wide. Conversely, if the HeapSize bit for a particular heap is not set, indexes into that heap are 2 bytes wide.
Heap size flag Description
0x01 Size of “#String” stream >= 216.
0x02 Size of “#GUID” stream >= 216.
0x04 Size of “#Blob” stream >= 216.
这些信息正好是ildasm对.assembly 伪指令的输出,比如
.assembly CountDown
{ .hash algorithm 32772
.ver 1:0:0:0
}
于是我们就可以求得总的行大小(Assembly表只有这一行)
bytes = 4;
bytes += 8;
bytes += 4;
bytes += (heapSizes & 0x04) ? 4 : 2;
bytes += (heapSizes & 0x01) ? 4 : 2;
bytes += (heapSizes & 0x01) ? 4 : 2;
现在我们改一下主版本号,注意我用的是内存映射文件
PMETA_ASSEMBLY_TABLE assemblyTable = (PMETA_ASSEMBLY_TABLE)(tables[TableType::Assembly].Address);
WORD* pVersion = &(assemblyTable->MajorVersion);
*pVersion = atoi(szBuffer);
用ildasm看已经修改过来了:
.assembly query
{
.ver 8:0:0:0
}
但是... ....