Steam游戲《Northgard(北境之地)》修改器制作
日期:2021.06.07
博客期:181
星期一
【溫馨提示】:
我現(xiàn)在把資源先放到開頭,不想研究學(xué)習(xí)的就直接取用。如果修改器失效了,你們可以在博客園本頁(yè)直接評(píng)論,也可以給我發(fā)郵件告訴我,就是不要到百度云上去說(shuō)了,百度云我好久不登錄一次的!大家給我發(fā)郵件的話,記得要注明是哪個(gè)游戲,內(nèi)容當(dāng)然是越詳細(xì)越好啦!郵箱地址:nightskysxs@163.com
| 資源下載表 | |||
| 沒有博客園賬號(hào)的網(wǎng)友 |
百度網(wǎng)盤下載鏈接:https://pan.baidu.com/s/1PNJpTtmFu6c-n-DENgRArg 提取碼:nort |
||
| 有博客園賬號(hào)的網(wǎng)友 | 版本 | CT文件 | 修改器 |
| v3.3.5.35761 | 點(diǎn)我下載 | 點(diǎn)我下載 | |
博客防爬取部分:http://www.rzrgm.cn/onepersonwholive/p/14858916.html
前言
現(xiàn)在是準(zhǔn)備畢業(yè),碰巧遇到了游戲我打不過,簡(jiǎn)單花時(shí)間開發(fā)一下。預(yù)計(jì)本次博客會(huì)不斷完善,直到我本人滿意為止,好吧!預(yù)期開發(fā)到各種指標(biāo)的修改、個(gè)人組織成員無(wú)敵、建房速度啊、維修速度啊之類的。對(duì)于個(gè)人能力提升的方面,我沒什么成見。或許這里面的內(nèi)容并沒有更多引起我注意的地方。基本是游戲修改初等的應(yīng)用了。
版本

修改內(nèi)容
1、三項(xiàng)資源的修改(食物、木材、金錢)
這三項(xiàng)資源類似,我們以 “食物” 一項(xiàng)為例,搜索 雙浮點(diǎn)類型 (Double)的值,得到如下圖所示的結(jié)果。其中我們需要的是最上方的有小數(shù)部分的那一個(gè),因?yàn)閷?shí)際上數(shù)據(jù)就應(yīng)該是含小數(shù)部分的而不是給我們看的整數(shù)部分。

我們查找是什么改寫了這項(xiàng)代碼,得到的結(jié)果是 —— “ 76CA9FC60A85 movsd [r10+48],xmm2 ” !得到區(qū)域代碼:
| 代碼所在內(nèi)存地址 | 操作碼 | 偽代碼 | 操作解釋 |
| 76CA9FC60A7F | movsd xmm2,[rbp+18] | xmm2 = [rbp+18] | 將地址“rbp+18”所存儲(chǔ)的 Double 類型值賦值給寄存器 xmm2 |
| 76CA9FC60A85 | movsd [r10+48],xmm2 | [r10+48] = xmm2 | 將寄存器 xmm2所存儲(chǔ)的 Double 類型值賦值給地址“r10+48”位置上 |
這部分代碼告訴我們上面講 [rbp+18] 的值傳給了 [r10+48] ,所以我們需要將 rbp+18 的值獲取之前將它改掉。
完成如下匯編:
push ebx // ebx 入棧
mov ebx,C34F // ebx 獲得 49999 的 4字節(jié)值
cvtsi2sd xmm2,ebx // 將 ebx 的值 轉(zhuǎn)為 Double 類型 ,并賦值到 xmm2 寄存器中
pop ebx // ebx 出棧
movsd [rbp+18],xmm2 // 將 xmm2 的值 傳給 [rbp+18] , 完成修改
同理可以得到另外兩項(xiàng)修改,所有匯編:(目前未采用 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
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
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
最終效果:

2、快速獲得村民
這個(gè)想要實(shí)現(xiàn)的方式有很多,我目前發(fā)現(xiàn)的一種比較簡(jiǎn)單的是找到村民來(lái)到的百分?jǐn)?shù),如下圖:

