免責聲明:內容僅供學習參考,請合法利用知識,禁止進行違法犯罪活動!
本次游戲沒法給
內容參考于:微塵網絡安全
上一個內容:6.x86游戲實戰-C++實現跨進程讀寫-通過基址讀取人物狀態標志位
上一個內容通過基址得到了人物狀態標志,這種操作屬于讀取,既然有讀取那就有寫入,所以本次來搞寫入,本次通過找坐標改坐標實現瞬移來學習跨進程寫數據。
這里有一件事,代碼(c/c++代碼)中用的那些函數(函數也叫api)怎么知道的?怎么就知道它能這樣用?怎么知道有這種東西?
比如之前的 OpenProcess函數、ReadProcessMemory函數,怎么知道的這倆函數?
這都是老師講的,逆向會常用OpenProcess、ReadProcessMemory這兩個函數(當然不止這倆),這倆函數是Windows系統提供,自己找是真找不到,寫這些字是為了那些鉆牛角尖的,不要再鉆了,我代碼里寫什么就學什么,否則其它的函數你就算知道了,也可能不知道怎么玩,純浪廢時間
Spy++
使用OpenProcess函數時要寫一個pid,這個pid游戲重啟、操作系統重啟都會發送改變,每次都要找它的pid,有一個函數可以獲取pid,這個函數需要Spy++里的一點東西,如下圖打開Spy++
![]()
使用
![]()
找坐標
首先打開CE并附加游戲,游戲中小地圖附近會有坐標信息(有些游戲沒有,后面會寫沒有的怎么辦)
如上圖坐標現在是240,143,界面上顯示的是整數,但它實際上是小數,很少有游戲坐標數據用整數,然后,如下圖使用單浮點類型(為什么用單浮點?因為經驗,也有的游戲會用雙浮點,如果不知道用單浮點還是雙浮點那就這倆都試一試,試完就知道用哪個了(錯誤的會找不到想要的數據),優先使用單浮點),來掃描內存,然后掃描類型是值介于...兩者之間,游戲中坐標在窗口中看到的是100,它實際上可能是101、106、96這樣的(所以這種找法不好,后面會有其它方式找坐標,只能做入門來用)
然后首次掃描,找到14511個數據
![]()
然后移動角色更改坐標
![]()
再次掃描,然后就剩下18個
![]()
然后把這些全部添加到下方列表中
![]()
然后再選中一半,然后鼠標放到選中的數據上如下圖右擊選擇數值,把數據修改一下,如果把坐標修改了游戲中會有反應
![]()
把數據修改為50,然后游戲中沒有反應,這說明坐標數據并不在這些數據中
![]()
然后選擇剩下的數據做上方的操作
![]()
修改成60之后游戲有了反應(會瞬移)
![]()
然后現在還是有很多數據,具體哪個是坐標還不知道,然后先把這些改了沒反應的給刪除
![]()
然后再選一半改數據,這里改之前移動一下角色,讓它恢復一下坐標(網絡游戲本地改坐標沒用,移動一下(發送數據包)就會恢復)
![]()
最終發現了兩個,一個是人物頭頂名字的坐標,一個是人物坐標
![]()
找到坐標之后使用c++代碼對它們做出修改
代碼:
![]()
// ConsoleApplication4.cpp : 此文件包含 "main" 函數。程序執行將在此處開始并結束。 //#include <iostream> #include "Windows.h"int main() {/*FindWindowA函數通過窗口類和標題獲取窗口句柄""是從Spy++中類里復制來的NULL表示啥也沒有*/HWND hwd = FindWindowA("", NULL);DWORD pid;// 根據窗口句柄獲取進程pid,pid也就是線程idGetWindowThreadProcessId(hwd, &pid);HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);DWORD* address = (DWORD*)0x457A555C;float ret = 60;/*h進程句柄address要修改的內存地址,或者說修改什么內存地址里存放的值ret意思是把address(457A555C)地址的值修改成ret的值NULL不重要*/WriteProcessMemory(h, address, &ret, 4, NULL);address = (DWORD*)0x457A5544;ret = 60;WriteProcessMemory(h, address, &ret, 4, NULL);//跨進程讀內存(); }void 跨進程讀內存() {/*PROCESS_ALL_ACCESS表示全部權限FALSE表示不繼承,這個一般用不到,不用了解14384進程的Pid,詳情看文章中的圖h是進程句柄,句柄是用來代表一個進程的數字,由操作系統提供HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 14384); 這一句的意思是獲取14384進程的所有權限,并把句柄放到h中 */ //HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 14384); /*DWORD* 的意思是,* 表示當前的數據認定成內存地址,DWORD是4字節數字DWORD* 的意思是把xxx認定成內存地址,內存地址里的值是一個4字節數字(DWORD*)0xA107BC也就是把0xA107BC它當做內存地址來看待,0xA107BC內存地址里的值是一個4字節數字 */ //DWORD* buffer = (DWORD*)0xA107BC; //DWORD ret; /*h要讀取誰的內存buffer內存地址ret內存地址的數據4讀取4個字節NULL沒用&是取地址的意思,&ret的意思就是ret的內存地址ReadProcessMemory(h, buffer, &ret, 4, NULL); 這一句的意思是,從h的內存中的0x60BAA6A0位置開始讀取4字節,放到ret它里面,如果ret的大小沒有4字節會顯示有問題或程序崩潰 */ //ReadProcessMemory(h, buffer, &ret, 4, NULL); //printf("%d", ret);HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 15052);DWORD* buffer = (DWORD*)0xA107BC;DWORD ret;ReadProcessMemory(h, buffer, &ret, 4, NULL);//printf("%d", ret);buffer = (DWORD*)(ret + 0x60);ReadProcessMemory(h, buffer, &ret, 4, NULL);buffer = (DWORD*)(ret + 0x14c);ReadProcessMemory(h, buffer, &ret, 4, NULL);printf("人物狀態標志:%d\n", ret); }
?