26. Mono.Cecilのコード例
Hello Worldを表示するだけのEXEを生成
var assembly = AssemblyDefinition.CreateAssembly(
new AssemblyNameDefinition("Test", new Version()),
"Test.exe",
ModuleKind.Console);
var module = assembly.MainModule;
var type = module.Types.First();
var method = new MethodDefinition(
"Main",
MethodAttributes.Static, module.Import(typeof(void)));
var il = method.Body.GetILProcessor();
var write = typeof(Console).GetMethod("WriteLine", new[] { typeof(object) });
il.Emit(OpCodes.Ldstr, "HelloWorld");
il.Emit(OpCodes.Call, module.Import(write));
il.Emit(OpCodes.Ret);
type.Methods.Add(method);
assembly.EntryPoint = method;
assembly.Write("Test.exe");
27. Mono.Cecilのコード例
全メソッドの末尾(retの前)にメッセージ出力を追加
var assembly = AssemblyDefinition.ReadAssembly("Test.exe");
var write = typeof(Console).GetMethod("WriteLine", new[] { typeof(string) });
assembly.Modules
.SelectMany(x => x.Types)
.SelectMany(x => x.Methods)
.ToList()
.ForEach(method => {
var il = method.Body.GetILProcessor();
var ldstr = il.Create(OpCodes.Ldstr, "Finish");
var call = il.Create(OpCodes.Call, method.Module.Import(write));
method.Body.Instructions
.Where(x => x.OpCode == OpCodes.Ret)
.ToList()
.ForEach(x => {
il.InsertBefore(x, ldstr);
il.InsertBefore(x, call);
});
});
assembly.Write("Test-Mod.exe");
Assembly内の全メソッドを取得
Console.WriteLine("Finish");を
挿入
29. CLR Profiling API
• .NET界でも最上級レベルの黒魔術
• 実行中に全APIをフックして処理の差し替えが可能
• 私は使ったことはありません
• 参考資料
• C# 動的メソッド入れ替え - Apply a monkey patch to
any static languages on CLR -
http://urasandesu.blogspot.jp/2011/10/c-apply-monkey-patch-to-any-static.html