J'ai une classe scellée avec une méthode publique à l'intérieur d'un assemblage, je voudrais ajouter un système de journalisation mais malheureusement je n'ai pas les sources. Donc j'essayais de détourner cette méthode sur une méthode de journalisation spécifique et d'appeler l'original en sortie. L'accrochage fonctionne correctement mais je ne suis pas en mesure d'obtenir n'importe quel type de paramètres ou au moins je reçois quelque chose de complètement faux.Hook une méthode gérée à l'exécution en C#
Je ne peux pas non plus utiliser d'injection ou de bibliothèques comme PostSharp, alors je me demande si ce genre de choses peut être réalisé en cours d'exécution ou est-ce que je peux abandonner?
Juste pour vous donner plus de détails que je vais coller certaines parties de code ci-dessous:
public Hook(Delegate target, Delegate hook)
{
this.target = Marshal.GetFunctionPointerForDelegate(target);
targetDelegate = target;
this.hook = Marshal.GetFunctionPointerForDelegate(hook);
originalBytes = new byte[6];
Marshal.Copy(this.target, originalBytes, 0, 6);
byte[] hookPointerBytes = BitConverter.GetBytes(this.hook.ToInt32());
// Jump
newBytes = new byte[]
{
0x68, hookPointerBytes[0], hookPointerBytes[1], hookPointerBytes[2], hookPointerBytes[3], 0xC3
};
}
public object CallOriginal(params object[] args)
{
// Remove the patch
Uninstall();
// Invoke the original method
object ret = targetDelegate.DynamicInvoke(args);
// Re-apply the patch
Install();
return ret;
}
public sealed class Foo
{
public void DoSomething(Int32 value1)
{
// and here I am getting value1 = -1919988997
Console.WriteLine(value1);
}
}
class Program
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void DoSomethingDelegate(Int32 value1);
private static DoSomethingDelegate Original { get; set; }
private static DoSomethingDelegate Hooked { get; set; }
private static HookManager _hookManager;
public static void DoSomething(Int32 value1)
{
// This is called as well after foo.DoSomething but value1 is 251934152
Console.WriteLine("Hooked DoSomething: " + value1) ;
var hook = _hook["DoSomethingHook"];
// Call the original Foo.DoSomething
hook.CallOriginal(value1);
}
static void Main(string[] args)
{
RuntimeHelpers.PrepareMethod(typeof(Foo).GetMethod("DoSomething").MethodHandle);
_hookManager = new HookManager();
var originalPointer = typeof(Foo).GetMethod("DoSomething").MethodHandle.GetFunctionPointer();
Original = (DoSomethingDelegate)Marshal.GetDelegateForFunctionPointer(originalPointer, typeof(DoSomethingDelegate));
Hooked = DoSomething;
_hookManager.Add(Original, Hooked, "DoSomethingHook");
// Call Hook method, HookManager it is just an extended dictionary...
_hookManager.InstallAll();
var foo = new Foo();
// Calling the original method here with 1
foo.DoSomething(1);
Console.ReadLine();
}
}
GetMethod vous donnera un MethodInfo toutes les informations sur la méthode, y compris les types de paramètres – Gusman
Vous pouvez trouver cet article utile: http://www.codeproject.com/Articles/37549/CLR-Injection- Runtime-Method-Replacer – Amy
Merci @Gusman, je l'ai déjà vu. Mais il remplace la méthode originale par une autre, ce n'est pas vraiment ce dont j'ai besoin –