Steam 游戲 《Crashlands2》(崩潰大陸2)的 修改器制作 - 附修改過程
日期:2025.04.16
博客期:182
星期三
【溫馨提示】:
我現在把資源先放到開頭,不想研究學習的就直接取用。如果修改器失效了,你們可以在博客園本頁直接評論,也可以給我發郵件告訴我,就是不要到百度云上去說了,百度云我好久不登錄一次的!大家給我發郵件的話,記得要注明是哪個游戲,內容當然是越詳細越好啦!郵箱地址:nightskysxs@163.com
相關下載(CT文件【本文完結時發布】+簡易修改器):
百度云網盤下載:https://pan.baidu.com/s/1vtidvugrvF3kKeJ1sNLexw 提取碼:cras
夸克網盤下載:https://pan.quark.cn/s/f327cb3f8c6c 提取碼: Yssm
當前最新研究的版本如下圖:

當前最新的修改器圖示:

前言
在修改分析方面,二代相比一代來說很多機制都有所改變,如武器沒有了“品質改變”的情況、攻擊力的計算機制等等。但不妨礙它們有很多共通性質的東西——基本只存在雙浮點類型的數據 以及 物品數量的數據存在多份等等。這些共性無疑為我們去研究這款游戲的修改性提供了重要幫助!
如果你想把《崩潰大陸2》作為 CE 游戲修改的練習題,那么可以閱讀一下這篇文章,了解一下我的修改思路以及看看對你的修改技術提升有沒有幫助。
如果你已經看過我制作《崩潰大陸》一代這一期的博客并了解到了那一期的修改器思路,那么這篇文章可能對你的價值可能不是很高,請酌情閱讀。
正文
本修改使用的工具是 Cheat Engine,其下載以及漢化請參考其他博客教程。
在游戲修改之前,我們可以事先根據一代的功能進行暢想——說這一代我到底要做哪些功能呢?
a. 與生命值相關:[ 無限生命 ] 、[ 一擊必殺 ]
b. 與冷卻時間相關:[ 技能無冷卻 ] 、[ buff時間不減 ] 、[ 快速建造 ]
c. 與采集相關:[ 無限物品 ] 、[ 十倍采集資源 ]
d. 其他類型:[ 高級品質裝備 ]、[ 超級移速 ]、[ 隱身模式 ]、[ 圖紙限制解除 ]
好!我們暫且認為我們仍然要去實現以上功能,抱著這樣的期待,我們進入游戲吧!
FUN A:--------------------------------------【無限物品】
無限物品功能實現的是可使用物品數量的無限,也就是說需要將玩家收集到的物品數值改到一個非常大的數值(可以在游戲中被視為用不完的程度)。如果你會一些 Cheat Engine的基礎操作,很容易完成如下操作以實現單一物品的數量修改。
① 打開 Cheat Engine軟件,點擊左上角的小電腦選擇 “Crashlands2”進程,選擇“打開”!

② 選擇數值類型為雙浮點類型(如果是新游戲剛開始修改拿不準類型的話就選擇所有類型——所有類型默認包括單浮點、雙浮點和4字節整型);

③ 在游戲中查看你要修改的物品的當前數量(我搜索的是游戲中 “光草”的物品數量),將數值填入搜索框內,并點擊 “首次掃描”;(如游戲中 光草 的數量為 5,則搜索框內填入5.00;這樣基本可以篩選掉5.1、4.8等小數部分不為0的數值)
④ 在游戲中修改此物品的數量,并重新將更新的數值填入搜索框內,并點擊 “再次掃描” (對結果進一步的篩選);
⑤ 重復上一步,直到剩下了無法被篩選掉的幾項(本游戲中暫時為三項);

⑥ 按住 shift 熱鍵 點擊第一項和最后一項,完成三項地址的選中,鼠標右擊,再點擊 “改變已選中地址的數值”。

⑦ 在彈出的窗口的輸入框內填入要修改的數值(如49999)完成修改(為什么是49999?因為我還沒做一代修改器的時候,修改物品數量超過99999之后數據在保存時會被清零,后來我就改49999了)。

ok,會了以上步驟,你其實已經能夠使用CE修改這個游戲里所有物品的數量值了!當然,絕大部分的CE使用者也都是停留在這個階段的。那么有網友就會覺得每次修改都得走一整套上面的流程,這實在是太麻煩了!雖然節省了物品采集的繁瑣步驟,但是實際上游戲里面幾百種材料,我要來上這么幾百次,累計的工作量也屬實不小哦!就算我能夠控制游戲中的 a物品 和 b物品 的數量保持一致,然后在查找時一次性找出 a物品 和 b物品的地址來一定程度上減少我查找的次數!但其實這實際上也不能夠降低消耗的時間規模和操作復雜規模。所以需要采用 代碼注入的方式 將 一部分匯編碼 嵌入到源程序的代碼中去,來使得我們的無限物品以 “自動化” 的方式運行。
<1> 我們分別雙擊第④步找到的三個地址,并按照次序依次命名為 “FValue”、“MValue”、“LValue” (First Value、Middle Value、Last Value 僅表示了其地址大小關系,與CT表中的值不一定對應,以 CT 表 的 Act 中跳轉地址為準;簡單來說,叫什么名字無所謂,不要過分糾結CT表中和本文中的名字問題)。由于我們需要拿這三個值當作實例,所以我們還是把它們的物品數量改回 8.00 ;

<2> 要想實現 “無限物品”功能,就需要找到所有修改 FValue、MValue、LValue三個值的代碼,并把它們全部改寫成一個 對游戲來說算是無限大的值 就可以啦(此后無限物品部分,我將使用49999這個值)!
<3> 在開始修改前我們也要想好——修改物品數量 都會在游戲中對應什么樣的游戲操作。答案是:a. 采集物資 b.建筑模式放置以及拿回 c.工作臺上消耗物品以及產生產品 d.任務中獲取物資以及給出物資 e.技能中投擲物品消耗物品數量
<4> 考慮 “無限物品”功能的覆蓋性,我們要考慮在完成上述五個操作對應的代碼都要進行修改,也就是說理論上要我們找到 5 個模式下分別修改 3類值 的代碼,對應要找 5×3 = 15 次!這真的是太麻煩了,對不對?哼哼~我才不會告訴你們這里面有很多是重復的呢!是的,一般游戲作者也不會去寫那么多重復實現同一個功能的代碼的。之后,咱們考慮按照功能驗證的方式去實現咱們的 “無限物品”。就是先完成 采集部分對FValue的代碼修改,然后在游戲中驗證這個修改對15個點的覆蓋情況。當有一種情況發現未被覆蓋時,針對這種情況再做代碼修改,依此類推直到完成了以上 15個點的覆蓋。
接下來<5>到<30>,即為 采集部分對 FValue 的代碼修改部分。
<5> 我們對 FValue 鼠標右擊,選擇 “找出是什么改寫了這個地址” 。因為我們想要做出來的修改效果是:在我們獲取了一個物品的時候(物品數量被改寫的時候),就直接把數量改成 49999(無限)。如果選擇“找出是什么訪問了這個地址”范圍就會擴大,并囊括出諸如 “羅列物品清單時”、“物品數量不降為負值的校驗”等等。

<6> 在游戲中采集光草后(我這個物品數量是光草的數量),得到如下結果,點擊“顯示反匯編程序”,會彈出標題為 “Memory Viewer” 的內存查看器。

<7> 分析 mov [rbx],rax 一句,mov是賦值語句,左操作項是被賦值者,右操作項是要賦的值。用C來說的話就是:*(rbx) = rax 。由此對應到游戲的實際意義——在物品修改的代碼運行到這里時,rbx 寄存器存儲的是 FValue 的地址,即我們搜到的 28FA7B79250,而 rax 此時存儲的是 要被修改成多少的那個數值。由此,我們知道了這一段代碼是修改很多不同實際意義的雙浮點類型數據的一段代碼,可以給此處代碼設一個書簽(我這里是書簽0)方便我們訪問,如下圖。

<8> 此處設置斷點,我們發現斷點一直處于激活狀態,說明游戲的實時進程中對于此部分代碼的復用程度很高。但我們需要的是只有在物品被修改時,這個斷點才被激活,這樣我們才能夠確定物品修改所對應的CALL調用結構。有什么方法可以做到嗎?那就是先通過代碼注入的方式,將代碼改造成 “帶有是否來源于物品修改”的判定的代碼段,然后預留出是物品修改的情況的單獨代碼段(就是預留出給咱們加斷點的地方,哈哈)。注:別忘了把斷點刪除,并點擊運行使游戲恢復運行。
<9> 選中 書簽0 代碼段 (上圖 Crashlands2.exe+1EBC075 :mov [rbx],rax 一句),點擊菜單欄選擇 - 工具 - 自動匯編 (或者直接快捷鍵 Ctrl + A);

