| 123456789101112131415161718192021222324252627282930313233343536373839404142 |
- using System;
- using Mono.Cecil;
- using Mono.Cecil.Cil;
- class P {
- static int Main(string[] a) {
- string src = a[0], dst = a[1];
- var m = ModuleDefinition.ReadModule(src);
- var tsAppDomain = new TypeReference("System", "AppDomain", m, m.TypeSystem.CoreLibrary, false);
- var getCurrentDomain = new MethodReference("get_CurrentDomain", tsAppDomain, tsAppDomain){ HasThis = false };
- var getBaseDir = new MethodReference("get_BaseDirectory", m.TypeSystem.String, tsAppDomain){ HasThis = true };
- var mGetCurrent = m.ImportReference(getCurrentDomain);
- var mGetBase = m.ImportReference(getBaseDir);
- int patched = 0;
- foreach (var t in m.GetTypes())
- foreach (var meth in t.Methods) {
- if (!meth.HasBody) continue;
- var il = meth.Body.Instructions;
- for (int i = 1; i < il.Count; i++) {
- var ins = il[i];
- if (ins.OpCode == OpCodes.Call && ins.Operand is MethodReference mr
- && mr.Name == "initialize" && mr.DeclaringType.Name == "Entry"
- && mr.Parameters.Count == 2 && il[i-1].OpCode == OpCodes.Ldnull) {
- // assumes the ldnull is not a branch or handler target; Replace
- // does not retarget operands pointing at the removed instruction
- var proc = meth.Body.GetILProcessor();
- var ldnull = il[i-1];
- var call1 = proc.Create(OpCodes.Call, mGetCurrent);
- var call2 = proc.Create(OpCodes.Callvirt, mGetBase);
- proc.Replace(ldnull, call1);
- proc.InsertAfter(call1, call2);
- patched++;
- Console.WriteLine($"Patched {t.FullName}.{meth.Name}: ldnull -> AppDomain.CurrentDomain.BaseDirectory");
- }
- }
- }
- if (patched == 0) { Console.WriteLine("No patch site found"); return 2; }
- m.Write(dst);
- Console.WriteLine($"Wrote {dst}, patched={patched}");
- return 0;
- }
- }
|