111,076
社区成员




*((ulong*)((uint*)method.MethodHandle.Value.ToPointer() + 2)) = (ulong)ptr;
byte[] jmp_inst =
{
0x50, //push rax
0x48,0xB8,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90, //mov rax,target_addr
0x50, //push rax
0x48,0x8B,0x44,0x24,0x08, //mov rax,qword ptr ss:[rsp+8]
0xC2,0x08,0x00 //ret 8
};
protected override void CreateOriginalMethod(MethodInfo method)
{
uint oldProtect;
var needSize = NativeAPI.SizeofMin5Byte(srcPtr);
byte[] src_instr = new byte[needSize];
for (int i = 0; i < needSize; i++)
{
src_instr[i] = srcPtr[i];
}
fixed (byte* p = &jmp_inst[3])
{
*((ulong*)p) = (ulong)(srcPtr + needSize);
}
var totalLength = src_instr.Length + jmp_inst.Length;
IntPtr ptr = Marshal.AllocHGlobal(totalLength);
Marshal.Copy(src_instr, 0, ptr, src_instr.Length);
Marshal.Copy(jmp_inst, 0, ptr + src_instr.Length, jmp_inst.Length);
NativeAPI.VirtualProtect(ptr, (uint)totalLength, Protection.PAGE_EXECUTE_READWRITE, out oldProtect);
RuntimeHelpers.PrepareMethod(method.MethodHandle);
*((ulong*)((uint*)method.MethodHandle.Value.ToPointer() + 2)) = (ulong)ptr;
}
public class CustomMonitor : IMethodMonitor //自定义一个类并继承IMethodMonitor接口
{
[Monitor("TargetNamespace", "TargetClass")] //你要hook的目标方法的名称空间,类名
public string Get() //方法签名要与目标方法一致
{
return "B" + Ori();
}
[MethodImpl(MethodImplOptions.NoInlining)]
[Original] //原函数标记
public string Ori() //方法签名要与目标方法一致
{
return null; //这里写什么无所谓,能编译过即可
}
}
public string Get()
{
return "A";
}
Console.WrtieLine(Get());
Monitor.Install()
Console.WrtieLine(Get());
牛
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DotNetDetour;
using System.Runtime.CompilerServices;
namespace zzz
{
public class CustomMonitor : IMethodMonitor //自定义一个类并继承IMethodMonitor接口
{
[Monitor("zzz", "zzzzz")] //目标方法的名称空间,类名
public string Get() //方法签名要与目标方法一致
{
return "B" + Ori();
}
[MethodImpl(MethodImplOptions.NoInlining)]
[Original] //原函数标记
public string Ori() //方法签名要与目标方法一致
{
return null; //这里写什么无所谓,能编译过即可
}
}
class zzzzz
{
public string Get()
{
return "A";
}
public void z()
{
//CustomMonitor c = new CustomMonitor();
Console.WriteLine(Get());
Monitor.Install();
Console.WriteLine(Get());
}
}
class Program
{
static void Main(string[] args)
{
zzzzz z = new zzzzz();
z.z();
}
}
}
((Func<System.Data.SQLite.SQLiteCommand, string>)Delegate.CreateDelegate(typeof(Func<System.Data.SQLite.SQLiteCommand, string>), typeof(CustomMonitorTest).GetProperty("CommandText", BindingFlags.Instance | BindingFlags.Public).GetGetMethod(false)))).MethodHandle.GetFunctionPointer()
[Serializable, ClassInterface(ClassInterfaceType.AutoDual), ComVisible(true), __DynamicallyInvokable]
public abstract class Delegate : ICloneable, ISerializable
{
[SecurityCritical]
internal object _methodBase;
[SecurityCritical]
internal IntPtr _methodPtr;
[SecurityCritical]
internal IntPtr _methodPtrAux;
[SecurityCritical]
internal object _target;
}
就是委托的两个私有字段,普通反射也能获取到的。[/quote]
嗯,看了源码已经知道了。
对了,我还有一个问题,我在用src.MethodHandle.GetFunctionPointer()获取函数地址时,发现某些函数是不准确的,例如:System.Data.SQLite.SQLiteCommand.set_CommandText,获取的地址就不对,最后我只能通过hook clrjit.dll中的compileMethod方法并得到BYTE **nativeEntry参数的值来抓取函数真正的地址,不知你是否有什么办法能够解决这个问题