<10> 在自動匯編窗口下,在菜單欄中依次選擇 模板-CT表框架代碼、模板-代碼注入,代碼注入時的彈窗不用管(因為我們是選中地址進行匯編的,默認就是從這句開始注入),直接點擊 確認/OK,得到結果如下;
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,2048,"Crashlands2.exe"+1EBC075) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 mov [rbx],rax 13 mov rbx,[rsp+00000090] 14 15 exit: 16 jmp returnhere 17 18 "Crashlands2.exe"+1EBC075: 19 jmp newmem 20 nop 6 21 returnhere: 22 23 24 25 26 [DISABLE] 27 //code from here till the end of the code will be used to disable the cheat 28 dealloc(newmem) 29 "Crashlands2.exe"+1EBC075: 30 db 48 89 03 48 8B 9C 24 90 00 00 00 31 //mov [rbx],rax 32 //mov rbx,[rsp+00000090]
<11> 我們需要調整代碼邏輯為 “當此時來源于物品修改函數的CALL時執行一段空代碼”!我突然很想說數學上的一個四字詞語啊!就是 不難發現 啊,當 rbx 是 我們剛剛找到的光草物品數量的 FValue 時,此句在被執行的時候,肯定是恰好是物品修改的CALL。
<12> 我們把 originalcode 部分的源代碼剪貼到 exit 部分的開頭,之后在 originalcode 部分寫上針對于 rbx 地址的判別跳轉邏輯,以及符合條件的單獨代碼部分,如下部分。
cmp ebx,28C9E05BE10 // 比較 ebx 和 源地址的關系(rbx寄存器對應 8字節,ebx 對應 rbx 的后 4個字節,其實等價于 cmp ebx,9E05BE10。雖然不太嚴謹,但因為實現的實際效果基本一樣,我就這樣比較了。直接 cmp rbx,28C9E05BE10 會報錯,需要先賦值一個 rax ,再寫 cmp rbx,rax !但這樣很麻煩!)
jne exit // 上次比較關系中比較的結果如果是 不相等,則跳轉到 exit 這個 label 中去;
nop // 什么也不執行,用來代表物品被修改的情況(此時往下執行到 mov [rbx],rax一句過程中 rbx并未被修改)
jmp exit // 跳轉到 exit
完整代碼如下:
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,2048,"Crashlands2.exe"+1EBC075) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 cmp ebx,28C9E05BE10 13 jne exit 14 nop 15 jmp exit 16 17 exit: 18 mov [rbx],rax 19 mov rbx,[rsp+00000090] 20 jmp returnhere 21 22 "Crashlands2.exe"+1EBC075: 23 jmp newmem 24 nop 6 25 returnhere: 26 27 28 29 30 [DISABLE] 31 //code from here till the end of the code will be used to disable the cheat 32 dealloc(newmem) 33 "Crashlands2.exe"+1EBC075: 34 db 48 89 03 48 8B 9C 24 90 00 00 00 35 //mov [rbx],rax 36 //mov rbx,[rsp+00000090]
<13> 寫好代碼后,在菜單欄中選擇 文件-分配到當前的CT表,并命名為 “Break Point Check Test”(雙擊腳本的描述部分),再把勾打上表示激活,如圖所示源代碼已經注入成功;

<14> 我們下一步就是去 代表物品被修改的代碼段設置斷點,上圖我們是跳轉到了 7FF786B60000 。所以我們在代碼處,鼠標右擊選擇 “轉到地址” ,輸入你要跳轉的地址(我的是 7FF786B60000,系統給你生成的是什么可以參考上圖你的代碼改成了 jmp 哪里),然后!確認!
<15> 到了我們跳轉的地址后進行,在nop一句中設置斷點。(很重要:提前留意一下你修改的時候,游戲本體一定是窗口化的,而不是全屏。一來對照著游戲看CE里的信息方便一些;二來如果游戲設置了全屏,游戲被斷點卡住進程的時候,會出現切不出CE屏幕的情況,那真是太好笑了。除非用 Topmost軟件強制把窗口置頂)
<16> 回到游戲中,進行采集光草(物品)的活動,查看此時斷點的堆棧情況(圖中右下紅框部分即為此時的堆棧表)。

<17> 但是很明顯啊,這返回地址太假了!根本不是我們想要的!所以呢,接下來我們要把進程卡在Crashlands2進程的內存部分才好看出是調用的哪些CALL。我們按幾次 “步過” 按鈕,讓程序繼續執行下去,并跳回我們之前的 Crashlands2.exe+ ... 函數部分,如下圖,此時查看堆棧情況。

這是 針對于物品采集的函數CALL 調用此公用代碼段函數跳轉的情況。以上分別為一級返回,二級返回,三級返回,四級返回 ... ...
<18> 請保存好前面幾級的跳轉返回地址,并在 Memory Viewer (內存查看器)的菜單欄中選擇 視圖-斷點列表,右擊我們剛剛設置的斷點,把斷點刪除掉。再點擊運行。

<19> 程序運行之后,把 “Break Point Check Test”的勾劃掉(再點一次方框)。
<20> 拿出剛剛保存的 一級返回,二級返回,三級返回,四級返回的 堆棧表,跳轉到第一返回地址(我這里是 Crashlands2.exe+1EBBA63,在<17>下的圖上)的地址當中去(跳轉方法不會的再看一下<14>);
<21> 在一級返回地址的前一個CALL,就是調用這個CALL我們才會在那個公用代碼段里修改我們 光草物品數量的 FValue 值,直接在 CALL 這一句設置斷點。注:可以看到這里斷點被監測即將執行了,但是我們并沒有在游戲中做物品修改的操作,這說明這個CALL這一句仍然屬于共用代碼;

<22> 【不必操作】跳轉到第二返回地址(我這里是 Crashlands2.exe+1EE276F),重復 <21> 操作。再跳轉到第三返回地址(我這里是 Crashlands2.exe+1F03797),重復 <21> 操作。注:得到的結果都是一樣的,需要繼續向前找;
<23> 跳轉到第四返回地址(我這里是 Crashlands2.exe+108956E)重復 <21> 操作。誒~這次斷點沒有被監測到即將執行,回到游戲當中隨便采集一個光草(物品),斷點激活!這下沒問題了,只有在執行這個CALL的時候,是采集物品數量修改函數調用的。
<24> 我們在第三返回地址前面這個CALL這一句這里進行基礎匯編注入(自動匯編+CT表框架+代碼注入,不會的回看<9>、<10>);
在聲明部分定義一個8字節的變量 tag_of_ItemA,使用 alloc(tag_of_ItemA,8)聲明,后面的 [DISABLED]部分寫上釋放代碼 dealloc(tag_of_ItemA)
在聲明部分將tag_of_ItemA注冊為全局變量,使得其他的Script也能夠使用該變量,[ENABLE]部分寫 registersymbol(tag_of_ItemA) ,[DISABLED]部分寫 unregistersymbol(tag_of_ItemA)
代碼部分在 CALL 的前面部分 把 tag_of_ItemA 改為 1,CALL 之后 把 tag_of_ItemA 改為 0 (默認一開始 tag_of_ItemA 就是 0)。這樣的話,如果其他腳本在執行到 tag_of_ItemA == 1 的情況時就知道哦,我在改 FValue 的值。
[不重要] - 最一開始的 alloc(newmem,100) 中 2048 改為 100 是不想讓它分配那么大的空間(本身沒用多少地方,屬于優化項)。
所以把代碼調整為如下:
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+1089569) 4 alloc(tag_of_ItemA,8) 5 registersymbol(tag_of_ItemA) 6 label(returnhere) 7 label(originalcode) 8 label(exit) 9 10 newmem: //this is allocated memory, you have read,write,execute access 11 //place your code here 12 13 originalcode: 14 // Mark The Tag 15 mov [tag_of_ItemA],00000001 16 call Crashlands2.exe+1F036D0 17 mov [tag_of_ItemA],00000000 18 19 exit: 20 jmp returnhere 21 22 "Crashlands2.exe"+1089569: 23 jmp newmem 24 25 returnhere: 26 27 28 [DISABLE] 29 //code from here till the end of the code will be used to disable the cheat 30 dealloc(newmem) 31 dealloc(tag_of_ItemA) 32 unregistersymbol(tag_of_ItemA) 33 "Crashlands2.exe"+1089569: 34 db E8 62 A1 E7 00 35 //call Crashlands2.exe+1F036D0
之后,分配到CT表中,并命名為 “Act Ⅰ:在 "Crashlands2.exe"+1089569 處標記 FValue 的采集函數”(命名步驟見<13>),此后在本博文的 “無限物品” 部分,它將被我簡略描述為 “Act 1”。
<25> 將 “Act 1”激活,這樣我們得到了 “FValue 數據 是否在采集函數的CALL中執行 ” 這樣的一個 bool 值,接下來我們要做的是利用這個 bool 值來實現 “采集時將 FValue 值改為 49999”!
<26> 然后我們從跳轉回 書簽0 (還記得書簽0是哪個地址嗎?它是我們找到的修改 FValue 的代碼段地址),我們從那個地址的上一句開始進行代碼匯編 (自動匯編+CT表框架+代碼注入,不會的回看<9>、<10>,后面不再重復)。
Q:為什么要從那個地址的上一句進行匯編呢?
A:(下圖中 +...075是書簽0,+...072是我們選擇的匯編起始段)這是一個習慣問題。我們很容易看到如果對+...075匯編,那么它會占用 mov [rbx],rax 和 mov rbx,[rsp+00000090] 兩句的位置,后面開發其它功能還要用到此公用代碼的時候,代碼的注入位置就很難去安排,但如果往前走一句,后面 mov rbx,[rsp+00000090] 我就可以在實現其他功能的時候注入了,從而使這兩個功能的生效互相不會被干擾。而再往前其實我們的代碼路線是不清楚的,因為我們不確定是執行完了 Crashlands2.exe+1EBC6D 這個 CALL 之后執行的 +...072 還是從 +...068 直接跳轉過來的。綜上,+...072為最佳注入地址。

