请依据实验文档《游戏辅助的实现》中的内容,自行编写一个游戏内存数据修改程序,使其可以对某款游戏的某一项或某几项数值进行修改。有余力的同学可以任选一款游戏尝试修改。
实验报告的最后请简述,作为游戏开发厂商,应该如何对抗本次实验所采用的辅助技术。
要求提交实验报告、编译好的exe程序以及cpp源代码。
实验文档与工具.rar
游戏内存修改的原理:
有以下步骤:
FindWindow(NULL, L"shooting")->GetSafeHwnd();
函数功能:该函数获得一个顶层窗口的句柄,该窗口的类名和窗口名与给定的字符串相匹配。这个函数不查找子窗口。在查找时不区分大小写。
GetWindowThreadProcessId(hWnd, &Pid);
函数功能:GetWindowThreadProcessId是一种计算机函数,功能是找出某个窗口的创建者(线程或进程),返回创建者的标志符,函数原型是DWORD GetWindowThreadProcessId。
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);
函数功能:OpenProcess 函数用来打开一个已存在的进程对象,并返回进程的句柄。
result = WriteProcessMemory(hProcess, (LPVOID)Address, &Score, 4, 0);
函数功能:WriteProcessMemory是计算机语言中的一种函数。此函数能写入某一进程的内存区域(直接写入会出Access Violation错误),故需此函数入口区必须可以访问,否则操作将失败。
总结就是:获得窗口句柄->获得该窗口的进程(在内存中)->打开进程->修改内存
//自定义内存修改
void CXianjianModiferhsb20190625Dlg::OnBnClickedButton2()
{
CString Cstr;
GetDlgItemText(IDC_EDIT4, Cstr);
int fix = _ttoi(Cstr);
CString Cstr2;
GetDlgItemText(IDC_EDIT4, Cstr2);
int address = _ttoi(Cstr2);
DWORD Pid;
HANDLE hProcess = 0;
DWORD Address = address;
DWORD Score = fix;
DWORD result;
HWND hWnd = FindWindow(NULL, L"shooting")->GetSafeHwnd(); ;
if (hWnd != 0) {
GetWindowThreadProcessId(hWnd, &Pid);
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);
if (hProcess == 0) {
//printf("Open process failed.");
MessageBox(L"Open process failed.", L"提示", MB_OK);
//return 0;
}
result = WriteProcessMemory(hProcess, (LPVOID)Address, &Score, 4, 0);
if (result == 0) {
//printf("Modify failed.");
MessageBox(L"Modify failed.", L"提示", MB_OK);
}
else {
//printf("Modify Success.");
MessageBox(L"Modify Success.", L"提示", MB_OK);
}
}
else {
//printf("Failed");
MessageBox(L"Failed", L"提示", MB_OK);
}
}
//默认内存修改
void CXianjianModiferhsb20190625Dlg::OnBnClickedButton3()
{
CString Cstr;
GetDlgItemText(IDC_EDIT4, Cstr);
int fix = _ttoi(Cstr);
CString Cstr2;
GetDlgItemText(IDC_EDIT4, Cstr2);
int address = _ttoi(Cstr2);
DWORD Pid;
HANDLE hProcess = 0;
DWORD Address = 0x0019FD48;
DWORD Score = fix;
DWORD result;
HWND hWnd = FindWindow(NULL, L"shooting")->GetSafeHwnd(); ;
if (hWnd != 0) {
GetWindowThreadProcessId(hWnd, &Pid);
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);
if (hProcess == 0) {
//printf("Open process failed.");
MessageBox(L"Open process failed.", L"提示", MB_OK);
//return 0;
}
result = WriteProcessMemory(hProcess, (LPVOID)Address, &Score, 4, 0);
if (result == 0) {
//printf("Modify failed.");
MessageBox(L"Modify failed.", L"提示", MB_OK);
}
else {
//printf("Modify Success.");
MessageBox(L"Modify Success.", L"提示", MB_OK);
}
}
else {
//printf("Failed");
MessageBox(L"Failed", L"提示", MB_OK);
}
}
通过此次学习了游戏内存修改,内存游戏修改的原理大概如下:
获得窗口句柄->获得该窗口的进程(在内存中)->打开进程->修改内存
作为游戏开发厂商,应该如何对抗本次实验所采用的辅助技术:
我认为防御游戏内存修改,就应该使发布同一种游戏的每一个游戏的内存地址都不变,可以通过随机添加注释对游戏内存地址进行偏移。这样,同一个游戏内存修改器只可以使用者自己游戏内存,而对于别人的游戏内存修改不能起到相应的作用,虽然可以通过使用CheatEngine找到要修改的每一个游戏内存地址,可是无疑增大游戏外挂开发者的成本,这样就可以有一定限度地做到防御游戏外挂开发者的作用了。
通过此次试验,收益良多。