#include <iostream>
#include <windows.h>
using namespace std;
typedef void(*pF)();
void test()
{
cout<<"this is a pFtest!"<<endl;
}
void fun()
{
cout<<"funfunction!!"<<endl;
}
void Hook(pF pf1,pF pf2)
{
//输入“JMP步长”指令的 地址
printf("pf1=%.8x\n",pf1);//fun=401087
printf("pf2=%.8x\n",pf2);//test=40102d
//输出了“JMP步长”指令 所代表的机器码
// +5(0003c4e9,因为是用INT*输出的,所以就少了一个字节的显示,应该是000003c4e9)
printf("*((int*)pf1=%.8x\n",*((int*)pf1));//机器码0003c4e9 E9 3c4 401087 + 3c4 + 5 = 00401450(函数体地址)
printf("*((int*)pf2=%.8x\n",*((int*)pf2));//机器码00036ee9 jmp 36e 40102d + 36e + 5 = 004013A0(函数体地址)
//(unsigned char*)pf2+1(因为char类型的指针加1就是加1个地址,为了进行计算地址用)
// 【C】data存了图中的绿线所代表的距离,但这时没加上指令JMP FUN2所占的5个字节
intdata= *((int*)((unsigned char*)pf2+1))// 输出了36E。见图上的黑线 【 A 】见图第一步,代表36e,没加上指令JMP FUN2所占的5个字节)
+
(int)pf2-(int)pf1;// 【 B】见图第二步,求两个过度地址之间的距离,用目标函数的过度地址减去被HOOK的函数过度地址地址,距离值也可能是负数,算上了JMP FUN1所占的5个字节)
SIZE_Tresult=0;
//下面的(int*)是为了让((unsignedchar*)pf1+1)这个地址指向4个内存单元的内容 (int*)((unsigned char*)pf1+1
WriteProcessMemory(
GetCurrentProcess(),//进程的句柄
((unsignedchar*)pf1+1),//指向被读取的内存在进程中基地址的指针 ,指向了步长3c4
&data, //为要写到指定进程的数据的指针
4,//指定从指定进程中要写入的字节数
&result//返回写入数据的实际字节数
);
【D】之所以data没对JMP FUN2指令所占的5进行计算,因为在调用函数的时候会自动加上5,例:机器码E9 3c4 401087 + 3c4 + 5 =00401450(函数体地址),这样这段距离的两个5,就都算了上(JMP FUN2的5是在调用函数的时候会自动加上5,JMP FUN2的5是在(int)pf2-(int)pf1加上的)
}
int main()
{
printf("\nHook=%.8x\n",Hook);
Hook(fun,test);
fun();
system("pause");
return0;
}