<27> 對代碼進行一些預處理:mov [rbx],rax 一句移動到 exit 的開頭, newmem 的分配空間調整為 100,此后我們開始加入一些代碼;
<28> 代碼中間部分的處理邏輯為 tag_of_ItemA 是 0,我就跳過不執行;如果 tag_of_ItemA 是 1,我就把 49999 的值 (Double:雙浮點)賦值給 rax;
push rdx // rdx 入棧
cmp [tag_of_ItemA],00000001 // 判定 CALL 的來源
jne exit // 不屬于 FValue 的采集 CALL ,直接跳轉正常執行
mov edx,#49999 // 將 十進制數 49999 賦值給 edx ,也可以寫 mov edx,C34F 。C34F 是 16進制數 ,我們手寫時記作 0xC34F。“#”用來做進制轉換
cvtsi2sd xmm0,edx // 將 edx 四字節數,轉化為 Double(8字節浮點數),類似于 C語言中的 xmm0 = (double)edx
movsd [tmp_unItem],xmm0 // 將 xmm0 的 Double 數值的 8 字節值賦值給 tmp_unItem所表示地址 (因為 movsd rax,xmm0 的格式是不被允許的,只能是 movsd xmm0,[ ]或者 movsd [ ],xmm0 這樣的格式;需要借助 tmp_unItem 變量完成賦值,需要用 alloc函數聲明)
mov rax,[tmp_unItem] // tmp_unItem 賦值給 rax
jmp exit // 代碼執行完畢跳回公共部分
pop rdx // 在 exit 中,rdx 出棧以保證堆棧平衡 (使用寄存器如果之前入棧了一些寄存器,代碼執行完一定要保證所有代碼執行路線的情況它們都出棧完畢)
<29> 這樣看上去貌似,我們已經實現了對于 FValue 的無限修改已經完成了。但是基于我第一代的修改經驗,這種代碼會出現游戲實際中的邏輯問題,這個涉及到 【物品】 的定義,我們認為的 【物品】是指的材料、工作臺這些,其實它還包括“武器”、“飾品”、“道具”、“圖紙項目”、“寵物蛋” 等等。其中,“武器” 和 “飾品” 等有一個特性就是數量就是1,我們不能修改它的數值為49999。另外,還有一種情況就是物品數量從 1 到 0 的情況,這種情況對應的是第一版的 “ 拆解 ”功能。拆解時武器數量從 1 到 0 ,如果不多加判定會導致武器拆解完后數量綁定到 49999,從而拆解失敗。但截至到目前為止我還沒有看到 “拆解” 功能,但邏輯上還是提前做了準備(結果只是物品數量被改成0時,不做修改而已)。
此部分代碼應放到 CALL 來源判定的后面。它先做 rax != 0 以及 rax != 1(Double)的判定,如果等于其中任意一個就跳轉 exit 不做修改
mov [tmp_unItem],rax // rax的值 給到 tmp_unItem 地址中的值
movsd xmm0,[tmp_unItem] // tmp_unItem 地址中的值 給到 xmm0
cvttsd2si edx,xmm0 // edx = (int)xmm0 將 xmm0 中的 8字節數據按照 Double 類型轉化為 4字節的 整型數
cmp edx,01 // 比較 edx 和 1
jna exit // if( edx <= 1) 跳轉 exit jna,不大于,<=
此處的完全體代碼如下:
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+1EBC072) 4 alloc(tmp_unItem,8) 5 label(returnhere) 6 label(originalcode) 7 label(exit) 8 9 newmem: //this is allocated memory, you have read,write,execute access 10 //place your code here 11 12 originalcode: 13 mov rax,[rsi] 14 15 // --------------------------------- [Insert Code] 16 // - edx --> var 17 push rdx 18 19 // --- When tag is True 20 cmp [tag_of_ItemA],00000001 21 jne exit 22 23 // --- The Item Now is Zero Or One ( value <= 1 ) 24 mov [tmp_unItem],rax 25 movsd xmm0,[tmp_unItem] 26 cvttsd2si edx,xmm0 27 cmp edx,01 28 jna exit 29 30 // --- change Item to 49999 31 mov edx,#49999 32 cvtsi2sd xmm0,edx 33 movsd [tmp_unItem],xmm0 34 mov rax,[tmp_unItem] 35 jmp exit 36 // --------------------------------- 37 38 exit: 39 pop rdx 40 mov [rbx],rax 41 jmp returnhere 42 43 "Crashlands2.exe"+1EBC072: 44 jmp newmem 45 nop 46 47 returnhere: 48 49 50 [DISABLE] 51 //code from here till the end of the code will be used to disable the cheat 52 dealloc(newmem) 53 dealloc(tmp_unItem) 54 "Crashlands2.exe"+1EBC072: 55 db 48 8B 06 48 89 03 56 //mov rax,[rsi] 57 //mov [rbx],rax
<30> 將此部分代碼分配到 CT 表后,命名為 “Act Ⅴ:When tag is true & the item now is not 1 or 0, just make item to 49999”,并放到“Act 1”的子項結點下,并給 “Act 1” 設置上群組的子項同啟用、同禁用,如下圖(這樣不會出現我把主項里的全局變量注銷了,后面子項還在用這個變量進而引發報錯的問題),此后這個子項稱為 “Act 5”。

<31> 在 “Act 1”激活的狀態下,激活 “Act 5”。做采集動作,然后看到的效果是只有 FValue 被修改了,說明需要再單獨分析 MValue 和 LValue 的情況。

<32> 先把“Act 1” 和 “Act 5” 的 Script 關閉掉(去掉勾),暫時不需要激活它們了,還有把 FValue 改回 和 MValue、LValue 一樣的值。這樣我們算是對 FValue 的采集函數做完了分析,之后其實是一個重復的過程。
<33> 【不用操作】我們對 MValue 鼠標右擊,選擇 “找出是什么改寫了這個地址” ,發現還是 Crashlands2.exe+1EBC075 這一句,和修改 FValue 是一樣的,不妨大膽一點,對,LValue 也是這樣的。
<34> 我們直接找到我們的“Break Point Check Test” 腳本!把里面的原本 FValue的地址 28C9E05BE10 改為 MValue 28C9E05BE40(cmp ebx,28C9E05BE10 → cmp ebx,28C9E05BE40),并開啟此腳本。
<35> 繼續在 nop 一句設置斷點,回到游戲采集光草,回來點擊 “步過” 按鈕,直到進程跳回 Crashlands2.exe+...,觀察此時的堆棧情況,如下圖。

<36> 在<21>、<22>步中,已經幫助我們排除了圖上 Crashlands2.exe+1EE276F 和 我這里是 Crashlands2.exe+1F03797 兩個返回地址同屬共用代碼段了。所以我們直接在三級返回地址 Crahlands2.exe+10897E8 前的CALL處設斷點,發現還是共用代碼段!只有在采集光草時,這段代碼被執行了!沒問題!這就是我們要加標記的地方了!取消斷點!仿照 “Act 1” 給這句匯編一下,加上標記,只不過標記不用新聲明了,就用之前的 tag_of_ItemA 就行。
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+10897E3) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 // Mark The Tag 13 mov [tag_of_ItemA],00000001 14 call Crashlands2.exe+1F036D0 15 mov [tag_of_ItemA],00000000 16 17 exit: 18 jmp returnhere 19 20 "Crashlands2.exe"+10897E3: 21 jmp newmem 22 23 returnhere: 24 25 26 [DISABLE] 27 //code from here till the end of the code will be used to disable the cheat 28 dealloc(newmem) 29 "Crashlands2.exe"+10897E3: 30 db E8 E8 9E E7 00 31 //call Crashlands2.exe+1F036D0
<37> 先把 “Break Point Check” 腳本關閉,再激活 “Act 1”,之后把代碼保存到 CT表,并命名為 “Act Ⅱ:在 "Crashlands2.exe"+10897E3 處標記 MValue 的采集函數” (簡稱 “Act 2”),并把這個腳本放到 “Act 1”的子項群組中!

<38> 同理,我們可以用同樣的方法,對 LValue 的采集修改函數 CALL 進行標記!(詳細過程省略)
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+108BD2E) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 // Mark The Tag 13 mov [tag_of_ItemA],00000001 14 call Crashlands2.exe+1EE2F80 15 mov [tag_of_ItemA],00000000 16 17 exit: 18 jmp returnhere 19 20 "Crashlands2.exe"+108BD2E: 21 jmp newmem 22 23 returnhere: 24 25 26 [DISABLE] 27 //code from here till the end of the code will be used to disable the cheat 28 dealloc(newmem) 29 "Crashlands2.exe"+108BD2E: 30 db E8 4D 72 E5 00 31 //call Crashlands2.exe+1EE2F80
<39> 這樣采集時完成 數據綁定 49999 的功能就完成了!接下來就要驗證其他的操作是否也會修改光草物品的值!繼續推進任務,在工作臺制作光葉斧,發現 LValue 值減少了 20,FValue 和 MValue 未改變!可以得到的結論是 “在工作臺制作上,需要將 LValue 的修改做進一步的補充(打補丁)”!

