Steam游戏《Northgard(北境之地)》修改器制作
日期:2021.06.07
博客期:181
星期一
【溫馨提示】:
我現在把資源先放到開頭,不想研究學習的就直接取用。如果修改器失效了,你們可以在博客園本頁直接評論,也可以給我發郵件告訴我,就是不要到百度云上去說了,百度云我好久不登錄一次的!大家給我發郵件的話,記得要注明是哪個游戲,內容當然是越詳細越好啦!郵箱地址:nightskysxs@163.com
| 資源下載表 | |||
| 沒有博客園賬號的網友 |
百度網盤下載鏈接:https://pan.baidu.com/s/1ohVFp0vvE3nt-tEv9Xy5bQ 提取碼:nort |
||
| 有博客園賬號的網友 | 版本 | CT文件 | 修改器 |
| v2.5.3.21746 | 點我下載 | 點我下載 | |
博客防爬取部分:https://www.cnblogs.com/onepersonwholive/p/14858916.html
前言
現在是準備畢業,碰巧遇到了游戲我打不過,簡單花時間開發一下。預計本次博客會不斷完善,直到我本人滿意為止,好吧!預期開發到各種指標的修改、個人組織成員無敵、建房速度啊、維修速度啊之類的。對于個人能力提升的方面,我沒什么成見。或許這里面的內容并沒有更多引起我注意的地方。基本是游戲修改初等的應用了。
版本
修改內容
1、三項資源的修改(食物、木材、金錢)
這三項資源類似,我們以 “食物” 一項為例,搜索 雙浮點類型 (Double)的值,得到如下圖所示的結果。其中我們需要的是最上方的有小數部分的那一個,因為實際上數據就應該是含小數部分的而不是給我們看的整數部分。
我們查找是什么改寫了這項代碼,得到的結果是 —— “76CA9FC60A85 movsd [r10+48],xmm2 ” !得到區域代碼:
| 代碼所在內存地址 | 操作碼 | 偽代碼 | 操作解釋 |
| 76CA9FC60A7F | movsd xmm2,[rbp+18] | xmm2 = [rbp+18] | 將地址“rbp+18”所存儲的 Double 類型值賦值給寄存器 xmm2 |
| 76CA9FC60A85 | movsd [r10+48],xmm2 | [r10+48] = xmm2 | 將寄存器 xmm2所存儲的 Double 類型值賦值給地址“r10+48”位置上 |
這部分代碼告訴我們上面講 [rbp+18] 的值傳給了 [r10+48] ,所以我們需要將 rbp+18 的值獲取之前將它改掉。
完成如下匯編:
push ebx // ebx 入棧
mov ebx,C34F // ebx 獲得 49999 的 4字節值
cvtsi2sd xmm2,ebx // 將 ebx 的值 轉為 Double 類型 ,并賦值到 xmm2 寄存器中
pop ebx // ebx 出棧
movsd [rbp+18],xmm2 // 將 xmm2 的值 傳給 [rbp+18] , 完成修改
同理可以得到另外兩項修改,所有匯編:(目前未采用 AOB 注入方式)
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,2048,76CA9FC60A7F) 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 push ebx 13 mov ebx,C34F //49999 14 cvtsi2sd xmm2,ebx 15 pop ebx 16 movsd [rbp+18],xmm2 17 18 19 exit: 20 jmp returnhere 21 22 76CA9FC60A7F: 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 76CA9FC60A7F: 34 movsd xmm2,[rbp+18] 35 //Alt: db F2 48 0F 10 55 18
unlimited food
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,2048,76CA9FC60F02) 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 push ebx 13 mov ebx,C34F //49999 14 cvtsi2sd xmm2,ebx 15 pop ebx 16 movsd [rbp+18],xmm2 17 18 exit: 19 jmp returnhere 20 21 76CA9FC60F02: 22 jmp newmem 23 nop 24 returnhere: 25 26 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 76CA9FC60F02: 33 movsd xmm2,[rbp+18] 34 //Alt: db F2 48 0F 10 55 18
unlimited wood
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,2048,76CA9FC60CC2) 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 push ebx 13 mov ebx,C34F //49999 14 cvtsi2sd xmm2,ebx 15 pop ebx 16 movsd [rbp+18],xmm2 17 18 exit: 19 jmp returnhere 20 21 76CA9FC60CC2: 22 jmp newmem 23 nop 24 returnhere: 25 26 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 76CA9FC60CC2: 33 movsd xmm2,[rbp+18] 34 //Alt: db F2 48 0F 10 55 18
unlimited money
最終效果:
2、快速獲得村民
這個想要實現的方式有很多,我目前發現的一種比較簡單的是找到村民來到的百分數,如下圖:
如圖,我們需要搜索這個 雙浮點數值 (Double),數值和上面顯示的一樣,如果是 65% 就搜索 65 。有幾點需要注意的地方——第一,需要在剛進入游戲對局的時候搜素,這個數值到后面就不是 65% 對應 65 的了;第二,搜素的時候也不要搜素 “65.0” 這樣,因為數值是有小數部分的,這樣搜是等于在搜純整數的 Double 值;第三,搜索的時候一定要看清楚搜索時的數值是不是游戲當中的數值,實在不行配合 “變速齒輪”、“CE變速” 和 “搜索時游戲暫停” 等選項來搜索,別到時候游戲中的數值都變成 68 了,還在搜索 65 呢!還有這個值實在難以滿足這三個條件的話,就直接去搜索 Double 值吧!暫停游戲時搜未變,增長搜增長的數值,新村民來了以后搜減少的數值,這樣找。
搜索 “哪里修改了此處代碼”,得到的結果是 —— “ 76CA9FC731D4 movsd [rcx+60],xmm3 ” !得到區域代碼:
| 代碼所在內存地址 | 操作碼 | 偽代碼 | 操作解釋 |
| 76CA9FC731CE | movsd xmm3,[rbp+18] | xmm3 = [rbp+18] | 將地址“rbp+18”所存儲的Double類型值賦值給寄存器 xmm3 |
| 76CA9FC731D4 | movsd [rcx+60],xmm3 | [rcx+60] = xmm3 | 將寄存器 xmm3 所存儲的Double類型值賦值給地址“rcx+60”位置上 |
這部分代碼告訴我們上面講 [rbp+18] 的值傳給了 [rcx+60] ,所以我們需要將傳來的 xmm3 的值以更快的速度增長。
完成如下匯編:
push ebx // ebx 入棧
mov ebx,19 //ebx 獲得 25 的 4字節值
cvtsi2sd xmm0,ebx //將 ebx 的值 轉為 Double 類型 ,并賦值到 xmm0 寄存器中 (因為后面 76CA9FC731DA 地址對應代碼段xmm3 值賦給了 xmm0 ,所以判定 xmm0的值是無用的)
pop ebx // ebx 出棧
addsd xmm3,xmm0 // xmm3 = xmm3 + xmm0
大致意思就是上述原賦值代碼端每次運行會自動多增加 25 的值。匯編代碼如下:(目前未采用 AOB 注入的方式)
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,2048,76CA9FC731D4) 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 push ebx 13 mov ebx,19 //25 14 cvtsi2sd xmm0,ebx 15 pop ebx 16 addsd xmm3,xmm0 17 18 exit: 19 movsd [rcx+60],xmm3 20 jmp returnhere 21 22 76CA9FC731D4: 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 76CA9FC731D4: 34 movsd [rcx+60],xmm3 35 //Alt: db F2 48 0F 11 59 60
quick abtain peple +25
最終效果:
3、個人單位 NPC 無敵 (基本確保戰士無敵,其余未測試)
每次看到己方小兵被敵方大兵騷擾,都氣憤不已卻又無能為力,現在吾將賜予汝等神力!己方血量不減,來,讓我用村民完勝你的強化巨人戰士!
我們要搜索的值是 “收到傷害值” ,也就是說每次受到攻擊我們要搜的值是增加的。一般最好在你有兩名治療師的情況下,去找一匹狼戰斗!
這樣可以找到兩個值,查找是什么代碼段改寫了這個值,得到的結果是 —— “ 76CA9F81F265 movsd [rdx+00000188],xmm3” !得到區域代碼:
| 代碼所在內存地址 | 操作碼 | 偽代碼 | 操作解釋 |
| 76CA9F81F25F | movsd xmm3,[rbp+18] | xmm3 = [rbp+18] | 將地址“rbp+18”所存儲的 Double 類型值賦值給寄存器 xmm3 |
| 76CA9F81F265 | movsd [rdx+00000188],xmm3 | [rdx+188] = xmm3 | 將寄存器 xmm3 所存儲的 Double 類型值賦值給地址“rdx+188”位置上 |
這部分代碼告訴我們上面講 [rbp+18] 的值傳給了 [rdx+188] ,所以我們需要將傳來的 xmm3 的值改為 0,以保證血量收到傷害為 0 。
所以,我就直接寫入了將如下匯編代碼嵌入到源代碼中,它們的實際意義是 xmm3 = (Double) 0
push ebx // ebx 入棧
mov ebx,0 //ebx 獲得 25 的 4字節值
cvtsi2sd xmm3,ebx // 將 ebx 的值 轉為 Double 類型 ,并賦值到 xmm3 寄存器中
pop ebx // ebx 出棧
結果您猜怎么著?系統直接彈出并自動關閉游戲進程,按我的歷史經驗來看這是報錯了。我立馬在 76CA9F81F265 處設置斷點,發現除了給戰斗中的雙方賦值以外,還會帶有其他未知的賦值,這可能是最接近 剛才報錯原因 的原因了。之后,我按照做崩潰大陸的經驗查看此處斷點的堆棧情況:
英雄被狼攻擊時:
狼被英雄攻擊時:
我左看看,右看看。這返回的地址都是變化的,而且沒有一個可以用的。我們需要的是靜態的能夠標記出兩邊哪一方是敵人的。最后我發現返回值前面有一句 76CA9F92CB16 處的call 76CA9F81F210 ,我一瞬間想到這可能就是我一直想要找的突破口了。我在前面加入標識符 tag_isHero 標記 代碼是否是從這個地方調用一系列函數執行到這里的。
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,2048,76CA9F92CB16) 4 alloc(tag_isHero,8) 5 registersymbol(tag_isHero) 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_isHero],00000001 15 call 76CA9F81F210 16 mov [tag_isHero],00000000 17 18 exit: 19 jmp returnhere 20 21 76CA9F92CB16: 22 jmp newmem 23 returnhere: 24 25 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_isHero) 32 unregistersymbol(tag_isHero) 33 76CA9F92CB16: 34 call 76CA9F81F210 35 //Alt: db E8 F5 26 EF FF
reset data
之后在修改值的地方嵌入的代碼又加上了如下判定:
cmp [tag_isHero],00000001 // 比較 tag_isHero 的值代表地址的值是不是 1
jne exit // 不是的話跳轉 exit 所指代的地址
之后我發現程序不會報錯了,但是雙方都變得 “無敵” 了,誰也打不死誰。看來是需要找一找它們的結構區別了。(這一點類似于我在做《九張羊皮紙》的時候,處理共用代碼端的方法)
結構體對比圖:
經過長時間的對比,我們取 +44 處作為判定標準。敵人的 +40 處連帶 +44處都是地址,而己方則是 0 值。
之后在修改值的地方嵌入的代碼又加上了如下判定:
cmp [rdx+44],00000000 // 比較rdx+44 的值代表地址的值是不是 0
jne exit // 不是的話跳轉 exit 所指代的地址
最后測試果然成功了,匯編代碼如下:
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,2048,76CA9F81F25F) 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_isHero],00000001 13 jne exit 14 cmp [rdx+44],00000000 15 jne exit 16 push ebx 17 mov ebx,0 //0 18 cvtsi2sd xmm3,ebx 19 pop ebx 20 mov [tag_isHero],00000000 21 movsd [rbp+18],xmm3 22 jmp returnhere 23 24 // equals -> isHero -> damage = 0 25 exit: 26 movsd xmm3,[rbp+18] 27 jmp returnhere 28 29 76CA9F81F25F: 30 jmp newmem 31 nop 32 returnhere: 33 34 35 36 37 [DISABLE] 38 //code from here till the end of the code will be used to disable the cheat 39 dealloc(newmem) 40 76CA9F81F25F: 41 movsd xmm3,[rbp+18] 42 //Alt: db F2 48 0F 10 5D 18
isHero == 1 ? next : continue;[+44] == 0? damage = 0 : continue;
測試結果:
修改器截圖:
總結
以上是生活随笔為你收集整理的Steam游戏《Northgard(北境之地)》修改器制作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第三次学JAVA再学不好就吃翔(part
- 下一篇: 特征工程(part1)--什么是特征工程