2016-02-04 4 views
0

У меня есть закрытый класс с открытым методом внутри сборки, я хотел бы добавить систему ведения журнала, но, к сожалению, у меня нет источников. Поэтому я пытался объединить этот метод по определенному методу ведения журнала и вызвать исходный при выходе. Зацепка работает нормально, но я не могу получить какие-либо параметры или, по крайней мере, я получаю что-то совершенно неправильное.Подключить управляемый метод во время выполнения в C#

Я не могу использовать какие-либо инъекции или библиотеки, такие как PostSharp, поэтому мне интересно, можно ли достичь такого рода материала во время выполнения или я могу просто отказаться?

Просто чтобы дать вам некоторые детали я собираюсь вставить некоторые части кода ниже:

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(); 
    } 
} 
+0

GetMethod даст вам MethodInfo всю информацию о методе, включая типы параметров – Gusman

+0

Вы можете найти эту статью полезной: http://www.codeproject.com/Articles/37549/CLR-Injection- Runtime-Method-Replacer – Amy

+0

Спасибо @Gusman, я уже видел это. Но он заменяет оригинальный метод другим, это не так, как мне нужно –

ответ

0

решаемые, Marshal.GetFunctionPointerForDelegate: Я не могу использовать этот метод для создания делегата из функции указатель на другой управляемый делегат.

this.target = target.Method.MethodHandle.GetFunctionPointer(); //Marshal.GetFunctionPointerForDelegate(target); 
    targetDelegate = target; 
    this.hook = hook.Method.MethodHandle.GetFunctionPointer(); //Marshal.GetFunctionPointerForDelegate(hook); 

 Смежные вопросы

  • Нет связанных вопросов^_^