<40> 所以重復之前的步驟,將 “Break Point Check Test” 腳本的比較項改為 LValue 觀測返回地址,并重新打上標記!結果如下:
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+108E056) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 // Mark The Tag 13 mov [tag_of_ItemA],00000001 14 call Crashlands2.exe+1EE2F80 15 mov [tag_of_ItemA],00000000 16 17 exit: 18 jmp returnhere 19 20 "Crashlands2.exe"+108E056: 21 jmp newmem 22 23 returnhere: 24 25 26 [DISABLE] 27 //code from here till the end of the code will be used to disable the cheat 28 dealloc(newmem) 29 "Crashlands2.exe"+108E056: 30 db E8 25 4F E5 00 31 //call Crashlands2.exe+1EE2F80
<41> 在之后對剩下的游戲流程操作做驗證,發現這些代碼足夠覆蓋到所有物品修改的場景,OK,此功能完成啦!
<42> 【可有可無】之后就創建一個表頭名字叫做 “Fun A:Unlimited Items —— 【無限物品】”,把 “Act 1” 移動到這個表頭的子項上。給表頭設置上 同啟用、同禁用 和 未啟用時隱藏子項。給它們統一設置一個你喜歡的顏色用于代碼區分!結果如下:

【功能小結】:其實這第一個功能看似很繁瑣、勸退,但實際上核心就兩點。第一點是把參數比較的代碼注入共用代碼段來區別并找到特殊限制條件下的CALL(找上級CALL的方法),第二點是通過CALL的限定把共用代碼改造成為特定服務的代碼(上級多層CALL嵌套共用代碼段或調共用代碼段參數構成不明顯的情況)。
FUN B:--------------------------------------【無限生命】
無限生命在于解決玩家不斷被怪物傷害或狀態傷害削減生命的痛點。其主要方向是要找到玩家生命值的地址,然后鎖定生命值不減血。而鎖定生命值一可以通過找到玩家血量值的靜態地址映射關系,也可以直接去找生命值的修改地址,當玩家扣血時,我們把代碼扣血的邏輯刪除!
① 數值類型設置為雙浮點,搜索生命數值!
② 之后通過更改裝備,完成血量上限和生命值的變化,再次搜索得到如下結果即為玩家血量上限和玩家血量的地址。

③ 可以通過修改其中一個數值,另外一個不變的方式,搞清楚到底哪個是上限(其實大部分游戲都是上限在前)。
④ 將血量數值綁定到 999999,回游戲中查看情況,發現確實玩家打不死了(除非超過上限)!
其實到這里,這對于大多數玩家已經夠用了。只需要每次進入游戲后,搜一下數值,把數值改到很大,然后鎖定就好!但這樣會有一個問題哈,那就是地址的變動性!每次進入新存檔或者在游戲中傳送時,如果還鎖定著之前的地址,就會導致游戲崩潰掉!這時候我們首選找靜態地址映射關系的方法!如果找到一個穩定指向血量值的地址,就可以解決剛剛的問題!
<1>【不用做】對血量值的地址鼠標右擊,選擇 “對這個地址進行指針掃描”。

<2> 【不用做】選擇最大級別為 6,高級選項的第一項的勾取消掉(地址必須是32位的)。

<3>【不用做】掃描結果出來之后退回主菜單重進(或直接重啟游戲),重新按照 Double 類型的數值,對結果進行篩選。


<4> 【不用做】好吧,這樣操作之后發現,根本沒有固定的靜態地址映射關系!看來這種方法是行不通了,我們還是看看血量修改的代碼吧!
<5> 對 HP 值鼠標右擊,選擇 “找出是什么訪問了這個地址”。

<6> 得到結果如下,其中我在游戲中進行了 “回血”、“改裝備”的操作 。通過此處代碼邏輯,可以知道第 2 項是修改 HP 的,第 1 項才是獲取 HP 值的邏輯。

<7> 我們直接選擇第一項,隨時高頻訪問 HP 值的代碼,點擊 “顯示反匯編程序”!并對此處代碼設置 書簽0。并采用特值比較代碼注入的方法,找到是修改 HP 值的代碼段。
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,2048,"Crashlands2.exe"+1EBA7EA) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 cmp ebx,28C8C81D2C0 13 jne exit 14 nop 15 jmp exit 16 17 exit: 18 mov rax,[rbx] 19 mov [rdi],rax 20 jmp returnhere 21 22 "Crashlands2.exe"+1EBA7EA: 23 jmp newmem 24 nop 25 returnhere: 26 27 28 29 30 [DISABLE] 31 //code from here till the end of the code will be used to disable the cheat 32 dealloc(newmem) 33 "Crashlands2.exe"+1EBA7EA: 34 db 48 8B 03 48 89 07 35 //mov rax,[rbx] 36 //mov [rdi],rax
<8> 實際找到的是三級返回地址 Crashlands2.exe+131A4B4,在它之前的 CALL 一句上進行匯編,標記上這個來源。

1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+131A4AF) 4 alloc(tag_Hp_perm,8) 5 registersymbol(tag_Hp_perm) 6 label(returnhere) 7 label(originalcode) 8 label(exit) 9 10 newmem: //this is allocated memory, you have read,write,execute access 11 //place your code here 12 13 originalcode: 14 // --- 記錄調用 CALL 的 Tag 15 mov [tag_Hp_perm],00000001 16 call Crashlands2.exe+1EE2A80 17 mov [tag_Hp_perm],00000000 18 19 exit: 20 jmp returnhere 21 22 "Crashlands2.exe"+131A4AF: 23 jmp newmem 24 25 returnhere: 26 27 28 [DISABLE] 29 //code from here till the end of the code will be used to disable the cheat 30 dealloc(newmem) 31 dealloc(tag_Hp_perm) 32 unregistersymbol(tag_Hp_perm) 33 "Crashlands2.exe"+131A4AF: 34 db E8 CC 85 BC 00 35 //call Crashlands2.exe+1EE2A80
<9> 之后回到書簽0(高頻訪問 數值 的源代碼),重新在 "Crashlands2.exe"+1EBA7EA 處,進行匯編,具體代碼如下:
cmp [tag_Hp_perm],00000001 // 比較 標記值
jne exit // 不相等,跳轉到 exit
push rax // rax 入棧
mov eax,#99999999 // eax = 99,999,999
cvtsi2sd xmm0,eax // xmm0 = (double) eax
movsd [rbx],xmm0 // *(rbx) = xmm0
pop rax // rax 出棧
jmp exit // 跳轉到 exit
<10> 匯編完后,分配到 CT 表中,取名 “Act Ⅱ:If Tag Access, Change HP To 99,999,999”,放到 “Act 1”的子項,并給 “Act 1” 分配 同激活、同禁用。
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,2048,"Crashlands2.exe"+1EBA7EA) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 // --- When tag is True 13 cmp [tag_Hp_perm],00000001 14 jne exit 15 16 // --- change HP to 99,999,999 17 push rax 18 mov eax,#99999999 19 cvtsi2sd xmm0,eax 20 movsd [rbx],xmm0 21 pop rax 22 jmp exit 23 24 exit: 25 mov rax,[rbx] 26 mov [rdi],rax 27 jmp returnhere 28 29 "Crashlands2.exe"+1EBA7EA: 30 jmp newmem 31 nop 32 33 returnhere: 34 35 36 [DISABLE] 37 //code from here till the end of the code will be used to disable the cheat 38 dealloc(newmem) 39 "Crashlands2.exe"+1EBA7EA: 40 db 48 8B 03 48 89 07 41 //mov rax,[rbx] 42 //mov [rdi],rax
<11> 我們回到游戲中發現,誒血量值啟用后。玩家已經不怕傷害了,鎖死在了 10^9 - 1 ,這樣我們也完成了無限生命的功能開發。最后我們設置一下樣式,讓CT表更整潔一些。

<12> 實際上游戲中左側生命值展示欄也顯示了我們的血量修改情況!

FUN C:--------------------------------------【技能無冷卻】
技能冷卻數值很容易能夠找到,畢竟在游戲中玩家使用技能后,其冷卻值會直接顯示在對應的技能框上。而且這種技能冷卻值在游戲進程中是處于時刻變化的,所以我們需要有一定的游戲暫停手段。除此之外,基于浮點值的篩選條件,我們每次篩選時輸入的值應該間隔應該不低于2,所以我們還需要盡量挑選冷卻時間比較長的技能作為我們的參考項。
<1> 我們以游戲中的 “隱形花” 為例,“隱形花” 的技能冷卻值為 14 s 左右!在游戲中使用此技能后,看準游戲冷卻值顯示的值,快速按下 Esc 鍵(或M鍵),進入暫停狀態。(圖中各個菜單選項不全是暫停的,比如 “裝備” 菜單只是慢速)

<2> 一般篩選兩次就可以搜索到了,如下圖:

<3> 如果把它修改成 0,然后鎖定數值,就可以得到 “隱形花”的技能無冷卻!
<4> 但是我們現在要的是所有技能的冷卻值都不要有,所以還是需要注入一些小代碼!
<5> 我們對搜索到的 技能冷卻值 SkillCold 28C8C817610 選中,鼠標右鍵,選擇 “找出是什么改寫了這個地址”。

<6> 查找到了修改代碼地址后,選擇 “顯示反匯編程序”!

