64,637
社区成员
发帖
与我相关
我的任务
分享
#include <iostream>
#include <Windows.h>
using namespace std;
class Base
{
public:
virtual void PrintA()
{
cout<<"^-^"<<endl;
}
virtual void PrintB()
{
cout<<"T-T"<<endl;
}
};
class Derive:public Base
{
public:
virtual void PrintA()
{
cout<<":)"<<endl;
}
virtual void PrintB()
{
cout<<":("<<endl;
}
};
void Hack1()
{
cout<<"Hack1"<<endl;
}
int main()
{
Base *p=new Derive();
int PrintAAdress=*(int*)*(int*)p;//获取PrintA在虚表中的地址值
int PrintBAdress=*(int*)(*(int*)p+4);//获取PrintB在虚表中的地址值
//vc debug下函数指针值和函数名对应的地址开始,存放是一个jmp指令
//对应机器吗是0xe9
if (*(unsigned char*)PrintAAdress==0xe9)
{
DWORD d;
int PrintBOffset=*(int*)(PrintBAdress+1);//获取jmp指令后立即数的值
int Hack1Offset=*(int*)((int)Hack1+1);
//jmp 后立即数是相对于本条jmp指令的偏移,这里想把虚表的PrintA地址修
//改成PrintB,所以重新计算偏移
int diff=PrintBOffset-(PrintAAdress-PrintBAdress);
WriteProcessMemory(GetCurrentProcess(),(int*)(PrintAAdress+1), &diff, 4, &d);
diff=Hack1Offset-(PrintBAdress-(int)Hack1);
WriteProcessMemory(GetCurrentProcess(),(int*)(PrintBAdress+1), &diff, 4, &d);
//release下函数指针和函数名的值就是函数对应汇编指令的起始地址
}else{
DWORD dwIdOld;
HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,1,GetCurrentProcessId());
//把对应的内存页修改成可读写的,debug下权限比较大,所以可以直接读写
VirtualProtectEx(hProcess,(int*)*(int*)p,4,PAGE_READWRITE,&dwIdOld);
WriteProcessMemory(hProcess,(int*)*(int*)p, &PrintBAdress, 4, 0);
VirtualProtectEx(hProcess,(int*)*(int*)p,4,dwIdOld,&dwIdOld);
int Hack1Adress= (int)Hack1;
VirtualProtectEx(hProcess,(int*)(*(int*)p+4),4,PAGE_READWRITE,&dwIdOld);
WriteProcessMemory(hProcess,(int*)(*(int*)p+4), &Hack1Adress, 4, 0);
VirtualProtectEx(hProcess,(int*)(*(int*)p+4),4,dwIdOld,&dwIdOld);
}
//现在成功改写了虚表,所有Derive对象动态绑定,都会转到PrintB和Hack1上
p->PrintA();
p->PrintB();
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/Demon__Hunter/archive/2010/04/03/5447111.aspx