source: binary-improvements/assembly-patcher/Main.cs@ 74

Last change on this file since 74 was 73, checked in by alloc, 10 years ago

First version of binary fixer

File size: 2.2 KB
Line 
1using System;
2using System.Reflection;
3using Mono.Cecil;
4using Mono.Cecil.Cil;
5
6namespace dtdfixer
7{
8 class MainClass
9 {
10 public static void Main (string[] args)
11 {
12 ModuleDefinition module = ModuleDefinition.ReadModule ("Assembly-CSharp.dll");
13 telnetPatch (module);
14 module.Write ("Assembly-CSharp.dll");
15 Console.WriteLine ("Done");
16 }
17
18 private static void telnetPatch (ModuleDefinition module)
19 {
20 TypeDefinition type = module.GetType ("NetTelnetServer");
21
22 if (isPatched (type)) {
23 return;
24 }
25
26 markTypePatched (module, type);
27 patchMethod (type, ".ctor", 1, typeof(AllocsNetTelnetServer).GetMethod ("init"));
28 patchMethod (type, "Disconnect", 0, typeof(AllocsNetTelnetServer).GetMethod ("Disconnect"));
29 patchMethod (type, "SetConsole", 1, typeof(AllocsNetTelnetServer).GetMethod ("SetConsole"));
30 patchMethod (type, "WriteToClient", 1, typeof(AllocsNetTelnetServer).GetMethod ("WriteToClient"));
31 }
32
33 private static void markTypePatched (ModuleDefinition module, TypeDefinition type)
34 {
35 type.Fields.Add (new FieldDefinition ("AllocsPatch", Mono.Cecil.FieldAttributes.Private | Mono.Cecil.FieldAttributes.SpecialName, module.Import (typeof(int))));
36 }
37
38 private static void patchMethod (TypeDefinition type, string methodName, int opCount, MethodBase targetMethod)
39 {
40 foreach (MethodDefinition method in type.Methods) {
41 if (method.Name.Equals (methodName)) {
42 Console.WriteLine ("Patching " + methodName);
43 var il = method.Body.GetILProcessor ();
44 var call = il.Create (OpCodes.Call, method.Module.Import (targetMethod));
45 var i = 0;
46 for (int op = 0; op < opCount; op++) {
47 il.InsertBefore (method.Body.Instructions [i++], il.Create (OpCodes.Ldarg, op + 1));
48 }
49 il.InsertBefore (method.Body.Instructions [i++], call);
50 il.InsertBefore (method.Body.Instructions [i++], il.Create (OpCodes.Ret));
51 }
52 }
53 }
54
55 private static bool isPatched (TypeDefinition type)
56 {
57 foreach (FieldDefinition fd in type.Fields) {
58 if (fd.Name.Equals ("AllocsPatch")) {
59 Console.WriteLine ("\"" + type.Name + "\" is already patched, skipping");
60 return true;
61 }
62 }
63 Console.WriteLine ("Patching \"" + type.Name + "\"");
64 return false;
65 }
66 }
67}
Note: See TracBrowser for help on using the repository browser.