<7> 可以看到是和無限物品修改地址類似的代碼,所以一樣的思路使用 Break Point Check Test 監測它的上級返回地址。
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,2048,"Crashlands2.exe"+E73F2) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 cmp ebx,28C8C817610 13 jne exit 14 nop 15 jmp exit 16 17 exit: 18 mov [rbx],rax 19 mov rbx,[rsp+30] 20 jmp returnhere 21 22 "Crashlands2.exe"+E73F2: 23 jmp newmem 24 nop 3 25 returnhere: 26 27 28 29 30 [DISABLE] 31 //code from here till the end of the code will be used to disable the cheat 32 dealloc(newmem) 33 "Crashlands2.exe"+E73F2: 34 db 48 89 03 48 8B 5C 24 30 35 //mov [rbx],rax 36 //mov rbx,[rsp+30]
<8> 較為巧合地是,我們直接就可以使用一級返回地址來完成修改,而且在一級返回地址調用 CALL 到我們的修改地址之前,傳入參數 rcx (或 r15 )恰好是我們的被修改的技能冷卻地址。哦↑嗷↓嗷~現在我們知道 CALL Crashlands2.exe+E7360 之前的 rcx傳入值就是被修改的值!!!

<9> 所以我們就在 CALL 這一句進行匯編:先記錄上我們的 rcx 地址值,在CALL完之后,根據保存的技能冷卻地址,把冷卻修改為 0!
mov [skill_cold],rcx // 保存 rcx 值 , *(skill_cold) = rcx
call Crashlands2.exe+E7360 // 源代碼 CALL
push rcx // rcx 入棧
push rax // rax 入棧
mov rax,00000000 // rax = 0
xor rax,rax // rax = 0 ,自身異或操作等同于自身歸零
mov rcx,[skill_cold] // rcx = *(skill_cold)
mov [rcx],rax // *(rcx) = rax
pop rax // rax 出棧
pop rcx // rcx 出棧(rax 和 rcx 是兩個不同的寄存器,它倆之間的順序沒有那種先入后出的棧規則)
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+15F8A3) 4 alloc(skill_cold,8) 5 label(returnhere) 6 label(originalcode) 7 label(exit) 8 9 newmem: //this is allocated memory, you have read,write,execute access 10 //place your code here 11 12 originalcode: 13 mov [skill_cold],rcx 14 call Crashlands2.exe+E7360 15 push rcx 16 push rax 17 mov rax,00000000 18 xor rax,rax 19 mov rcx,[skill_cold] 20 mov [rcx],rax 21 pop rax 22 pop rcx 23 24 exit: 25 jmp returnhere 26 27 "Crashlands2.exe"+15F8A3: 28 jmp newmem 29 30 returnhere: 31 32 33 [DISABLE] 34 //code from here till the end of the code will be used to disable the cheat 35 dealloc(newmem) 36 dealloc(skill_cold) 37 "Crashlands2.exe"+15F8A3: 38 db E8 B8 7A F8 FF 39 //call Crashlands2.exe+E7360
<10> 再使用外表頭和特定顏色改造一下,這樣直接就完成啦!!!這個功能也是做起來非常簡單的一個功能!

FUN D:--------------------------------------【無限滾動】
這個功能其實是有兩種思路的,因為滾動這個技能比較特殊——它不僅有滾動技能恢復的冷卻值,還另外存有一個目前可釋放的滾動次數。那么兩種思路也很明顯了,要么把冷卻縮短到 0,要么鎖定了可釋放的滾動次數。那我們到底要選哪一個呢?聰明的人都發現了:“誒呀!這個冷卻值好像是個很抽象的數據啊,我們知道它是雙浮點數,但是滾動的冷卻本身恢復的就比較快。也就是說這個冷卻值呢,不太好找!那另外一個可釋放滾動次數呢?它不僅直接可以看到,甚至還是個整數——特別好搜!!!”這明眼人都知道要選第二種方法呀!
<1> 使用整數的浮點數搜索方法(整數+.00的值),搜索到 可釋放滾動次數的地址,保存下來并命名為 “Roll Times”。

<2> 對 “Roll Times” 鼠標右擊,選擇 “找出是什么修改了這個地址”。
<3> 然后找到的地址是和修改技能冷卻值一樣的代碼、一樣的地址。那么,還是使用 “Break Point Check Test” 注入代碼,監測 28C8C81B180 的數據的一級返回地址。
<4> 找到的 一級返回地址 是 Crashlands2.exe+148C93,那么我們在它之前的 CALL 一句進行匯編。
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+148C8E) 4 alloc(tmp_unRoll,8) 5 label(returnhere) 6 label(originalcode) 7 label(exit) 8 9 newmem: //this is allocated memory, you have read,write,execute access 10 //place your code here 11 12 originalcode: 13 mov [tmp_unRoll],rcx 14 call Crashlands2.exe+E7360 15 16 push rcx 17 // --- turn roll_value to 4 18 mov ecx,4 19 cvtsi2sd xmm0,ecx 20 mov rcx,[tmp_unRoll] 21 movsd [rcx],xmm0 22 pop rcx 23 24 exit: 25 jmp returnhere 26 27 "Crashlands2.exe"+148C8E: 28 jmp newmem 29 30 returnhere: 31 32 33 [DISABLE] 34 //code from here till the end of the code will be used to disable the cheat 35 dealloc(newmem) 36 dealloc(tmp_unRoll) 37 "Crashlands2.exe"+148C8E: 38 db E8 CD E6 F9 FF 39 //call Crashlands2.exe+E7360
<5> 再使用外表頭和特定顏色改造一下,這樣直接就完成啦!!!這個功能也是做起來非常簡單的一個功能!

FUN E:--------------------------------------【快速感悟心得】
在制作這個修改之前,我們肯定需要先做好心得修改的特殊存檔準備——首先要解鎖了心得、其次每個心得的感悟時間不能太短(一開始格拉爾的感悟很快,這時候不太時候用于搜索數據,最好把好感度降到最低)、最后要準備好兩個可感悟內容(一個感悟“修改”、一個感悟“暫停”)!
<1> 做好上述的存檔準備,例如把任務推進到如下圖這樣,并做好存檔備份(一旦修改過程中出現游戲崩潰,至少我們留存了存檔的備份、快照)。

<2> 我們把 “挖泥巴” 當作主目標,“上桌” 作為暫停工具,開始 “挖泥巴” 的心得研究!數值類型仍然為雙浮點類型,掃描類型為 “未知的初始值”。

<3> 此后隨著 “挖泥巴” 的研究進度的增加,我們把 “上桌”的研究開啟,這樣 “挖泥巴” 的研究進度就停止了。我們搜素 “增加的數值”,搜一遍。
<4> 之后按照 “未變動的數值” 再搜索一遍,繼續按照研究增加我就搜索“增加的數值”、研究停止我就搜索“未變動的數值”的模式對數據進行篩選;
<5> 直到我們就剩下兩個雙浮點的數據,其中只有第一個很明顯是研究進度的數值(第二個也算是因為第一個數值變動才被搜索到的)。

<6> 將此數值加入到地址欄中,并命名為 “Research Value”,之后鼠標右擊并選擇 “找出是什么改寫了這個地址”。
<7> 發現改動此地址的代碼和無限物品中物品改動的代碼是同一塊兒代碼,也就是 Crashlands2.exe+1EBC072,這也就表示后面我們注入的時候不能和無限物品的代碼注入同一個地方!!!
<8> 不過我們還是先編寫 “Break Point Check Test” 代碼,查找可以用于標記研究進度函數的返回地址前的CALL。
<9> 最后,我們在三級返回地址前找到了可以標記的 CALL。

1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+2835D2) 4 alloc(tag_perception,8) 5 registersymbol(tag_perception) 6 label(returnhere) 7 label(originalcode) 8 label(exit) 9 10 newmem: //this is allocated memory, you have read,write,execute access 11 //place your code here 12 13 originalcode: 14 mov [tag_perception],00000001 15 call Crashlands2.exe+1EE2F80 16 mov [tag_perception],00000000 17 18 exit: 19 jmp returnhere 20 21 "Crashlands2.exe"+2835D2: 22 jmp newmem 23 24 returnhere: 25 26 27 [DISABLE] 28 //code from here till the end of the code will be used to disable the cheat 29 dealloc(newmem) 30 dealloc(tag_perception) 31 unregistersymbol(tag_perception) 32 "Crashlands2.exe"+2835D2: 33 db E8 A9 F9 C5 01 34 //call Crashlands2.exe+1EE2F80
<10> 然后,在 "Crashlands2.exe"+1EBC078 處進行匯編,前面的 "Crashlands2.exe"+1EBC072 和 "Crashlands2.exe"+1EBC075 兩句已經被視為已經注入!
cmp [tag_perception],00000001 // 監測是否來源于研究進展函數
jne exit // 不是的話,就跳轉不修改
push rdx // rdx 入棧
mov edx,#69999 // edx = 69999 (4字節整型,十進制)
cvtsi2sd xmm0,edx // xmm0 = (Double) edx
movsd [tmp_pe],xmm0 // *(tmp_pe) = xmm0
mov rax,[tmp_pe] // rax = *(tmp_pe)
pop rdx // rdx 出棧
mov [rbx],rax // --- 因為要修改,把源碼前面一句補充上
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+1EBC078) 4 alloc(tmp_pe,8) 5 label(returnhere) 6 label(originalcode) 7 label(exit) 8 9 newmem: //this is allocated memory, you have read,write,execute access 10 //place your code here 11 12 originalcode: 13 // - 監測 Tag 標記 14 cmp [tag_perception],00000001 15 jne exit 16 17 // --- 修改部分 18 push rdx 19 mov edx,#69999 20 cvtsi2sd xmm0,edx 21 movsd [tmp_pe],xmm0 22 mov rax,[tmp_pe] 23 pop rdx 24 25 // --- 因為要修改,把源碼前面一句補充上 26 mov [rbx],rax 27 jmp exit 28 29 exit: 30 mov rbx,[rsp+00000090] 31 jmp returnhere 32 33 "Crashlands2.exe"+1EBC078: 34 jmp newmem 35 nop 3 36 37 returnhere: 38 39 40 [DISABLE] 41 //code from here till the end of the code will be used to disable the cheat 42 dealloc(newmem) 43 dealloc(tmp_pe) 44 "Crashlands2.exe"+1EBC078: 45 db 48 8B 9C 24 90 00 00 00 46 //mov rbx,[rsp+00000090]
<11> 將 “Act 2” 放到 “Act 1”的子項里面,然后給 “Act 1”設置上子項同啟用、同禁用;
<12> 再使用外表頭和特定顏色改造一下,這樣直接就完成啦!!!