如圖,我們需要搜索這個(gè) 雙浮點(diǎn)數(shù)值 (Double),數(shù)值和上面顯示的一樣,如果是 65% 就搜索 65 。有幾點(diǎn)需要注意的地方——第一,需要在剛進(jìn)入游戲?qū)值臅r(shí)候搜素,這個(gè)數(shù)值到后面就不是 65% 對(duì)應(yīng) 65 的了;第二,搜素的時(shí)候也不要搜素 “65.0” 這樣,因?yàn)閿?shù)值是有小數(shù)部分的,這樣搜是等于在搜純整數(shù)的 Double 值;第三,搜索的時(shí)候一定要看清楚搜索時(shí)的數(shù)值是不是游戲當(dāng)中的數(shù)值,實(shí)在不行配合 “變速齒輪”、“CE變速” 和 “搜索時(shí)游戲暫停” 等選項(xiàng)來(lái)搜索,別到時(shí)候游戲中的數(shù)值都變成 68 了,還在搜索 65 呢!還有這個(gè)值實(shí)在難以滿足這三個(gè)條件的話,就直接去搜索 Double 值吧!暫停游戲時(shí)搜未變,增長(zhǎng)搜增長(zhǎng)的數(shù)值,新村民來(lái)了以后搜減少的數(shù)值,這樣找。
搜索 “哪里修改了此處代碼”,得到的結(jié)果是 —— “ 76CA9FC731D4 movsd [rcx+60],xmm3 ” !得到區(qū)域代碼:
| 代碼所在內(nèi)存地址 | 操作碼 | 偽代碼 | 操作解釋 |
| 76CA9FC731CE | movsd xmm3,[rbp+18] | xmm3 = [rbp+18] | 將地址“rbp+18”所存儲(chǔ)的Double類型值賦值給寄存器 xmm3 |
| 76CA9FC731D4 | movsd [rcx+60],xmm3 | [rcx+60] = xmm3 | 將寄存器 xmm3 所存儲(chǔ)的Double類型值賦值給地址“rcx+60”位置上 |
這部分代碼告訴我們上面講 [rbp+18] 的值傳給了 [rcx+60] ,所以我們需要將傳來(lái)的 xmm3 的值以更快的速度增長(zhǎng)。
完成如下匯編:
push ebx // ebx 入棧
mov ebx,19 // ebx 獲得 25 的 4字節(jié)值
cvtsi2sd xmm0,ebx // 將 ebx 的值 轉(zhuǎn)為 Double 類型 ,并賦值到 xmm0 寄存器中 (因?yàn)楹竺?76CA9FC731DA 地址對(duì)應(yīng)代碼段 xmm3 值賦給了 xmm0 ,所以判定 xmm0的值是無(wú)用的)
pop ebx // ebx 出棧
addsd xmm3,xmm0 // xmm3 = xmm3 + xmm0
大致意思就是上述原賦值代碼端每次運(yùn)行會(huì)自動(dòng)多增加 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
最終效果:

