1. 嵌入的汇编机器代码(如函数地址:0x0040100F)

Mov eax, 0040100F 对应的机器码为:B8 0F 10 40 00
Jmp eax; 对应的机器码为:FF E0

其中,第2、3、4、5个字节取值会随自定义函数的地址不同而不同
CULHook类通过以下构建跳转指令的机器码(pfnHook为自定义函数地址)
BYTE btNewBytes[8] = { 0xB8, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xE0, 0x00 };

*(DWORD*)(btNewBytes + 1) = (DWORD)pfnHook;

2. 挂钩过程

(1) 在内存中寻址要挂钩的API函数

(2) 保存这个函数的前8个字节

(3) 使用上面构建的机器码重写这个函数的8字节。自定义函数必须和挂钩的函数有完全相同的签名:所有的参数、返回值、调用规则必须相同!

(4) 现在,当一个线程调用这个挂钩函数时,JUMP指令会跳转到组定义函数。自定义函数就可以干自己想干的事情了

(5) 恢复在第2步保留的字节,将它们放在挂钩函数的开头,以便取消挂钩

(6) 调用这个被挂钩的函数(挂钩已经取消了),执行之前的正常的函数

(7) 当原来的函数返回时,执行2、3步,再次挂钩API,以便自定义的函数在未来被调用

存在问题:不可解决的线程同步问题,但是对于挂钩单线程使用的API还是很有效的