天天看點

自己動手寫遊戲輔助工具

近期看到一個好玩的小工具“遊戲記憶體修改器”,其實就是一個簡易版的遊戲輔助工具。個人覺得可以作為C/C++初學者練習用,感受程式設計的樂趣,是以打算分享給大家看看。

背景

喜歡玩遊戲的同學應該都聽過遊戲輔助工具。抱着強烈的好奇心,想要了解一下什麼是遊戲輔助工具,它是怎麼工作的,無意中找到這份源碼,如獲珍寶。

當然,這裡算是一個簡易版的,在部分單機遊戲上可以用,不适用于網絡遊戲,那個會更複雜。

一個優秀的安全防禦專家,首先是一個熟知各種進攻手段的專家。期望這篇文章是你成為反作弊專家之路上的敲門磚,哈哈。

記憶體修改器工作原理

考慮簡單的情況,遊戲中的金币、血量、攻擊/防禦力等數值,是儲存在遊戲程序記憶體空間裡,我們隻要能夠通路遊戲程序的記憶體空間,搜尋到想要修改的資料位址,把數值修改掉就好了,是不是感覺So easy ?

程式運作後UI界面如下,在“選擇遊戲”中選擇遊戲程序,然後在“搜尋與修改”中輸入待修改的數值,點選搜尋後找到該數值的位址,并在“期待的值”中修改為目标數值,點選“修改”按鈕後生效。

自己動手寫遊戲輔助工具

為什麼說是簡單情況呢,因為專門氪金的遊戲是不會讓你這麼輕易得手的,比如對資料加個密,把資料儲存在伺服器上等等。魔高一尺道高一丈,就是在這持續的、絞盡腦汁的攻防轉換中,程式員們走上了從入門到秃頭的不歸路。

這篇文章我們隻看一個最簡單的情況,是以說是敲門磚。

源碼分析

1、關鍵API接口

(1)ReadProcessMemory:讀指定程序記憶體

(2)WriteProcessMemory:寫指定程序記憶體

2、關鍵代碼

(1)每次讀取大小為4K的1頁資料,将其中資料與待搜尋值進行比較,相等時将位址儲存進數組m_arList中。

BOOL CMemFinder::CompareAPage(DWORD dwBaseAddr, DWORD dwValue)
{
	// 讀取1頁記憶體
	BYTE arBytes[4096];
	if(!::ReadProcessMemory(m_hProcess, (LPVOID)dwBaseAddr, arBytes, 4096, NULL))
		return FALSE;	// 此頁不可讀

	// 在這1頁記憶體中查找
	DWORD* pdw;
	for(int i=0; i<(int)4*1024-3; i++)
	{
		pdw = (DWORD*)&arBytes[i];
		if(pdw[0] == dwValue)	// 等于要查找的值?
		{
			if(m_nListCnt >= 1024)
				return FALSE;
			// 添加到全局變量中
			m_arList[m_nListCnt++] = dwBaseAddr + i;
		}
	}

	return TRUE;
}
           

(2)第一次搜尋到的位址可能不唯一,如下函數可在此基礎上,進行第二次搜尋。

BOOL CMemFinder::FindNext(DWORD dwValue)
{
	// 儲存m_arList數組中有效位址的個數,初始化新的m_nListCnt值
	int nOrgCnt = m_nListCnt;
	m_nListCnt = 0;	

	// 在m_arList數組記錄的位址處查找
	BOOL bRet = FALSE;	// 假設失敗	
	DWORD dwReadValue;
	for(int i=0; i<nOrgCnt; i++)
	{
		if(::ReadProcessMemory(m_hProcess, (LPVOID)m_arList[i], &dwReadValue, sizeof(DWORD), NULL))
		{
			if(dwReadValue == dwValue)
			{
				m_arList[m_nListCnt++] = m_arList[i];
				bRet = TRUE;
			}
		}
	}
	
	return bRet;
}
           

工具測試

1、測試代碼如下;

#include <stdio.h>

int main()
{
	int money = 0;
	int flag = 0;

	printf("Please input money num:\n");
	scanf("%d", &money);

	while(1)
	{ 
		printf("%d\n", money);

		scanf("%d", &flag);

		if (flag == 1)
		{
			money++;
		}
		else if (flag == 2)
		{
			money--;
		}
		else
		{
			
		}
	}

	return 0;
}
           

2、測試結果如下

(1)測試程式中輸出金币初始值100。測試程序名字是GameDemo,在修改器中選擇。搜尋100所在的位址,可以看到有933個位址的數值是100;

自己動手寫遊戲輔助工具

(2)在測試程式中讓金币值增加1後為101,然後在修改器中搜尋101所在的位址,可以看到此時位址是唯一的。

自己動手寫遊戲輔助工具

(3)選中該位址後,将數值改為300,并點選修改。然後在測試程式中列印金币值,可見已經變為300了。

自己動手寫遊戲輔助工具

大功告成!

感興趣的同學關注“深眸視覺實驗室”,背景回複“遊戲修改器”可擷取源碼連結~

自己動手寫遊戲輔助工具