3、個(gè)人單位 NPC 無(wú)敵 (基本確保戰(zhàn)士無(wú)敵,其余未測(cè)試)
每次看到己方小兵被敵方大兵騷擾,都?xì)鈶嵅灰褏s又無(wú)能為力,現(xiàn)在吾將賜予汝等神力!己方血量不減,來(lái),讓我用村民完勝你的強(qiáng)化巨人戰(zhàn)士!
我們要搜索的值是 “收到傷害值” ,也就是說(shuō)每次受到攻擊我們要搜的值是增加的。一般最好在你有兩名治療師的情況下,去找一匹狼戰(zhàn)斗!
這樣可以找到兩個(gè)值,查找是什么代碼段改寫了這個(gè)值,得到的結(jié)果是 —— “ 76CA9F81F265 movsd [rdx+00000188],xmm3 ” !得到區(qū)域代碼:
| 代碼所在內(nèi)存地址 | 操作碼 | 偽代碼 | 操作解釋 |
| 76CA9F81F25F | movsd xmm3,[rbp+18] | xmm3 = [rbp+18] | 將地址“rbp+18”所存儲(chǔ)的 Double 類型值賦值給寄存器 xmm3 |
| 76CA9F81F265 | movsd [rdx+00000188],xmm3 | [rdx+188] = xmm3 | 將寄存器 xmm3 所存儲(chǔ)的 Double 類型值賦值給地址“rdx+188”位置上 |
這部分代碼告訴我們上面講 [rbp+18] 的值傳給了 [rdx+188] ,所以我們需要將傳來(lái)的 xmm3 的值改為 0,以保證血量收到傷害為 0 。
所以,我就直接寫入了將如下匯編代碼嵌入到源代碼中,它們的實(shí)際意義是 xmm3 = (Double) 0
push ebx // ebx 入棧
mov ebx,0 // ebx 獲得 25 的 4字節(jié)值
cvtsi2sd xmm3,ebx // 將 ebx 的值 轉(zhuǎn)為 Double 類型 ,并賦值到 xmm3 寄存器中
pop ebx // ebx 出棧
結(jié)果您猜怎么著?系統(tǒng)直接彈出并自動(dòng)關(guān)閉游戲進(jìn)程,按我的歷史經(jīng)驗(yàn)來(lái)看這是報(bào)錯(cuò)了。我立馬在 76CA9F81F265 處設(shè)置斷點(diǎn),發(fā)現(xiàn)除了給戰(zhàn)斗中的雙方賦值以外,還會(huì)帶有其他未知的賦值,這可能是最接近 剛才報(bào)錯(cuò)原因 的原因了。之后,我按照做崩潰大陸的經(jīng)驗(yàn)查看此處斷點(diǎn)的堆棧情況:
英雄被狼攻擊時(shí):

狼被英雄攻擊時(shí):

我左看看,右看看。這返回的地址都是變化的,而且沒有一個(gè)可以用的。我們需要的是靜態(tài)的能夠標(biāo)記出兩邊哪一方是敵人的。最后我發(fā)現(xiàn)返回值前面有一句 76CA9F92CB16 處的 call 76CA9F81F210 ,我一瞬間想到這可能就是我一直想要找的突破口了。我在前面加入標(biāo)識(shí)符 tag_isHero 標(biāo)記 代碼是否是從這個(gè)地方調(diào)用一系列函數(shù)執(zhí)行到這里的。
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
之后在修改值的地方嵌入的代碼又加上了如下判定:
cmp [tag_isHero],00000001 // 比較 tag_isHero 的值代表地址的值是不是 1
jne exit // 不是的話跳轉(zhuǎn) exit 所指代的地址
之后我發(fā)現(xiàn)程序不會(huì)報(bào)錯(cuò)了,但是雙方都變得 “無(wú)敵” 了,誰(shuí)也打不死誰(shuí)。看來(lái)是需要找一找它們的結(jié)構(gòu)區(qū)別了。(這一點(diǎn)類似于我在做《九張羊皮紙》的時(shí)候,處理共用代碼端的方法)
結(jié)構(gòu)體對(duì)比圖:

經(jīng)過長(zhǎng)時(shí)間的對(duì)比,我們?nèi)?+44 處作為判定標(biāo)準(zhǔn)。敵人的 +40 處連帶 +44處都是地址,而己方則是 0 值。
之后在修改值的地方嵌入的代碼又加上了如下判定:
cmp [rdx+44],00000000 // 比較 rdx+44 的值代表地址的值是不是 0
jne exit // 不是的話跳轉(zhuǎn) exit 所指代的地址
最后測(cè)試果然成功了,匯編代碼如下:
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
測(cè)試結(jié)果:

修改器截圖:


浙公網(wǎng)安備 33010602011771號(hào)