FUN F:--------------------------------------【Buff時間鎖定】
看上去很難做,實際上一點兒也不難!我們需要事先準備好 “技能無冷卻” 功能 并 裝備好 “隱身花” 技能!
<1> 開啟 “技能無冷卻” 功能,然后激活一次,觀察左上角 隱身Buff 的持續時間。

<2> 對上述值進行精確搜索,注意不要讓 Buff 消失(如果快結束了就再激活一次技能),可以按 Esc 或 M 鍵暫停 Buff 時間的變動,根據這樣的規則篩選 Buff 時間數據。

<3> 我們找到了一個和 Buff 剩余的持續時間值相等的地址,但是通過鎖定它無法改變 Buff 時間持續減少的情況。這種情況很明顯就是被 “加密” 數據的情況,也就是說當前我們搜索到的這個地址是個 “看板”,它不能用就只能看!但我們要知道,這個游戲它只有雙浮點類型的數據,我們可以通過未知初始值加上變動與不變動的篩選方式慢慢篩選。這里我已經通過這種方式找到了加密方式啦!哈哈!說加密,其實也算不上,它并不是和一代一樣的 “持續時間”的模式,而是一種“已經持續時間”的模式。之前一代里我命名的功能叫做 “Buff時間不減”,二代這里叫做 “Buff時間鎖定”,這也是為了提醒學習的朋友,這里變動了。
<4> 明白機理之后,我們可以利用 Buff Time 來搜索 Buff Continuing Time,計算公式為 Buff Time + Buff Continuing Time = Buff Max Time。
<5> 開始搜索!當 Buff Time = 5.55 ,搜索 3;當 Buff Time = 7.530725,就搜索 0;
<6> 最終我們找到了 隱身Buff 的已持續時間,我們把它記錄到 CT 表內,命名為 “Buff Continuing Time”。

<7> 對 “Buff Continuing Time” 鼠標右擊,選擇 “找出是什么訪問了這個地址”,代碼是 Crashlands2.exe+1EBA7EA(這一看和Crashlands2.exe+1EBC075很近啊!) 。
<8> 編寫 “Break Point Check Test” ,查找返回地址!

<9> 選擇三級返回地址 Crashlands2.exe+490F78 ,找前面的 CALL 進行匯編標記!
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+490F76) 4 alloc(tag_buff_time,8) 5 registersymbol(tag_buff_time) 6 label(returnhere) 7 label(originalcode) 8 label(exit) 9 10 newmem: //this is allocated memory, you have read,write,execute access 11 //place your code here 12 13 originalcode: 14 mov [tag_buff_time],00000001 15 call Crashlands2.exe+1EE2A80 16 mov [tag_buff_time],00000000 17 18 exit: 19 jmp returnhere 20 21 "Crashlands2.exe"+490F76: 22 jmp newmem 23 24 returnhere: 25 26 27 [DISABLE] 28 //code from here till the end of the code will be used to disable the cheat 29 dealloc(newmem) 30 dealloc(tag_buff_time) 31 unregistersymbol(tag_buff_time) 32 "Crashlands2.exe"+490F76: 33 db E8 05 1B A5 01 34 //call Crashlands2.exe+1EE2A80
<10> 此后,查看可匯編地址。“無限生命”功能占用了我們的 mov rax,[rbx] 和 mov [rdi],rax 兩句,那我們就從后面的 mov al,01這句開始匯編!

我覺得代碼很簡單,所以就沒有加詳細解釋!
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+1EBA7F0) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 // --- Exam the Tag 13 cmp [tag_buff_time],00000001 14 jne exit 15 16 // --- Change To 0 17 xor rax,rax 18 mov [rbx],rax 19 mov [rdi],rax 20 21 jmp exit 22 23 24 exit: 25 mov al,01 26 add rsp,28 27 jmp returnhere 28 29 "Crashlands2.exe"+1EBA7F0: 30 jmp newmem 31 nop 32 33 returnhere: 34 35 36 [DISABLE] 37 //code from here till the end of the code will be used to disable the cheat 38 dealloc(newmem) 39 "Crashlands2.exe"+1EBA7F0: 40 db B0 01 48 83 C4 28 41 //mov al,01 42 //add rsp,28
<11> 將 “Act 2” 設置為 “Act 1” 子項,開啟子項 同啟用、同禁用,并使用外表頭和特定顏色改造一下!!!Complete!!!

FUN G:--------------------------------------【快速孵蛋】
<1> 做這個功能前,要把任務推進到 “鼻涕蟲” 即將可以孵化的狀態,如下圖,只要放置上 大肚燈 就可以開始孵化了(把大肚燈收回,孵化就會停止)。

<2> 按照“未知初始值”并慢慢控制其數值增加、不變,對孵蛋進度值的數據進行篩選。

<3> 對篩選結果命名為 “Egg Process”,觀察這個數據,它其實是孵蛋進度的百分比。當我們鎖定 “Egg Process”的時候,發現孵蛋進程果然被暫停了!
<4> 對 “Egg Process” 鼠標右擊,選擇 “找出是什么修改了這個地址”。

<5> 使用 “Break Point Check Test”,監測返回地址,如此一級返回地址前的 CALL 是經典的 CALL Crashlands2.exe+E7360 一句(在做 “技能無冷卻” 功能的第<8>步時,我們知道只需要在一級返回地址的CALL前記錄rcx就能得到進度的地址)!

<6> 對一級返回地址前的 CALL 一句進行匯編,思路等同于 “技能無冷卻”。(修改的值要變成綁定為 1.00 ,也就是 100%)
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+1283BCB) 4 alloc(tmp_egg_time,8) 5 label(returnhere) 6 label(originalcode) 7 label(exit) 8 9 newmem: //this is allocated memory, you have read,write,execute access 10 //place your code here 11 12 originalcode: 13 mov [tmp_egg_time],rcx 14 call Crashlands2.exe+E7360 15 push rcx 16 // --- turn tmp_egg_time to 1 17 mov ecx,1 18 cvtsi2sd xmm0,ecx 19 mov rcx,[tmp_egg_time] 20 movsd [rcx],xmm0 21 pop rcx 22 23 exit: 24 jmp returnhere 25 26 "Crashlands2.exe"+1283BCB: 27 jmp newmem 28 29 returnhere: 30 31 32 [DISABLE] 33 //code from here till the end of the code will be used to disable the cheat 34 dealloc(newmem) 35 dealloc(tmp_egg_time) 36 "Crashlands2.exe"+1283BCB: 37 db E8 90 37 E6 FE 38 //call Crashlands2.exe+E7360
<7> 好了,使用外表頭和特定顏色改造一下!!!

FUN H:--------------------------------------【十倍采集資源】
<1> 十倍采集資源和無限物品從功能角度上來說就是沖突的——畢竟不能保證撿到物品后加十的同時綁定49999!
<2> 所以我們可以使用之前 “無限物品” 功能實現過程中注入的代碼!但首先還是讓我們把 “無限物品” 功能抱持關閉掉的狀態,并參考物品的搜索方法找到 FValue、MValue、LValue;

<3> 這里搜到三個數值,但實際上我們也不知道這三個數值都對應我們之前 “無限物品” 里的那三個值,所以我們找到 “無限物品” 中標記采集函數的三個 CALL 的位置,分別設置斷點,來查看在CALL執行完后哪個值被修改了就是對應哪個 Value;

<4> 回到游戲中采集物品(我還是用的 光草),觀察數據的變化——發現先變化的是 LValue!之后暫停的地方是標記 MValue 采集函數的地方(也就是說下一個變化的是 MValue值)。

<5> 如下圖,標記上變化數值為 MValue。當然,還剩下最后一個就是 FValue了!

<6> 由此我們還知道了這三個值的修改順序:LValue→MValue→FValue,但是對于 MValue 和 FValue 來說這個位置并不全是它們的采集函數的代碼!忘了嗎?我們剛剛做完綁定采集函數時,使用工作臺消耗的時候,這個位置把 MValue 和 FValue 全修改成 49999 了!所以還需要考慮這兩個值在工作臺消耗和采集時分別被修改的情況!
<7> 【無需操作】我們取消掉所有斷點,只保留 MValue 采集函數的 CALL 用于做對比,堆棧對比結果如下圖所示:

<8> 【無需操作】我們在上圖 Crashlands2.exe+108B359 處,標記一層 Tag 這樣再從這個 CALL 調用的位置就是采集函數的了。
<9> 貌似這樣不太行啊,我們想要的不是單獨 MValue 一個值的采集函數,而是整體采集函數的標記,所以進一步繼續找 FValue 的采集函數來看 堆棧對比。

