【前言】:
小弟我前幾天才剛剛接觸到《獸人必須死》這個(gè)游戲,發(fā)現(xiàn)主角真的很賤,不過玩起來很過癮。一直想下載個(gè)修改器來痛快虐虐獸人,但是下載的都報(bào)毒,不知道是真毒還是誤報(bào),反正老婆大人是不同意在她電腦上用。無奈,自己動(dòng)手豐衣足食吧。
【工具】
CE,這個(gè)就不說了,沒他啥也甭干了。
OD,就是OllyDbg,小弟我從事軟件安全工作,這個(gè)工具必不可少。
VC++,我就會(huì)C和匯編,其他不會(huì)。
【過程】
我打算就做2個(gè)功能,1個(gè)是鎖定錢,一個(gè)是鎖定魔法值。
先來做鎖定錢的,錢因?yàn)槭菙?shù)字,好分析。
1 先用CE找到金錢的地址,動(dòng)態(tài)地址就可以,不用找基址。如圖1.這個(gè)過程巨簡(jiǎn)單吧,我就不多說了。不會(huì)的童鞋可以看諸位大大的教程或者問我。
2.找到后,右鍵這個(gè)地址,選擇“什么改寫這個(gè)地址”。然后切換到游戲,花點(diǎn)錢,就能發(fā)現(xiàn)圖2的窗口。選擇顯示匯編,就是紅圈的那個(gè)。因?yàn)槲覀円治鰠R編語(yǔ)言。
3.接下來,選擇顯示匯編后,我們看見這個(gè)界面:
大家注意到,被高亮顯示的那句話就是我們的錢被改寫的匯編指令。我們可以看到,這句話在內(nèi)存地址00794B77的位置。當(dāng)然,各位童鞋要注意,你們顯示的地址肯定和我不一樣,我每次顯示的都不一樣。因?yàn)檫@是一個(gè)動(dòng)態(tài)鏈接庫(kù)(DLL),所以地址是動(dòng)態(tài)的。不過沒關(guān)系,下面我教大家怎么確定他的動(dòng)態(tài)地址。
4.知道了這個(gè)地址,我們就可以改了,但是,就像我說的,他每次都會(huì)在00794B77的位置上嗎?答案是否定的,退出游戲再進(jìn)來,地址就變了,因此我們可以肯定的是,這部分代碼應(yīng)該在動(dòng)態(tài)鏈接庫(kù)中。好,我們看看他在哪一個(gè)動(dòng)態(tài)鏈接庫(kù)中。點(diǎn)擊如下圖的菜單:
會(huì)顯示《獸人必須死》這個(gè)游戲所有加載進(jìn)來的動(dòng)態(tài)鏈接庫(kù)。如圖:
5.從此圖中我們看到,動(dòng)態(tài)鏈接庫(kù)SaberPlugin的開始地址是00730000,和我們的00794B77位置最近,因此,我們可以確定,剛才位于00794B77的指令在SaberPlugin的動(dòng)態(tài)庫(kù)中。
6.對(duì)于windows系統(tǒng),我們不知道每次動(dòng)態(tài)庫(kù)會(huì)被加載到內(nèi)存哪里,但是,我們可以通過系統(tǒng)一些功能函數(shù)得到動(dòng)態(tài)庫(kù)加載的基址,然后根據(jù)基址+偏移,最后得到目的地址。接下來,我們計(jì)算偏移。請(qǐng)看公式1:
目的地址 = 基址 + 偏移
偏移 = 目的地址 – 基址, 所以我們的偏移地址 = 00794B77 – 00730000 = 64B77。
7.接下來,OD出場(chǎng)了,呵呵,久等了。用OD 附加到游戲進(jìn)程,然后跳轉(zhuǎn)到指令00794B77的位置,童鞋們要注意了,這時(shí)候,要退出CE的調(diào)試,否者OD會(huì)報(bào)告進(jìn)程被其他程序加載而失敗。如圖所示:
8.從OD中了解到,該地址的指令是把寄存器EDI中的數(shù)值放到EAX+70的地址中,可以肯定的是,EDI中的數(shù)值就是金錢。該地址的二進(jìn)制指令從圖中可以看到,是:89 78 70。上圖紅圈處。為了簡(jiǎn)單起見,我直接將二進(jìn)制指令改成89 60 70,也就是把ESP中的數(shù)值放在EAX+70的地址中?隙ê枚嗤瑔枮樯丁Uf實(shí)話,就是我懶,因?yàn)檫@是個(gè)3字節(jié)的指令,如果我添加的指令長(zhǎng)度超過3字節(jié),就會(huì)覆蓋程序正常的指令,導(dǎo)致游戲崩潰。如果實(shí)在想添加多于3字節(jié)的指令,大家可以去看看遠(yuǎn)程代碼注入的知識(shí),做起來比較復(fù)雜,100樓之內(nèi)也說不清。所以,為了省時(shí)間,我直接就修改成ESP了。又有童鞋問了,為啥是ESP?呵呵,其實(shí)EAX,EBP,ECX…..等等,都成。因?yàn)镋SP數(shù)值肯定不會(huì)是0,所以錢肯定就不是0啊。我是偷懶。大家看我圖中,ESP的值是16進(jìn)制的0018E554,換成10進(jìn)制,大約是1631572這么多。好家伙,160多萬塊錢,夠了吧!
9.然后就是確定動(dòng)態(tài)庫(kù)基址的問題,大家請(qǐng)看代碼:
HMODULE checkModuleAddr(DWORD id)
{
HMODULE addr = 0;
MODULEENTRY32 me32={0};
//在本進(jìn)程中拍一個(gè)所有模塊的快照
HANDLE hModuleSnap=::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,id);
if(hModuleSnap==INVALID_HANDLE_VALUE)
return 0;
//遍歷快照中記錄模塊
me32.dwSize=sizeof(MODULEENTRY32);
//cout<<"模塊名稱及地址";
do
{
if(wcscmp(me32.szModule, modName) == 0)
{
addr = me32.hModule;
break;
}
}
while(::Module32Next(hModuleSnap,&me32));
CloseHandle(hModuleSnap);
return addr;
}
這段代碼就是獲得動(dòng)態(tài)庫(kù)的代碼,得到動(dòng)態(tài)地址后,加上剛才算的偏移(64B77),我們就能夠每次都算出目的地址啦,然后用WriteProcessMemory函數(shù)改寫成賦值ESP的二進(jìn)制,就大功告成啦。如圖(注意左下角的金錢):