日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Game Hacking Fundamentals 学习笔记4

發布時間:2024/3/24 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Game Hacking Fundamentals 学习笔记4 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

書接上文,我們這次來學習多級指針的查找,上節課我們的游戲代碼并不復雜。在真正的游戲里,通常一個類里面還會包含另一個類,這類只裝著那個類的指針,那個類也可以繼續套娃。舉個例子,人物類包含背包類,背包類包含武器類,武器類也可以包含彈藥量等數據。
最終彈藥的數據可以根據如下指針路徑找到

Player->Inventory->PrimaryWeapon->ammo

這些路徑的長度在不同游戲中不同,一般都是3-7級指針。

對于一個游戲hacker來講,最重要的技巧之一就是找到我們感興趣的變量的可靠的指針路徑。
下面我們會介紹兩個方法來找到這個路徑,但是在此之前,我們需要再來寫一個更加復雜的游戲,包含多級指針。
個人建議下面的代碼不要復制,請自己手打,會大大加深你的理解。出現bug和問題自行百度,解決不了可以留言或者加我聯系。

#include <iostream> #include <stdlib.h> using namespace std; class Weapon{ private:int damage;int rate_of_fire;int ammo; public://construct for our weaponWeapon(int ammo, int damage, int rate_of_fire):damage{damage},rate_of_fire{rate_of_fire},ammo{ammo}{}void shoot(){--ammo;}int getammo(){return ammo;} }; class Inventory{ private:int selectedWeapon;Weapon* primaryWeapon;Weapon* secondaryWeapon;int grenadecount; public://construct for our inventoryInventory():selectedWeapon{0},grenadecount{2}{// allocate memory on the heap and create weapons thereprimaryWeapon = new Weapon(50,1,30);secondaryWeapon = new Weapon(10,5,90);}~Inventory(){ // gets called when Inventory gets deleted// free memory that was used by our weaponsdelete primaryWeapon;delete secondaryWeapon;}void switchWeapon(){selectedWeapon = selectedWeapon == 0 ? 1 : 0;}void fire_one_shot(){if (selectedWeapon == 0)primaryWeapon->shoot();elsesecondaryWeapon->shoot();}void throwGrenade(){--grenadecount;}int getGrenade(){return grenadecount;}int getSelected(){return selectedWeapon;}int getAmmo(){if (selectedWeapon == 0)return primaryWeapon->getammo();elsereturn secondaryWeapon->getammo();} };class Player{ private:int mana;int health;Inventory* inventory; public:Player(int health = 100, int mana = 100): mana{mana},health{health}{inventory = new Inventory();}~Player(){delete inventory;}int getMana(){return this->mana;}int getHealth(){return this->health;}void castSpell(){this->mana -= 5;}void applyDamage(int damage){this->health -= damage;}void switchWeapon(){inventory->switchWeapon();}void fire_one_shot(){inventory->fire_one_shot();}void throwGrenade(){inventory->throwGrenade();}void printInfo(){cout<< "\n\n\n-----------PLAYER:----------"<< "\nMANA:" << mana<< "\nHEALTH:" << health<< "\nGRENADE:" << inventory->getGrenade()<< "\nSELECT WEAPON:"<< ( (inventory->getSelected() == 0) ? "PRIMARY" : "SECONDARY" )<< "\nAMMO:" << inventory->getAmmo()<< "\n--------------------------- " << endl;} }; int main() {static Player* myPlayer = new Player();while (myPlayer->getMana() < 200 && myPlayer->getHealth() < 200){myPlayer->printInfo();cout << "1 - FIRE WEAPON | 2 - SWITCH WEAPON |"<< " 3 - THROW GRENADE | 4 - CAST SPELL | 5 - HIT YOURSELF"<< endl;cout << "SELECTION:";int selection;cin >> selection;switch(selection){case 1:myPlayer->fire_one_shot();cout << "YOU FIRED YOUR WEAPON!" << endl;break;case 2:myPlayer->switchWeapon();cout << "YOU SWITCHED YOUR WEAPON!" << endl;break;case 3:myPlayer->throwGrenade();cout << "YOU HAVE THROWN A GRENADE!" << endl;break;case 4:myPlayer->castSpell();cout << "YOU DID CAST A SPELL!" << endl;break;case 5:myPlayer->applyDamage(5);cout << "STOP HITIING YOURSELF!" << endl;break;}}delete myPlayer;cout << "You have made it!" << endl;system("pause");return 0; }

我們定義了三個類,我們創造一個player對象的時候,這個對象會創造一個新的inventory對象,這個inventory對象兩個新的weapon對象。
所以如果我們現在想訪問到selected weapon的ammo,我們不能直接訪問到,我們通過inventory類訪問到weapon類,通過player類訪問到inventory。
這就意味著,如果我們想找到一個可靠的指針路徑指向ammo,我們需要反向追蹤。
下面是具體措施:

  • 1 找到當前ammo的地址