<10> 可以用的是上圖中綠色部分。啊?問我為什么給上面幾個地址打叉了?很明顯 Crahlands2.exe+1ED3988 這不是執行了很多次嗎?也就是說這肯定是一段共用代碼啊(本身采集函數都和自己共用這一部分了)!
<11> 我們在 Crashlands2.exe+109ED26處設置斷點,回到游戲工作臺消耗發現斷點被激活了...呃~情況很尷尬,我們繼續在 Crashlands2.exe+B18351 處設置斷點!重復工作臺消耗,結果很完美的沒有被執行!謝天謝地啊!
<12> 就在 這個 CALL 這里匯編設置標記,然后我們來整理我們的思路:
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+B18351) 4 alloc(tag_ObtainFun,8) 5 registersymbol(tag_ObtainFun) 6 label(returnhere) 7 label(originalcode) 8 label(exit) 9 10 newmem: //this is allocated memory, you have read,write,execute access 11 //place your code here 12 13 originalcode: 14 mov [tag_ObtainFun],00000001 15 call Crashlands2.exe+109DAF0 16 mov [tag_ObtainFun],00000000 17 18 exit: 19 jmp returnhere 20 21 "Crashlands2.exe"+B18351: 22 jmp newmem 23 24 returnhere: 25 26 27 [DISABLE] 28 //code from here till the end of the code will be used to disable the cheat 29 dealloc(newmem) 30 dealloc(tag_ObtainFun) 31 unregistersymbol(tag_ObtainFun) 32 "Crashlands2.exe"+B18351: 33 db E8 9A 57 58 00 34 //call Crashlands2.exe+109DAF0
<13> 根據下圖中的線性代碼執行表,我們分析出了修改方法,那就是采集函數對應各自的標記,使物品額外增加數值9!

<14> 為了保證 FValue、MValue、LValue 一致性,我們統一在最后修改 FValue值的時候,同時把十倍物資的 FValue 同步給 MValue 和 LValue,這也需要我們在前兩步記錄上 LValue 和 MValue 的地址!
<15> 注意到我們在 "Crashlands2.exe+1EBC072"處要對于不同的采集函數標記做不同的操作,實際上需要在 "Crashlands2.exe"+108BD21、"Crashlands2.exe"+1089569、"Crashlands2.exe"+10897E3 三處設立不同的 Tag 用于區分這三處來源!那我們實際上分析 "Crashlands2.exe"+B15831 處設立的 Tag ,可以完全支持對這三處的修改。

1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+108BD2E) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 // 查驗標記是否成立 13 cmp [tag_ObtainFun],00000001 14 jne exit 15 16 // --- 記錄調用 CALL 的 Tag - LValue -> 2 17 mov [tag_ObtainFun],00000002 18 call Crashlands2.exe+1EE2F80 19 mov [tag_ObtainFun],00000001 20 jmp returnhere 21 22 exit: 23 call Crashlands2.exe+1EE2F80 24 jmp returnhere 25 26 "Crashlands2.exe"+108BD2E: 27 jmp newmem 28 29 returnhere: 30 31 32 [DISABLE] 33 //code from here till the end of the code will be used to disable the cheat 34 dealloc(newmem) 35 "Crashlands2.exe"+108BD2E: 36 db E8 4D 72 E5 00 37 //call Crashlands2.exe+1EE2F80
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+1089569) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 // 查驗標記是否成立 13 cmp [tag_ObtainFun],00000001 14 jne exit 15 16 // --- 記錄調用 CALL 的 Tag - MValue -> 3 17 mov [tag_ObtainFun],00000003 18 call Crashlands2.exe+1F036D0 19 mov [tag_ObtainFun],00000001 20 jmp returnhere 21 22 exit: 23 call Crashlands2.exe+1F036D0 24 jmp returnhere 25 26 "Crashlands2.exe"+1089569: 27 jmp newmem 28 29 returnhere: 30 31 32 [DISABLE] 33 //code from here till the end of the code will be used to disable the cheat 34 dealloc(newmem) 35 "Crashlands2.exe"+1089569: 36 db E8 62 A1 E7 00 37 //call Crashlands2.exe+1F036D0
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+10897E3) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 cmp [tag_ObtainFun],00000001 13 jne exit 14 // --- 記錄調用 CALL 的 Tag - FValue -> 4 15 mov [tag_ObtainFun],00000004 16 call Crashlands2.exe+1F036D0 17 mov [tag_ObtainFun],00000001 18 jmp returnhere 19 20 exit: 21 call Crashlands2.exe+1F036D0 22 jmp returnhere 23 24 "Crashlands2.exe"+10897E3: 25 jmp newmem 26 27 returnhere: 28 29 30 [DISABLE] 31 //code from here till the end of the code will be used to disable the cheat 32 dealloc(newmem) 33 "Crashlands2.exe"+10897E3: 34 db E8 E8 9E E7 00 35 //call Crashlands2.exe+1F036D0
<16> 這樣我們就可以確定在 "Crashlands2.exe+1EBC072"處,這個 Tag 分別對應 2、3、4時,是修改我們 LValue、MValue、FValue值了,所以下面就是關鍵代碼了,在 "Crashlands2.exe+1EBC072" 處進行匯編:
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,200,"Crashlands2.exe"+1EBC072) 4 alloc(FValue,8) 5 alloc(MValue,8) 6 alloc(tmp_unItem,8) 7 registersymbol(FValue) 8 registersymbol(MValue) 9 label(returnhere) 10 label(originalcode) 11 label(exit) 12 label(fvalue_con) 13 label(mvalue_con) 14 15 newmem: //this is allocated memory, you have read,write,execute access 16 //place your code here 17 18 originalcode: 19 mov rax,[rsi] 20 push rdx 21 22 // --- 0 or 1 means not F M L Value Obtain Function 23 cmp [tag_ObtainFun],00000001 24 jbe exit 25 cmp [tag_ObtainFun],00000002 26 je fvalue_con 27 cmp [tag_ObtainFun],00000003 28 je mvalue_con 29 30 // --- tag_ObtainFun = 4! 31 // 32 // --- The Item Now is Zero Or One ( value <= 1 ) 33 mov [tmp_unItem],rax 34 movsd xmm0,[tmp_unItem] 35 cvttsd2si edx,xmm0 36 cmp edx,01 37 jna exit 38 39 // --- 為確保 三值的一致性,統一放到一起修改!!!(先修改 [rsi]) 40 add edx,09 41 cvtsi2sd xmm0,edx 42 movsd [tmp_unItem],xmm0 43 mov rax,[tmp_unItem] 44 mov [rsi],rax 45 46 // --- 修改 FValue 和 MValue 47 mov rdx,[FValue] 48 mov [rdx],rax 49 mov rdx,[MValue] 50 mov [rdx],rax 51 jmp exit 52 53 fvalue_con: 54 // 保存 FValue 地址 55 mov [FValue],rbx 56 jmp exit 57 58 mvalue_con: 59 // 保存 MValue 地址 60 mov [MValue],rbx 61 jmp exit 62 63 exit: 64 pop rdx 65 mov [rbx],rax 66 jmp returnhere 67 68 "Crashlands2.exe"+1EBC072: 69 jmp newmem 70 nop 71 72 returnhere: 73 74 75 [DISABLE] 76 //code from here till the end of the code will be used to disable the cheat 77 dealloc(newmem) 78 dealloc(FValue) 79 dealloc(MValue) 80 dealloc(tmp_unItem) 81 unregistersymbol(FValue) 82 unregistersymbol(MValue) 83 "Crashlands2.exe"+1EBC072: 84 db 48 8B 06 48 89 03 85 //mov rax,[rsi] 86 //mov [rbx],rax
<17> 前面的 label 是添加標簽的語句,寫上 label(fvalue_con) 之后,就可以寫 fvalue_con 代表的代碼,并考慮情況跳轉到 fvalue_con 部分,如 jmp fvalue_con;
<18> 代碼邏輯也算是比較簡單,可以直接看代碼里的注釋。
<19> 之后把 Act 2~5 作為 Act 1 的子項,給 Act 1設置好 子項同啟用&禁用。
<20> 好了,再使用外表頭和特定顏色改造一下!!!

FUN I:--------------------------------------【統計任務速達】
<1> 這個功能實現起來很簡單,它也不過是一個整數雙浮點而已。但它的問題在于很容易卡關,尤其是這個數值影響著很多物資能否采集。比如,最后要有一個主線任務要采集17朵南瓜掌,如果目標值大于等于17,那南瓜掌的采集功能就會失效!此時,如果你沒有開啟無限物品,南瓜掌物品的數量低于17,無法交付任務,那么恭喜你!你存檔成功的死掉了!所以,這個功能要配合無限物品來實現。無限物品的邏輯是物品數量只存在 0,1,49999!那我們的任務目標也就只存在 0,1,49999。它其實是和目標綁定一致!
<2> 首先,還是快速的搜索到這個統計項的數值,然后鼠標右擊,選擇 “找出是什么修改了這個地址”,發現代碼地址是 令人親切的 Crashlands2.exe+E73EF!

<3> 使用 “Break Point Check Test”,檢索其多級返回地址。而且一級返回地址前的這個 CALL 我們可太熟悉了!

