static void InstallHook(HookData hook) { Console.WriteLine(hook.Host.FullName + " => " + hook.Virus.FullName); switch (hook.Type) { case "Before": { InstallHookBefore(hook); break; } case "After": { InstallHookAfter(hook); break; } default: { Console.WriteLine("Unknow hook type : " + hook.Type); break; } } }
static void InstallHookAfter(HookData hook) { if (!CheckSignatureCompatibility(hook.Host, hook.Virus, true)) { Console.WriteLine("Error : Method signature difference between Hook and Target"); return; } foreach (var arg in hook.Host.Parameters) { Console.WriteLine(arg.Name + " : " + arg.ParameterType); } foreach (var arg in hook.Virus.Parameters) { Console.WriteLine(arg.Name + " : " + arg.ParameterType); } bool hasReturnType = hook.Host.ReturnType.FullName != "System.Void"; VariableDefinition returnVar = null; if (hasReturnType) { returnVar = new VariableDefinition("returnVar", hook.Host.ReturnType); hook.Host.Body.Variables.Add(returnVar); } var ilp = hook.Host.Body.GetILProcessor(); var last = hook.Host.Body.Instructions[hook.Host.Body.Instructions.Count - 1]; // Ret // Store original return value if (hasReturnType) { ilp.InsertBefore(last, ilp.Create(OpCodes.Stloc, returnVar)); } // Add this parameter if (hook.Host.HasThis && !hook.Host.ExplicitThis) { ilp.InsertBefore(last, ilp.Create(OpCodes.Ldarg_0)); } // Add parameters foreach (var param in hook.Host.Parameters) { ilp.InsertBefore(last, ilp.Create(OpCodes.Ldarg, param)); } // Load original return value if (hasReturnType) { ilp.InsertBefore(last, ilp.Create(OpCodes.Ldloc, returnVar)); } ilp.InsertBefore(last, ilp.Create(OpCodes.Call, hook.Host.Module.Import(hook.Virus))); }
static List <HookData> GetHookList(AssemblyDefinition hookAssembly) { List <HookData> hooks = new List <HookData>(); foreach (var module in hookAssembly.Modules) { foreach (var type in module.Types) { foreach (var method in type.Methods) { HookData hook = GetHookAttribute(method); if (hook != null) { hooks.Add(hook); } } } } return(hooks); }
static void InstallHookBefore(HookData hook) { if (!CheckSignatureCompatibility(hook.Host, hook.Virus, false)) { Console.WriteLine("Error : Method signature difference between Hook and Target"); return; } if (hook.Virus.ReturnType.FullName != "System.Void") { Console.WriteLine("Error : Hook must return void"); return; } foreach (var arg in hook.Host.Parameters) { Console.WriteLine(arg.Name + " : " + arg.ParameterType); } foreach (var arg in hook.Virus.Parameters) { Console.WriteLine(arg.Name + " : " + arg.ParameterType); } var ilp = hook.Host.Body.GetILProcessor(); var first = hook.Host.Body.Instructions[0]; if (hook.Host.HasThis && !hook.Host.ExplicitThis) { ilp.InsertBefore(first, ilp.Create(OpCodes.Ldarg_0)); } foreach (var param in hook.Host.Parameters) { ilp.InsertBefore(first, ilp.Create(OpCodes.Ldarg, param)); } ilp.InsertBefore(first, ilp.Create(OpCodes.Call, hook.Host.Module.Import(hook.Virus))); }
static MethodDefinition FindTargetHook(AssemblyDefinition targetAssembly, HookData hook) { foreach (var module in targetAssembly.Modules) { foreach (var type in module.Types) { if (!(type.Namespace == hook.Namespace && type.Name == hook.Class)) { continue; } foreach (var method in type.Methods) { if (method.Name == hook.Method) { return(method); } } } } return(null); }