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;
}
3.类库开发所用到的语言
之前我说,我的这个库是完全用C#实现的,但其中的确用到了一个C写的反汇编库,于是我用C#把那个库重写了一遍,说来也简单,C的代码粘过来,C#启用unsafe代码,改了10分钟就好了,真心是非常方便,毕竟C#是支持指针和结构体的,而且基础类型非常丰富,这里得给C#点个赞!
4.具体使用
使用非常简单,首先新建控制台程序并添加一个类,继承接口IMethodMonitor,Get是你自己的函数,Ori是原函数会在运行时动态生成,在Get中你可以干你想干的任何事情
C# code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class CustomMonitor : IMethodMonitor //自定义一个类并继承IMethodMonitor接口
{
[Monitor("TargetNamespace", "TargetClass")] //你要hook的目标方法的名称空间,类名
public string Get() //方法签名要与目标方法一致
{
return "B" + Ori();
}
[MethodImpl(MethodImplOptions.NoInlining)]
[Original] //原函数标记
public string Ori() //方法签名要与目标方法一致
{
return null; //这里写什么无所谓,能编译过即可
}
}
然后定义目标函数,例如
C# code
1
2
3
4
public string Get()
{
return "A";
}
最后调用Monitor.Install()安装监视器,例如:
C# code
1
2
3
Console.WrtieLine(Get());
Monitor.Install()
Console.WrtieLine(Get());