[tc]魔獸3 內(nèi)存修改器 v7 程序員手冊
[tc]天馳 2008.11.5
一、從選中單位的列表獲得單位ESI
0、也可以利用".?AUCUnitListNode@@",以下沒有用這個(gè)方法
1、[6FAA2FFC],參考sub_6F416AE0
2、[上面+58+4*a2],參考6f3a0564
其中a2=word ptr[上面+28],參考6F042B76
3、[上面+34]記為鏈表基地址,參考6f2cc0a8
這個(gè)地址還有一種獲得方法,用.\CPlayerWar3.cpp所在的段+90,我不知道是否準(zhǔn)確
4、這個(gè)基地址的結(jié)構(gòu):
[基地址+1F0]:表頭
[基地址+1F4]:表尾
[基地址+1F8]:表長度
參考sub_6F415B70: 6f415b95 mov eax, [ebx+1f4]
5、展開當(dāng)前地址(假設(shè)一開始等于表頭)。
即[表頭],其結(jié)構(gòu)為:
[節(jié)點(diǎn)+0]:下一個(gè)節(jié)點(diǎn)
[節(jié)點(diǎn)+4]:not 下一個(gè)節(jié)點(diǎn)(二者為not關(guān)系,不知道為什么要這樣)
[節(jié)點(diǎn)+8]:單位ESI
參考:6F412504 mov eax, [edi+0c](eax為節(jié)點(diǎn)位置)
參考:6f412518 mov edi, [esi+08](edi為選中的單位,夢寐以求的單位ESI)
二、重要說明
1、ESI的使用
● ESI記為ThisUnit
● [ThisUnit + 1E4]記為UnitAttributes
● [ThisUnit + 1EC]記為HeroAttributes
例:[08220320 + 1E4] = 07B60424
[08220320 + 1EC] = 05AA0094
2、重要的內(nèi)存提取算法
算法0(6F03F180):從GameMemory取得數(shù)據(jù),需要索引號(hào)Index1和一個(gè)參考數(shù)ReferenceNumber1。注意Index1最高位不得為1,不然不是這個(gè)算法。建議判一下正負(fù)。
(1)[6FAA4178]記為ThisGame
例:[6FAA4178] = 02AE00B8
(2)[ThisGame + 0xC]計(jì)為ThisGameMemory
例:[02AE00B8 + C] = 0F060088
(3)[ThisGameMemory + Index1 * 8 + 4]計(jì)為Address1,返回之
(4)[Address1 + 0x18]應(yīng)當(dāng)?shù)扔赗eferenceNumber1,不相等游戲會(huì)異常(訪問地址0),所以做修改器不用考慮這里
算法1(6F4634E0):也需要Index1
(1)用算法0
(2)Address1 + 0x78輸出為地址
算法2(6F468A20):也需要Index1
(1)[ThisGameMemory + Index1 * 8 + 4],記為Address3
(2)[Address3 + 20]為零的前提下返回[Address + 54]的內(nèi)容
三、單位的修改
1、HP float
[HPMax地址-C]
2、HPMax float
(1)ThisUnit + 98 // 參考sub_6F28A760
例:08220320 + 98
(2)[上面 + 8] // 參考sub_6F467710
例:[82203C0] = 06BC
(3)用算法0解開上面
例:093E0AFC
(4)解開后內(nèi)容在[上面 + 84] // 參考6F46752F: fcompp, EDX
3、MP float
[MPMax地址-C]
4、MPMax float
(1)ThisUnit + 98 // 參考sub_6F28A760
例:08220320 + 98
(2)[上面 + 28] // 參考sub_6F467750
例:[^+28] = 06BD
(3)用算法0解開上面
(4)解開后內(nèi)容在[上面 + 84] // 參考sub_6F467750
5、經(jīng)驗(yàn)值:[HeroAttributes + 8C] int
源代碼:6F26DFF0
即:getHeroExp()
6、力量初值:[HeroAttributes + 94] int
源代碼:3F353D06
即:int __thiscall DrawHeroProperty(int *GameContext, int **HeroAttributes, int *AttributeBias, unsigned int *GBuffer)
7、敏捷初值:[HeroAttributes + A8] int
源代碼:同上
8、智力初值:int
源代碼:6F0DA9D0
即:int __fastcall getHeroIntellect_NotSure(int pAttribute1)
[HeroAttributes + 7C + 2 * 4] 記為Index1
[HeroAttributes + 7C + 3 * 4] 記為ReferenceNumber1
用算法1得到地址
9、攻擊頻率:[UnitAttributes + 1B0] float
源代碼:6F0C64E0
即:int __thiscall getHeroROF_NotSure(int *this, int a2, int a3, int a4)
10-13、攻擊相關(guān):int
參考(攻擊頻率/UnitAttributes) 0 1B0
攻擊 - 基礎(chǔ) -110 A0
攻擊 - 倍乘 -11C 94
攻擊 - 骰子 -128 88
攻擊 - 種類 -BC F4
14、移動(dòng)速度:[參數(shù) + 70h] float 單位的移動(dòng),或者[參數(shù) + 78h] float 當(dāng)前的移動(dòng)速度
源代碼:6F201190
即:void __thiscall sub_6F201190(int this, int a2, int a3)
參數(shù)的獲得:sub_6F077550:從6F077693開始
參考1:6f2011a1: mov eax, [ecx+70] ecx=07c50094
< sub_6F201190(a1+0x70)
< 6F077758(arg0 = 0012F874)
參考2:斷點(diǎn)下在6F0776F6
> [ThisUnit + 1D8]記為MoveAbilityIndex
例:06CE
算法2(^)=07e23cd4記為I
例:[I]=6F8BDBCC
(
Index依次等于:(This+1D8=)6CE 6CD 6C6、 6C5 6C4
對(duì)應(yīng)算法2結(jié)果: 07E23CD4、05AA0094、05A90094、07B50424、07B50448、07C50094
Next :
)
while [I + 24] & [I + 28] != -1
{
if [[I] + 2D4] == 6F201190(如果是6F052080,這個(gè)是空的)
{
[I + 70]為移動(dòng)速度,或者用[I + 78]
exit
}
I = 算法2([I + 24]) = 05AA0094、05A90094、...、07C50094
}
> 如果[+2D4] != 6F201190則
{
> [^ + 24]作為Index
06CD
> 解index
[ED236F4]=084BEEC4
[^+54]= 05aa0094
}
15、防御:[ThisUnit + E0] float
源代碼:6F353250
6F3532A2: mov eax, dword ptr [ebx+e0]
即:void __thiscall sub_6F353250(int this, int a2, int a3, int a4)
16、防御類型:[ThisUnit + E4] int
17、坐標(biāo)X:
[ThisUnit + 164],參考:6F2776C4
[上面+8]作為index,[上面+C]作為Refrence,用算法0,參考:6F464685
[上面+78],參考:6F38A52C
[上面]為坐標(biāo)X,參考:6f6de775
18、[坐標(biāo)Y] = [坐標(biāo)X的地址 + 4]
四、金錢的修改
參考:6F407220,看最后一段
即:signed int __thiscall sub_6F407220(int this, signed int a2, unsigned int a3, int a4, int a5, int a6)
1、上16位
(1)[ThisGameMemory + 1 * 8 + 4]計(jì)為Address2
(2)Address2上16位,下16位見下一款
2、下16位
1P 0190
2P 1410
3P 26a0
4P 3920
5P 4bb0
6P 5e30
7P 70c0
8P 8350
9P 95d0
10P a860
3、對(duì)每個(gè)玩家
金錢 0 int x10
木頭 + 80 int x10
最大人口 +180 int
當(dāng)前人口 +200 int