首先打开ce附加红警3的进程(注意要选对进程,是ra3_1.12.game)
找钱的数值9750
输入钱的数,点首次扫描
找到7个结果
在游戏内让钱发生改变
到ce内输入变化后的钱,点再次扫描
找到3个结果,双击添加到下面的框中
双击进行更改数值,然后回到游戏内看钱的变化情况,确定哪个才是真正的地址
发现04DF0AC4才是真正的地址.删除错误的地址,对真的地址进行追踪
右键地址选择”找出是什么改写了这个地址”,会要求附加调试器,选择是
再次回到游戏中,改变钱的数量,然后跳出来发现有了结果
往下察看,esi的值为04DF0AC0,第一个偏移4也出来了
记住偏移和值,接着开始搜索这个值,找到一个结果
把结果加到下面的框中右键选择”找出是什么前往了这个地址”
得到一个结果
有人就开始疑惑,这个的偏移是多少呢?接下来要怎么找呢?
先点击”显示反汇编程序”
往上退3行,有句xor eax,eax的指令,这是异或判断,如果eax=eax,结果就为0
EAX的值是结果是从ECX+EAX*4得来的,EAX=0,所以实际上句子是
mov eax,[ecx+0*4]
所以接下来我们要查找的地址是ECX=03B656C0,这里的偏移就是0
继续追踪
发现两个结果
选择sub那个结果
下一个要找到的地址是ECX=030FC320这里的偏移就是E4
接下来找出来的结果就有点多了,我们只能一个个找先
首先排除红色的,然后第一个和第四个没有结果,我们追到第5个
结果依然很多。。。。
但是我们发现,结果不外乎2个,一个是自己,那么另一个就是正确的值了
EAX=03B86878,偏移是28
接下来找到了一个绿色的值,那么这个就是基地址了,我们来验证一下
我们关闭游戏重开,重新附加,点“手工加入地址”,钩上指针,填写上绿色的地址,以我们找到的基地址反序添加
修改数值,发现游戏中的钱被修改了
这下地址和偏移都找到了,我们开始写程序吧
#include
#include
int main (void)
{
char input;
HWND hWnd;
DWORD pid;
HANDLE hProcess=0;
//钱的基地址和偏移
DWORD ba_addr=0x00CE8C9C;//基地址
DWORD m_offset1=0x28;//偏移1
DWORD m_offset2=0xE4;//偏移2
DWORD m_offset3=0x0;//偏移3
DWORD m_offset4=0x4;//偏移4
//电的偏移(钱与电基地址相同)
DWORD p_offset1=0x28;//偏移1
DWORD p_offset2=0x74;//偏移2
DWORD p_offset3=0x4;//偏移3
while(1)
{
printf("------------------------------------------\n");
printf(" O.打开外挂 M.修改金钱 \n");
printf(" P.修改电量 E.退出外挂 \n");
printf("------------------------------------------\n");
input=getchar();
if(input=='O'||input=='o')
{
hWnd=FindWindow(NULL,"命令与征服:红色警戒3");
if(hWnd!=0)
{
GetWindowThreadProcessId(hWnd,&pid);
hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);//打开进程,取得句柄
if(hProcess==0)
{
printf("打开游戏进程失败\n");
}
else
{
printf("打开游戏成功!!\n");
}
}
else
{
printf("游戏没有运行!!\n");
}
}if(input=='M'||input=='m')
{
if(hProcess==0)
{
printf("请先打开游戏进程");
}
else
{
DWORD m_tempadd;
DWORD MONEY;
printf("请输入要修改的钱\n");
scanf("%d",&MONEY);
ReadProcessMemory(hProcess,(LPVOID)ba_addr,&m_tempadd,4,0);
ReadProcessMemory(hProcess,(LPVOID)(m_tempadd+m_offset1),&m_tempadd,4,0);
ReadProcessMemory(hProcess,(LPVOID)(m_tempadd+m_offset2),&m_tempadd,4,0);
ReadProcessMemory(hProcess,(LPVOID)(m_tempadd+m_offset3),&m_tempadd,4,0);
//要修改的内存地址是(tempadd+offset4)
DWORD res=WriteProcessMemory(hProcess,(LPVOID)(m_tempadd+m_offset4),&MONEY,4,0);
if(res==0)
{
printf("修改失败");
}
else
{
printf("修改成功");
}
}
}
if(input=='P'||input=='p')
{
if(hProcess==0)
{
printf("请先打开游戏进程");
}
else
{
DWORD p_tempadd;
DWORD POWER;
printf("请输入要修改的电量\n");
scanf("%d",&POWER);
ReadProcessMemory(hProcess,(LPVOID)ba_addr,&p_tempadd,4,0);
ReadProcessMemory(hProcess,(LPVOID)(p_tempadd+p_offset1),&p_tempadd,4,0);
ReadProcessMemory(hProcess,(LPVOID)(p_tempadd+p_offset2),&p_tempadd,4,0);
//要修改的内存地址是(tempadd+p_offset3)
DWORD res=WriteProcessMemory(hProcess,(LPVOID)(p_tempadd+p_offset3),&POWER,4,0);
if(res==0)
{
printf("修改失败");
}
else
{
printf("修改成功");
}
}
}
if(input=='E'||input=='e')
{
break;
}
}
return 0;
}