C语言编写红色警戒外挂

首先打开ce附加红警3的进程(注意要选对进程,是ra3_1.12.game)

C语言编写红色警戒外挂_第1张图片

找钱的数值9750

C语言编写红色警戒外挂_第2张图片

输入钱的数,点首次扫描

C语言编写红色警戒外挂_第3张图片

找到7个结果

C语言编写红色警戒外挂_第4张图片

在游戏内让钱发生改变

C语言编写红色警戒外挂_第5张图片

到ce内输入变化后的钱,点再次扫描

C语言编写红色警戒外挂_第6张图片

找到3个结果,双击添加到下面的框中

C语言编写红色警戒外挂_第7张图片

双击进行更改数值,然后回到游戏内看钱的变化情况,确定哪个才是真正的地址

C语言编写红色警戒外挂_第8张图片

发现04DF0AC4才是真正的地址.删除错误的地址,对真的地址进行追踪

C语言编写红色警戒外挂_第9张图片

右键地址选择”找出是什么改写了这个地址”,会要求附加调试器,选择是

C语言编写红色警戒外挂_第10张图片

再次回到游戏中,改变钱的数量,然后跳出来发现有了结果

C语言编写红色警戒外挂_第11张图片

往下察看,esi的值为04DF0AC0,第一个偏移4也出来了

C语言编写红色警戒外挂_第12张图片

记住偏移和值,接着开始搜索这个值,找到一个结果

C语言编写红色警戒外挂_第13张图片

把结果加到下面的框中右键选择”找出是什么前往了这个地址”

C语言编写红色警戒外挂_第14张图片

得到一个结果

C语言编写红色警戒外挂_第15张图片

有人就开始疑惑,这个的偏移是多少呢?接下来要怎么找呢?
先点击”显示反汇编程序”
往上退3行,有句xor eax,eax的指令,这是异或判断,如果eax=eax,结果就为0
EAX的值是结果是从ECX+EAX*4得来的,EAX=0,所以实际上句子是
mov eax,[ecx+0*4]
所以接下来我们要查找的地址是ECX=03B656C0,这里的偏移就是0

C语言编写红色警戒外挂_第16张图片

继续追踪

C语言编写红色警戒外挂_第17张图片

发现两个结果

C语言编写红色警戒外挂_第18张图片

选择sub那个结果
下一个要找到的地址是ECX=030FC320这里的偏移就是E4
接下来找出来的结果就有点多了,我们只能一个个找先

C语言编写红色警戒外挂_第19张图片

首先排除红色的,然后第一个和第四个没有结果,我们追到第5个
结果依然很多。。。。

C语言编写红色警戒外挂_第20张图片

但是我们发现,结果不外乎2个,一个是自己,那么另一个就是正确的值了
EAX=03B86878,偏移是28

接下来找到了一个绿色的值,那么这个就是基地址了,我们来验证一下 

C语言编写红色警戒外挂_第21张图片

我们关闭游戏重开,重新附加,点“手工加入地址”,钩上指针,填写上绿色的地址,以我们找到的基地址反序添加

C语言编写红色警戒外挂_第22张图片

修改数值,发现游戏中的钱被修改了

C语言编写红色警戒外挂_第23张图片

这下地址和偏移都找到了,我们开始写程序吧

#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;
}


你可能感兴趣的:(游戏开发)