日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【转】托管函数的挂钩(完美版)

發(fā)布時間:2024/8/24 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【转】托管函数的挂钩(完美版) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原文:http://blog.csdn.net/cstod/article/details/6262506

CLR Injection: Runtime Method Replacer

http://www.codeproject.com/Articles/37549/CLR-Injection-Runtime-Method-Replacer

CLR Injection: Modify IL Code during Run-time

http://www.codeproject.com/Articles/463508/NET-CLR-Injection-Modify-IL-Code-during-Run-time

我之前發(fā)過一篇叫“托管函數(shù)的掛鉤”的文章,實現(xiàn)了對MarshalByRefObject繼承樹下的實例函數(shù)的掛鉤。?

最近,在CodeProject上看到一個關于托管函數(shù)掛鉤的文章,發(fā)現(xiàn)作者的方法很好用,但是正好不能用于MarshalByRefObject繼承樹下的實例函數(shù)(作者本人并沒有發(fā)現(xiàn)這個問題),于是兩種方法正好互補。

你也許要用,我為什么要強調MarshalByRefObject繼承樹呢?這是因為非常多的類都存在于該類的繼承樹下,比如很多人習慣把代碼寫在自己的窗體類中,而Form就在MarshalByRefObject樹下,從我的實際經驗來看,它比非MarshalByRefObject繼承樹的范圍更廣。?

我對兩種代碼進行了封裝,使用時只需調用ManagedReplacer.Replace方法即可。?

說明:托管函數(shù)在第一次被調用時會被JIT成本地代碼,之后會復用被JIT的本地代碼,所以一定要在函數(shù)被JIT之前進行掛鉤,否則將無效。

參考:http://www.sysnet.pe.kr/2/0/942

