(本文章原始記錄於 2008 年 9 月 3 日並於當日 Post 於巴哈姆特)

[指標搜尋]

前言:

鎖定第一關搜尋到的位址有效,到了第二關就無效時(甚至還沒進入第二關就當機了),該位址可能是由指標來指定的,有可能是因為物件導向程式設計的緣故,一切皆為物件所致;例如 Wario Land Shake! 中,壞利歐是一個物件,敵人也是物件,關卡本身也是一個物件,大容量遊戲由於主機記憶體有限,不可能一次將整個光碟資料都載入記憶體中,通常是在進入某關才載入該關應有的資料,例如該關出現的敵人及關卡音樂、圖片等。

進入一個關卡,可能會先載入關卡的物件,再載入敵人的物件,再載入主角的物件,這些物件以一定的順序排列(例如關卡圖片及音樂→眾多敵人→主角),但是資料量不見得一樣(例如第一關只有三種敵人,第二關就有十種敵人;或第一關路程短圖片少,而第二關圖片多),因此可能第一關關卡的圖片、音樂等資料用了 100 Bytes、敵人 50 Bytes、主角 20 Bytes,主角物件的開始位置就會在關卡物件資料開始後的第 151 Bytes 的位置;但是第二關關卡可能就用了 300 Bytes、敵人 100 Bytes、主角還是 20 Bytes,主角物件的開始位置就變成在關卡資料開始後的第 401 Bytes 的位置;

每一關所用到的資料量都不同,因此主角物件資料就不會固定在同一個位址上,而會動態配置。那程式要如何去找到實際的資料位址呢?這個時候就可能會使用到指標了。指標會記錄「物件最開始變數的位址」─ 記錄的是如 8031EA42 之類的位址,而非值。前面提到在關卡中的各項目物件會以一定的順序排列,而物件中的變數也會依序排列(例如主角的 HP→MP→Power,MP 所在位址一定會出現在 Power 之前,且在 HP 之後)。所以找到指標之後,就可以找到目前關卡主角物件的最開始位址(此位址會隨關卡而變動),然後這個位址偏移(Offset) XX 處代表的就是 HP,偏移 YY 處代表的就是 MP,只要鎖定指標所指位址偏移處的位址即可成功鎖定。

關於這部份可參考 dexter0 部落格 Hacking Example 2 之物件導向及指標說明
http://members.cox.net/dexter0/WiiHacking/example2.shtml

  1. 依一般搜尋方式尋找想要鎖定的位址,確定找到之後(一定要確定正確否則將白費力氣),於一覽中在找到的位址上點滑鼠右鍵→Pointer Address1 將位址傳至 Pointer Search 頁,或者切換到 Pointer Search 頁,手動將搜尋到的位址資料輸入 Address 1 欄位。
  2. 按下 File 1 右邊的 Dump 按鈕。會將目前關卡資料 dump 出來成為 DUMP180.BIN 檔案(此檔案會放在 WiiRd 根目錄下,亦即跟 WiiRdGUI.exe 同一個目錄中)。
  3. 離開目前的關卡,跳到「不同的關卡」,搜尋出正確的位址,再同前面 A.B. 步驟的操作,將位址資料填入 Pointer Search 的 Address 2 欄位,且按下 File 2 右邊的 Dump 鈕。

    這邊要注意的是先輸入到 Address 1 或 Address 2 都可以,但是對應的 Dump 檔要正確,如果第一次位址資料是輸入在 Address 2 中,則按 File2 右邊的 Dump 鈕(成DUMP280.BIN)
    依序為 (Address 1 + DUMP180.BIN) → (Address 2 + DUMP280.BIN)
    或者 (Address 2 + DUMP280.BIN) → (Address 1 + DUMP180.BIN)
    不管怎麼操作,Address 要對照到正確的 Dump 檔就是了。

  4. 兩項資料都輸入完成後,按下 Pointer Search 左下方的 Search! 按鈕即會開始搜尋指標。如果資料都輸入完成,但是 Search! 按鈕還是不能按時,只好手動載入 Dump 檔。按下 File 1 鈕,載入 DUMP180.BIN 檔,按下 File 2 鈕,載入 DUMP280.BIN 檔,如 B. 所述,這兩個檔案放在 WiiRd 的根目錄下。都載入的話,Search! 鈕應該就可以按了。
  5. 搜尋完畢,左下方就會出現搜尋到的資料一覽,右邊則是最佳可能位址一覽(Best Results)。會以 [Address]+Offset 的形式顯示(例如 [806B7B40]+2AE 之類),這代表該資料的位址會是在 [Address] 所指的「位址」加上 Offset 處。通常 [Address] 後面沒 Offset 的都不會是想要的正確位址,除非該物件的第一個變數所代表的就是想要找的資料。
  6. 將遊戲進入不同於前兩個搜尋時的關卡(這樣查找比較正確),切換到 Memory Viewer 頁籤,在左邊位址欄位中輸入於 Pointer Search 中所找到的 Address,
    (Best Results 一覽中,中括號 [ ] 裡面的數字)
    然後按下 Enter 鍵,就會跳到該記憶體處。在這裡可以看到它記錄著另一組記憶體數字。
  7. 打開附屬應用程式的小算盤,將模式切換到「工程型」(檢視→工程型)點十六進位,輸入步驟 F. 中所顯示的數字,然後加上 Pointer Search 該 Address 後面的 Offset 值,例如要測試 Best Results 中的 [806B7B40]+2AE,先用 Memory Viewer 找 806B7B40 位址,出現的值是 805A38F6 ,則在小算盤中輸入 805A38F6,再加上 Offset 的值 2AE ,加總完成的結果會是 805A3BA4。
  8. 再回到 Memory Viewer,輸入剛剛 Address + Offset 的值,然後按 Enter 跳到該位址,如果所顯示的資料是應有的值(例如應該顯示 HP 100 → 0064),則這個指標就是正確的。

後記:

搜尋幾個指標之後,可以發現指標是固定的,只有指標所指的位址會變動,
例如血的位址為 [806B7B40]+2AE,Power 的位址為 [806B7B40]+110 ,速度為 [806B7B40]+380,其中 806B7B40 都一樣,只有後面的 Offset 不同,這代表 806B7B40 這一個指標,會指向某個物件第一個變數的位址,此位址加上不同的偏移量,就代表不同的變數資料所在位址。可以想成 806B7B40 這個指標位址指向主角物件的開頭第一個變數位址,而 804F2AE4 這個指標位址則指向敵人物件的開頭第一個變數位址‧‧‧等等。