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

Last change on this file since 75 was 75, checked in by alloc, 6 years ago

fixes

File size: 3.3 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                        connectLogPatch(module);
15                        module.Write ("Assembly-CSharp.dll");
16                        Console.WriteLine ("Done");
17                }
18
19                private static void connectLogPatch (ModuleDefinition module)
20                {
21                        TypeDefinition type = module.GetType ("GameManager");
22
23                        if (isPatched (type)) {
24                                return;
25                        }
26
27                        markTypePatched (module, type);
28                        addHook (type, "RequestToSpawnPlayer", true, 5, typeof(AllocsRequestToSpawnPlayer).GetMethod ("RequestToSpawnPlayer"));
29                }
30
31                private static void telnetPatch (ModuleDefinition module)
32                {
33                        TypeDefinition type = module.GetType ("NetTelnetServer");
34
35                        if (isPatched (type)) {
36                                return;
37                        }
38
39                        markTypePatched (module, type);
40                        replaceMethod (type, ".ctor", 1, typeof(AllocsNetTelnetServer).GetMethod ("init"));
41                        replaceMethod (type, "Disconnect", 0, typeof(AllocsNetTelnetServer).GetMethod ("Disconnect"));
42                        replaceMethod (type, "SetConsole", 1, typeof(AllocsNetTelnetServer).GetMethod ("SetConsole"));
43                        replaceMethod (type, "WriteToClient", 1, typeof(AllocsNetTelnetServer).GetMethod ("WriteToClient"));
44                }
45
46                private static void markTypePatched (ModuleDefinition module, TypeDefinition type)
47                {
48                        type.Fields.Add (new FieldDefinition ("AllocsPatch", Mono.Cecil.FieldAttributes.Private | Mono.Cecil.FieldAttributes.SpecialName, module.Import (typeof(int))));
49                }
50
51                private static void addHook (TypeDefinition type, string methodName, bool addThisRef, int opCount, MethodBase targetMethod)
52                {
53                        foreach (MethodDefinition method in type.Methods) {
54                                if (method.Name.Equals (methodName)) {
55                                        Console.WriteLine ("Patching " + methodName);
56                                        var il = method.Body.GetILProcessor ();
57                                        var call = il.Create (OpCodes.Call, method.Module.Import (targetMethod));
58                                        var i = 0;
59                                        if (addThisRef)
60                                                il.InsertBefore (method.Body.Instructions [i++], il.Create (OpCodes.Ldarg, 0));
61                                        for (int op = 0; op < opCount; op++) {
62                                                il.InsertBefore (method.Body.Instructions [i++], il.Create (OpCodes.Ldarg, op + 1));
63                                        }
64                                        il.InsertBefore (method.Body.Instructions [i++], call);
65                                }
66                        }
67                }
68
69                private static void replaceMethod (TypeDefinition type, string methodName, int opCount, MethodBase targetMethod)
70                {
71                        foreach (MethodDefinition method in type.Methods) {
72                                if (method.Name.Equals (methodName)) {
73                                        Console.WriteLine ("Patching " + methodName);
74                                        var il = method.Body.GetILProcessor ();
75                                        var call = il.Create (OpCodes.Call, method.Module.Import (targetMethod));
76                                        var i = 0;
77                                        for (int op = 0; op < opCount; op++) {
78                                                il.InsertBefore (method.Body.Instructions [i++], il.Create (OpCodes.Ldarg, op + 1));
79                                        }
80                                        il.InsertBefore (method.Body.Instructions [i++], call);
81                                        il.InsertBefore (method.Body.Instructions [i++], il.Create (OpCodes.Ret));
82                                }
83                        }
84                }
85
86                private static bool isPatched (TypeDefinition type)
87                {
88                        foreach (FieldDefinition fd in type.Fields) {
89                                if (fd.Name.Equals ("AllocsPatch")) {
90                                        Console.WriteLine ("\"" + type.Name + "\" is already patched, skipping");
91                                        return true;
92                                }
93                        }
94                        Console.WriteLine ("Patching \"" + type.Name + "\"");
95                        return false;
96                }
97        }
98}
Note: See TracBrowser for help on using the repository browser.