<4> 直接匯編,代碼邏輯為 0,1,49999 →完成任務需求!
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+1418EB5) 4 alloc(tmp_total,8) 5 alloc(tmp_setag,8) 6 label(returnhere) 7 label(originalcode) 8 label(exit) 9 10 newmem: //this is allocated memory, you have read,write,execute access 11 //place your code here 12 13 originalcode: 14 mov [tmp_total],rbx 15 call Crashlands2.exe+E7360 16 push rcx 17 18 // --- The number Now is Zero Or One ( value <= 1 ) 19 mov [tmp_setag],rax 20 movsd xmm0,[tmp_setag] 21 cvttsd2si ecx,xmm0 22 cmp ecx,01 23 jna exit 24 25 // --- turn total_value to 49999 26 mov ecx,#49999 27 cvtsi2sd xmm0,ecx 28 mov rcx,[tmp_total] 29 movsd [rcx],xmm0 30 jmp exit 31 32 exit: 33 pop rcx 34 jmp returnhere 35 36 "Crashlands2.exe"+1418EB5: 37 jmp newmem 38 39 returnhere: 40 41 42 [DISABLE] 43 //code from here till the end of the code will be used to disable the cheat 44 dealloc(newmem) 45 dealloc(tmp_total) 46 dealloc(tmp_setag) 47 "Crashlands2.exe"+1418EB5: 48 db E8 A6 E4 CC FE 49 //call Crashlands2.exe+E7360
<5> 由此,僅兼容 “無限物品” 的 “任務需求速達” 功能就完成了,再使用外表頭和特定顏色改造一下!!!

<6> 之后是關于 此部分功能的優化,先禁用這個功能,然后返回 Act 1 所匯編的位置,設置好斷點。

<7> 準備好我們的任務——巨型機器人(最好是南瓜掌的那個任務)!

<8> 禁用其他功能后,收集上圖大塊頭來激活斷點以觀察堆棧情況。

<9> 找到一級返回地址 Crashlands2.exe+1D2FDFB ,對它前面的 CALL 匯編加 Tag,之前的 “Act 1” 要變成 “Act 2”。
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+1D2FDF6) 4 alloc(tag_obtain_mission,8) 5 registersymbol(tag_obtain_mission) 6 label(returnhere) 7 label(originalcode) 8 label(exit) 9 10 newmem: //this is allocated memory, you have read,write,execute access 11 //place your code here 12 13 originalcode: 14 // --- 記錄調用 CALL 的 Tag 15 mov [tag_obtain_mission],00000001 16 call Crashlands2.exe+1418700 17 mov [tag_obtain_mission],00000000 18 19 exit: 20 jmp returnhere 21 22 "Crashlands2.exe"+1D2FDF6: 23 jmp newmem 24 25 returnhere: 26 27 28 [DISABLE] 29 //code from here till the end of the code will be used to disable the cheat 30 dealloc(newmem) 31 dealloc(tag_obtain_mission) 32 unregistersymbol(tag_obtain_mission) 33 "Crashlands2.exe"+1D2FDF6: 34 db E8 05 89 6E FF 35 //call Crashlands2.exe+1418700
<10> 將 “ Act 2” (原本的 “Act 1” )改造一下,使得它在采集函數過程中,只聽從 采集物品值,即不按照我們直接49999的規則修改!
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+1418EB5) 4 alloc(tmp_total,8) 5 alloc(tmp_setag,8) 6 label(returnhere) 7 label(originalcode) 8 label(exit) 9 10 newmem: //this is allocated memory, you have read,write,execute access 11 //place your code here 12 13 originalcode: 14 mov [tmp_total],rbx 15 call Crashlands2.exe+E7360 16 push rcx 17 18 cmp [tag_obtain_mission],00000001 19 je exit 20 21 // --- turn total_value to 49999 22 mov ecx,#49999 23 cvtsi2sd xmm0,ecx 24 mov rcx,[tmp_total] 25 movsd [rcx],xmm0 26 jmp exit 27 28 exit: 29 pop rcx 30 jmp returnhere 31 32 "Crashlands2.exe"+1418EB5: 33 jmp newmem 34 35 returnhere: 36 37 38 [DISABLE] 39 //code from here till the end of the code will be used to disable the cheat 40 dealloc(newmem) 41 dealloc(tmp_total) 42 dealloc(tmp_setag) 43 "Crashlands2.exe"+1418EB5: 44 db E8 A6 E4 CC FE 45 //call Crashlands2.exe+E7360
<11> 重新使用外表頭和特定顏色改造一下!!!

FUN J:--------------------------------------【一擊必殺】
<1> 一擊必殺的制作方向比較明顯的有兩條:① 找到玩家血量的地址,修改扣血的代碼——玩家以外的血量值扣血直接扣成 0 ;② 找到玩家攻擊力的代碼,之后想辦法把攻擊力調整到 MAX(高于敵人最大血量值)。
<2> 很遺憾,我沒有找到攻擊力的數據,甚至我現在都沒有搞清楚這個游戲的傷害機制,所以我們自然而然地選擇第一種方法。還是先找到之前的 HP Value 和 HP Upper 兩個值!
<3> 我們在無限血量中已經找到了 HP 的高頻訪問函數 在 Crashlands2.exe + 131A4AF 處的標記,我們在它的前面和后面分別注入代碼用于 一擊必殺功能中的 HP 的高頻訪問函數標記!

<4> 注入代碼,以達成 Fun B 中 Act 1的效果。

1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+131A4A6) 4 alloc(tag_Hp_perm2,8) 5 alloc(HP_Address,8) 6 registersymbol(HP_Address) 7 registersymbol(tag_Hp_perm2) 8 label(returnhere) 9 label(originalcode) 10 label(exit) 11 12 newmem: //this is allocated memory, you have read,write,execute access 13 //place your code here 14 15 originalcode: 16 mov edx,[Crashlands2.exe+310CEA8] 17 // --- 記錄調用 CALL 的 Tag 18 mov [tag_Hp_perm2],00000001 19 20 exit: 21 jmp returnhere 22 23 "Crashlands2.exe"+131A4A6: 24 jmp newmem 25 nop 26 27 returnhere: 28 29 30 [DISABLE] 31 //code from here till the end of the code will be used to disable the cheat 32 dealloc(newmem) 33 dealloc(tag_Hp_perm2) 34 dealloc(HP_Address) 35 unregistersymbol(HP_Address) 36 unregistersymbol(tag_Hp_perm2) 37 "Crashlands2.exe"+131A4A6: 38 db 8B 15 FC 29 DF 01 39 //mov edx,[Crashlands2.exe+310CEA8]
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+131A4B4) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 movaps xmm0,[rbp+000002E0] 13 // --- 取消記錄調用 CALL 的 Tag 14 mov [tag_Hp_perm2],00000000 15 16 exit: 17 jmp returnhere 18 19 "Crashlands2.exe"+131A4B4: 20 jmp newmem 21 nop 2 22 23 returnhere: 24 25 26 [DISABLE] 27 //code from here till the end of the code will be used to disable the cheat 28 dealloc(newmem) 29 "Crashlands2.exe"+131A4B4: 30 db 0F 28 85 E0 02 00 00 31 //movaps xmm0,[rbp+000002E0]
<5> 然后需要在原來綁定 HP Value 值為 99,999,999 的代碼處,讀取 HP Value 的地址。故對 HP Value 設置 “Break Point Check Test”,停止后一步步 “步過” 直到程序返回到了一級地址!如圖,此時 rdi 的值是 HP Value的地址,故在此匯編,將此地址數據保存下來 (向上、向下找都可以)。

1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+1EE17DF) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 mov r15,[rsp+30] 13 14 // --- 發現被標記的高頻函數時,將 HP 地址記錄上 15 cmp [tag_Hp_perm2],00000001 16 jne exit 17 mov [HP_Address],rdi 18 jmp exit 19 20 exit: 21 jmp returnhere 22 23 "Crashlands2.exe"+1EE17DF: 24 jmp newmem 25 26 returnhere: 27 28 29 [DISABLE] 30 //code from here till the end of the code will be used to disable the cheat 31 dealloc(newmem) 32 "Crashlands2.exe"+1EE17DF: 33 db 4C 8B 7C 24 30 34 //mov r15,[rsp+30]
<6> 之后,對 HP Value 的值鼠標右擊,選擇 “找出是什么修改了這個地址”,之后回到游戲中讓怪物摸你一下!

<7> 就在這個地址注入匯編代碼,邏輯是 把玩家以外的血量 設置為 0;
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+B60FDD) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 // --- 當 未記錄 上 HP_Address 時,直接跳過不修改!!! 13 push rax 14 push rdx 15 cmp [HP_Address],00000000 16 je exit 17 18 // -- 監測傷害是否提供給玩家 19 mov rax,r15 20 mov rdx,[HP_Address] 21 cmp rax,rdx 22 je exit 23 // --- 生命值歸 0 24 xor rax,rax 25 cvtsi2sd xmm6,eax 26 jmp exit 27 28 exit: 29 pop rax 30 pop rdx 31 movsd [r15],xmm6 32 jmp returnhere 33 34 "Crashlands2.exe"+B60FDD: 35 jmp newmem 36 37 returnhere: 38 39 40 [DISABLE] 41 //code from here till the end of the code will be used to disable the cheat 42 dealloc(newmem) 43 "Crashlands2.exe"+B60FDD: 44 db F2 41 0F 11 37 45 //movsd [r15],xmm6
<8> 整理代碼,并使用外表頭和特定顏色改造一下!!!


浙公網安備 33010602011771號