?

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; using System.IO; using RuntimeHelpers = System.Runtime.CompilerServices.RuntimeHelpers; using System.Runtime.InteropServices; using System.Reflection.Emit;namespace System {public static class MethodUtil{/// <summary>/// 將源方法替換為新方法/// </summary> public static void Replace(this MethodBase source, MethodBase dest){ReplaceMethod(source, dest, false);}public static void ReplaceMethod(MethodBase source, MethodBase dest, bool isDynamicSource){if (!MethodSignaturesEqual(source, dest)){throw new ArgumentException("The method signatures are not the same.", "source");}ReplaceMethod(GetMethodAddress(source), dest, isDynamicSource);}public static void ReplaceMethod(IntPtr srcAdr, MethodBase dest, bool isDynamicSource){IntPtr destAdr = GetMethodAddress(dest);unsafe{if (IntPtr.Size == 8){ulong* d = (ulong*)destAdr.ToPointer();if (isDynamicSource == true){*d = (ulong)srcAdr.ToInt64();}else{*d = *((ulong*)srcAdr.ToPointer());}}else{uint* d = (uint*)destAdr.ToPointer();if (isDynamicSource == true){*d = (uint)srcAdr.ToInt32();}else{*d = *((uint*)srcAdr.ToPointer());}}}}public static IntPtr GetMethodAddress(MethodBase method){if ((method is DynamicMethod)){return GetDynamicMethodAddress(method);}// Prepare the method so it gets jited RuntimeHelpers.PrepareMethod(method.MethodHandle);// If 3.5 sp1 or greater than we have a different layout in memory.if (IsNet20Sp2OrGreater()){return GetMethodAddress20SP2(method);}unsafe{// Skip theseconst int skip = 10;// Read the method index.UInt64* location = (UInt64*)(method.MethodHandle.Value.ToPointer());int index = (int)(((*location) >> 32) & 0xFF);if (IntPtr.Size == 8){// Get the method tableulong* classStart = (ulong*)method.DeclaringType.TypeHandle.Value.ToPointer();ulong* address = classStart + index + skip;return new IntPtr(address);}else{// Get the method tableuint* classStart = (uint*)method.DeclaringType.TypeHandle.Value.ToPointer();uint* address = classStart + index + skip;return new IntPtr(address);}}}private static IntPtr GetDynamicMethodAddress(MethodBase method){unsafe{RuntimeMethodHandle handle = GetDynamicMethodRuntimeHandle(method);byte* ptr = (byte*)handle.Value.ToPointer();if (IsNet20Sp2OrGreater()){RuntimeHelpers.PrepareMethod(handle);return handle.GetFunctionPointer();//if (IntPtr.Size == 8)//{// ulong* address = (ulong*)ptr;// address = (ulong*)*(address + 5);// return new IntPtr(address + 12);//}//else//{// uint* address = (uint*)ptr;// address = (uint*)*(address + 5);// return new IntPtr(address + 12);//} }else{if (IntPtr.Size == 8){ulong* address = (ulong*)ptr;address += 6;return new IntPtr(address);}else{uint* address = (uint*)ptr;address += 6;return new IntPtr(address);}}}}private static RuntimeMethodHandle GetDynamicMethodRuntimeHandle(MethodBase method){RuntimeMethodHandle handle;if (Environment.Version.Major == 4){MethodInfo getMethodDescriptorInfo = typeof(DynamicMethod).GetMethod("GetMethodDescriptor",BindingFlags.NonPublic | BindingFlags.Instance);handle = (RuntimeMethodHandle)getMethodDescriptorInfo.Invoke(method, null);}else{FieldInfo fieldInfo = typeof(DynamicMethod).GetField("m_method", BindingFlags.NonPublic | BindingFlags.Instance);handle = ((RuntimeMethodHandle)fieldInfo.GetValue(method));}return handle;}private static IntPtr GetMethodAddress20SP2(MethodBase method){unsafe{return new IntPtr(((int*)method.MethodHandle.Value.ToPointer() + 2));}}private static bool MethodSignaturesEqual(MethodBase x, MethodBase y){if (x.CallingConvention != y.CallingConvention){return false;}Type returnX = GetMethodReturnType(x), returnY = GetMethodReturnType(y);if (returnX != returnY){return false;}ParameterInfo[] xParams = x.GetParameters(), yParams = y.GetParameters();if (xParams.Length != yParams.Length){return false;}for (int i = 0; i < xParams.Length; i++){if (xParams[i].ParameterType != yParams[i].ParameterType){return false;}}return true;}private static Type GetMethodReturnType(MethodBase method){MethodInfo methodInfo = method as MethodInfo;if (methodInfo == null){// Constructor info.throw new ArgumentException("Unsupported MethodBase : " + method.GetType().Name, "method");}return methodInfo.ReturnType;}private static bool IsNet20Sp2OrGreater(){if (Environment.Version.Major == 4){return true;}return Environment.Version.Major == NetFxVersions.Net20SP2.Major &&Environment.Version.MinorRevision >= NetFxVersions.Net20SP2.MinorRevision;}#region NetFxVersionspublic static class NetFxVersions{public static readonly Version Net35 = new Version(3, 5, 21022, 8);public static readonly Version Net35SP1 = new Version(3, 5, 30729, 1);public static readonly Version Net30 = new Version(3, 0, 4506, 30);public static readonly Version Net30SP1 = new Version(3, 0, 4506, 648);public static readonly Version Net30SP2 = new Version(3, 0, 4506, 2152);public static readonly Version Net20 = new Version(2, 0, 50727, 42);public static readonly Version Net20SP1 = new Version(2, 0, 50727, 1433);public static readonly Version Net20SP2 = new Version(2, 0, 50727, 3053);}#endregion} }

?

??

?

devexpress patch for vs2015 packge :?devexpress.vspackage.vs2015.zip

?

?

IntelliJ IDEA 14?sn

(1)key:IDEA

value:61156-YRN2M-5MNCN-NZ8D2-7B4EW-U12L4?

(2)key:huangwei

value:97493-G3A41-0SO24-W57LI-Y2UGI-JGTU2?

(3)key:hkl520

value:34423-VZYXD-FQXZ7-O6I7U-J3ZK8-R7V62?

(4)key:Intelligent

value:40957-EG6O9-2915L-CF1RP-57IQJ-Y6VZ3?

(5)key:tommy

value:49164-YPNVL-OXUZL-XIWM4-Z9OHC-LF053?

(6)key:whuanghk

value:98220-IN97R-TV1ID-2JAPO-OXZEO-LAM70?

(7)key:itey

value:91758-T1CLA-C64F3-T7X5R-A7YDO-CRSN1

轉載于:https://www.cnblogs.com/zhahost/p/3660139.html

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的【转】托管函数的挂钩(完美版)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。