2007/11/2
强暴.Net程序集 之八 (元数据Token和指定程序入口方法)
警告:本系列文章为本人原创,只作技术研究之用,您可以引用链接传播,禁止其它的转载方式,禁止用于商业或非法目的, 对于造成的一切后果本人概不负责
一般的.net程序都是从一个静态的Main方法开法运行的,下面我将演示如何指定程序集中的另一个方法作为入口方法
假设有如下程序,我们要修改程序集让NewMain先运行
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("Program::Main()");
}
public static void NewMain()
{
Console.WriteLine("Program::NewMain()");
}
}
回想一下IMAGE_COR20_HEADER的格式,字段EntryPointToken指定了程序入口
在Partition II Metadata中写道:
Entry point metadata token
The entry point token (§15.4.1.2) is always a MethodDef token (§22.26) or File token (§22.19 ) when the entry point for a multi-module assembly is not in the manifest assembly. The signature and implementation flags in metadata for the method indicate how the entry is run
它的值不是一个地址,而是一个元数据Token
这个Token的格式是,前1个字节是元数据表的编号,最后一个字节是记录的索引
比如Token为0x06000001,0x06指Method表,0x01指Method表的第一个记录,这通常指向到Main方法
在元数据中大量使用了这种Token的方式,来引用其它表或流的项目
我们只需要修改此Token就能指定新的入口方法,在我们这个演示中改为NewMain方法的Token,即0x06000002
程序如下:
pCorHeader->EntryPointToken = _htoi(szNewEntryPointToken);
用ildasm打开后观察
.method public hidebysig static void NewMain() cil managed
{
.entrypoint
// 代码大小 13 (0xd)
.maxstack 8
IL_0000: nop
IL_0001: ldstr "Program::NewMain()"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop
IL_000c: ret
} // end of method Program::NewMain
可以看到.entrypoint伪指令已经在我们指定的NewMain方法中了