很簡單不展開介紹了

  • 2 找到inventory對象中的weapon指針的地址
    右鍵主武器彈藥地址,找到什么寫入了這個地址,點擊確定,回去游戲中射擊一發,我們就看見窗口中多了一條指令,這條指令向我們的ammo地址寫入了數據。

雙擊這個指令可以看到詳細信息。

我們看到他把edx的值移動到了eax+08指向的地方。[]就是dereference,類似于*運算符。
中括號內就是值的地址,帶上括號就是地址內的值,在這個例子中就是我們的ammo。
我這里和書上的代碼不同,書上是dec [eax+08],edx ,可能是編譯優化的問題,你自己實踐的時候,只要能理解問題就可以了。繼續講解。
回憶一下我們的weapon的寫法,別忘了,方法的代碼不會放在某個實例中。

class Weapon{ private:int damage;int rate_of_fire;int ammo; }

C++代碼中,每個int占4字節,ammo前面有兩個int,所以從weapon類到ammo的偏移地址為2*4=8字節。
這也就解釋了為什么CE找到的代碼修改的值的地址偏移為0x8,我們把這個偏移量記作一級偏移。
也意味著weapon的地址就是eax,詳細信息里可以看到CE告訴我們eax值為00CEA588,也就是說inventory中的primaryPointer的值為00CEA588,我們現在去CE中搜索這個值,記得勾選上前面的HEX選項,代表你要搜索的值用16進制表示。
很奇怪的是,我的例子中搜索到了2個地址,很奇怪,因為按照代碼來說,應該是只有一個primaryweapon的指針呀。未來這種情況會不斷發生,我們需要非常耐心的反復嘗試,有時候多個指針路徑都可以成功,在這個例子中我們當然知道只有一個可以。

先繼續步驟,點擊右下角的add address manually (手動添加地址)
勾選指針,1處填入搜索到的結果地址,2處填入偏移地址8。這次以第二個地址為例子。

  • 3找到player對象中的inventory指針的地址
    我們現在需要找到指向inventory的指針的地址。重復我們找primarypointer的方法就可以了。
    右鍵我們剛才找的地址,這次選擇什么訪問了這個地址,因為這個指針沒有被寫入,但是被訪問來得到我們primary weapon的地址。
    在彈出的窗口中選擇是什么訪問了這個指針(自己思考下為什么吧)
    緊著著返回游戲再射擊一次。
    我們得到兩條指令。

雙擊第一個打開詳細信息。我們可以看到我們的primarypointer 通過dereference eax+0x4得到。
我們再來看一下我們的inventory類的定義代碼。

class Inventory{ private:int selectedWeapon;Weapon* primaryWeapon;Weapon* secondaryWeapon;int grenadecount; }

一個int4個字節,下面的就是我們指針了。
也就是inventory的地址+4=primarypointer的地址。
也就是說eax的只就是inventory在player對象中的地址。

記得詳細信息里面的寄存器的值都是在上面指令執行之后的值。
我們再次搜索十六進制值,但是不是下面的EAX的值,而是上面那一行可以直接復制的。
The value of the pointer needed to find this address is probably …
對這個值做一次hex掃描,這次還很幸運只得到一個結果,我們選擇手動添加地址,或者雙擊結果到下面再修改,勾選pointer,填入地址,填入兩個偏移,一級填4,add offset,二級填8,注意這里的數值都是16進制哦。


確定當前指針路徑正確之后,我們還是可以定位到ammo,下一步接著來找player的地址吧。
重復上次的步驟,右鍵指針,找到是什么訪問了這個地址,找到是什么訪問了這個指針,回游戲發射一次,我們又看到了代碼,表明我們現在做的還是正確的,若是沒有,可能就是某個步驟找錯了。

雙擊第一條指令查看詳細信息,我們就看到inventorypointer被[eax+08]訪問。

老規矩,回憶一下player類的寫法。

class Player{ private:int mana;int health;Inventory* inventory; }

兩個int在前,正好8字節,復制猜想值再做一次hex搜索,蕪湖,我們找到了一個夢寐以求的綠色地址

我們終于找到了我們player對象的地址,也找到了指向這個地址的靜態指針
手動添加地址,三層偏移由距離ammo的距離排列為8,4,8

最終我們得到了一條靜態的指針路徑,也就意味著即使游戲重啟我們也可以順著它找到primary ammo
不用再做搜索了。
也意味著我們以后編寫cheat程序可以使用這個路徑了。
這樣手動找指針路徑的練習是十分重要的,請務必自主實現一個,多多練習,這是你唯一真正理解和適應它的方法。
重啟游戲驗證下,哈哈,除了最后一個靜態指針,其他的都失效了,最后我們可以保存CT數據,ctrl+s即可,方便下次可以打開直接使用。

小作業,基于已有的結果,怎么快速找到primary damage,rate_of_fire?
小作業,找到grenadeCount的指針路徑,secondary ammo的指針路徑。
CE的詳細信息的值,就是當前變量結構體的頭,我們搜索他就是找到指到它的上一級指針。
最后放上一張圖解幫助你更好地理解

總結

以上是生活随笔為你收集整理的Game Hacking Fundamentals 学习笔记4的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。