找回密码
 立即注册
查看: 1730|回复: 0

突破镶6孔的限制

[复制链接]
发表于 2013-6-8 08:17:58 | 显示全部楼层 |阅读模式
  经过研究,解决了游戏对物品打孔的最大限制6。对应Itemstatcost.TXT的4bit=15的限制,将上限改为15。下面将我解决问题的步骤说明如下:
首先修改相应物品TXT文件的孔数限制,加合成打15孔的公式。
在游戏中测试打孔,只能打6个,必有打孔限制。故第二步应该解决打孔限制的问题。
打孔的限制代码:
镜像地址
  00A2746C BB 06000000 mov ebx,6 ;上限
  │
  00A27499 0FAFC2 imul eax,edx ;计算格子(宽X高)限制
  00A2749C 3BC3 cmp eax,ebx ;比对哪个限制小
  00A2749E 7F 0E jg short D2Common.00A274AE
  00A274A0 . 8BD8 mov ebx,eax ;格子限制小,引用
  以上代码在D2Common.dll(1.10)中,是Properties的sock FUNC 函数(第14个函数)中的一段。
镜像地址
  00A31940 . 50 push eax
  00A31941 . 53 push ebx
  00A31942 . E8 9B2A0200 call <jmp.&Fog.#10130>
  00A31947 . 894424 28 mov dword ptr ss:[esp+28],eax ;存档限制(Itemstatcost.TXT中)
  │
  00A31959 C74424 1C 06000000 mov dword ptr ss:[esp+1C],06 ;上限
  │
  00A3199C 0FAFC1 imul eax,ecx ;计算格子(宽X高)限制
  00A3199F 83F8 06 cmp eax,6 ;比对哪个限制小
  00A319A2 7F 08 jg short D2Common.00A319AC
  00A319A4 │. 85C0 test eax,eax
  00A319A6 │. 894424 1C mov dword ptr ss:[esp+1C],eax;格子限制小,引用
  以上代码在D2Common.dll(1.10)中,为D2Common.#10882函数,根据存档结构(Itemstatcost.TXT中)限制物品属性(估计)时的一段。
由于sock FUNC 函数和显示物品属性时会加入两种限制的最小值(Itemstatcost.tXT中的限制4bit不用改),我们要对应的将上限改高和屏蔽格子限制。
  将上限改高的修改
  00A2746C BB 06000000 mov ebx,6
  00A31959 C74424 1C 06000000 mov dword ptr ss:[esp+1C],06
  00A3199F 83F8 06 cmp eax,6

  00A2746C BB 0F000000 mov ebx,0F
  00A31959 C74424 1C 0F000000 mov dword ptr ss:[esp+1C],0F
  00A3199F 83F8 0F cmp eax,0F
屏蔽格子限制的修改
  00A2749E 7F 0E jg short D2Common.00A274AE
  00A319A2 7F 08 jg short D2Common.00A319AC

  00A2749E EB 0E jmp short D2Common.00A274AE
  00A319A2 EB 08 jmp short D2Common.00A319AC
把某白色物品打15孔,退出游戏(储存),从新进入游戏,物品仍然是15孔。验证打孔限制解决。
  
  打孔限制的问题解决,然后就要进行镶嵌测试。当镶嵌第7个宝石时,游戏弹出。所以镶嵌代码也有限制问题。找到插孔代码:
  镜像地址
  00A2D9E0 > 83EC 28 sub esp,28
  00A2D9E3 │. 53 push ebx
  00A2D9E4 8B5C24 30 mov ebx,dword ptr ss:[esp+30]
  00A2D9E8 │. 55 push ebp
  00A2D9E9 │. 56 push esi
  00A2D9EA │. 85DB test ebx,ebx
  00A2D9EC │. 57 push edi
  00A2D9ED │. 0F84 8D000000 je D2Common.00A2DA80
  00A2D9F3 │. 8B03 mov eax,dword ptr ds:[ebx]
  │
  00A2DB8D │> 5F pop edi
  00A2DB8E │. 5E pop esi
  00A2DB8F │. 8BC3 mov eax,ebx
  00A2DB91 │. 5D pop ebp
  00A2DB92 │. 5B pop ebx
  00A2DB93 83C4 28 add esp,28
  00A2DB96 \. C2 0400 retn 4
  以上代码在D2Common.dll(1.10)中,是D2Common.#10822函数,功能是可以组神符之语的物品插孔查找宝石(符文),寄存后进行神符之语检测。分析知所留空间不足,导致堆栈溢出。需要增加堆栈。
  修改
  00A2D9E0 83EC 28 sub esp,28
  00A2D9E4 8B5C24 30 mov ebx,dword ptr ss:[esp+30]
  00A2DA86 83C4 28 add esp,28
  00A2DB11 8B4C24 3C mov ecx,dword ptr ss:[esp+3C]
  00A2DB3F 8B4424 3C mov eax,dword ptr ss:[esp+3C]
  00A2DB87 83C4 28 add esp,28
  00A2DB93 83C4 28 add esp,28
为(加9个X 4 = 36 BYTE = 24H)
  00A2D9E0 83EC 4C sub esp,4C
  00A2D9E4 8B5C24 54 mov ebx,dword ptr ss:[esp+54]
  00A2DA86 83C4 4C add esp,4C
  00A2DB11 8B4C24 60 mov ecx,dword ptr ss:[esp+60]
  00A2DB3F 8B4424 60 mov eax,dword ptr ss:[esp+60]
  00A2DB87 83C4 4C add esp,4C
  00A2DB93 83C4 4C add esp,4C
  修改后,在游戏中镶嵌6个以上的宝石,到镶满15颗,没出错。
接下来退出游戏(储存),从新进入游戏,显示存档损坏。分析存档物品储存结构,发现孔数用4bit储存,但是镶嵌了的宝石数却只用3bit储存。要储存后能用,只能修改物品储存结构。由于镶嵌了的宝石数前面的数据为物品代码,而物品代码一般(特殊情况:除非你非要用)只用ASCII的基本码即80h前的ASCII码,用7bit就能表示。所以将物品代码第4位第8bit用于扩展镶嵌宝石数的储存。需要修改读取存档和写入存档的部分代码。
以下为读取存档物品代码储存和镶嵌宝石数储存的解编部分代码:
  00A30455 │> \8D4C24 08 lea ecx,dword ptr ss:[esp+8]
  00A30459 6A 20 push 20 ;4 X 8 =32 =20h,物品代码,长20 bit
  00A3045B │. 51 push ecx
  00A3045C │. E8 813F0200 call <jmp.&Fog.#10130>
  00A30461 │. 50 push eax
  00A30462 │> E8 B972FBFF call D2Common.#10602
  00A30467 │. 8906 mov dword ptr ds:[esi],eax
  00A30469 │. 33C0 xor eax,eax
  00A3046B │. F7C7 00002002 test edi,2200000
  00A30471 │. 75 0C jnz short D2Common.00A3047F
  00A30473 │. 8D5424 08 lea edx,dword ptr ss:[esp+8]
  00A30477 6A 03 push 3 ;已镶嵌的个数,3 bit=2^3 =7
  00A30479 │. 52 push edx
  00A3047A │. E8 633F0200 call <jmp.&Fog.#10130>
  00A3047F │> 8946 14 mov dword ptr ds:[esi+14],eax
修改
  00A30459 6A 20 push 20
  00A30477 6A 03 push 3
  为
  00A30459 6A 1F push 1F
  00A30477 6A 04 push 4
以下为写入前存档物品代码和镶嵌宝石数的编制部分代码:
  00A3334C │> \8B90 80000000 mov edx,dword ptr ds:[eax+80]
  00A33352 │. 6A 20 push 20 ;4 X 8 =32 =20h,物品代码,长20 bit
  00A33354 │. 52 push edx
  00A33355 │. 53 push ebx
  00A33356 │. E8 A5100200 call <jmp.&Fog.#10128>
  00A3335B │. 33F6 xor esi,esi
  00A3335D │. 57 push edi
  00A3335E │. E8 FD9FFFFF call D2Common.#10810
  00A33363 │. 85C0 test eax,eax
  00A33365 │. 74 61 je short D2Common.00A333C8
  00A33367 │. 8B47 60 mov eax,dword ptr ds:[edi+60]
  00A3336A │. 85C0 test eax,eax
  00A3336C │. 74 5A je short D2Common.00A333C8
  00A3336E │. 50 push eax
  00A3336F │. E8 2CB4FEFF call D2Common.#10277
  00A33374 │. 85C0 test eax,eax
  00A33376 │. 74 50 je short D2Common.00A333C8
  00A33378 │> 50 push eax ;-\
  00A33379 │. 46 inc esi ;
  00A3337A │. E8 01EDFEFF call D2Common.#10304 ; 搜索镶嵌的个数
  00A3337F │. 85C0 test eax,eax ;
  00A33381 │.^ 75 F5 jnz short D2Common.00A33378;-/
  00A33383 │. 85F6 test esi,esi
  00A33385 │. 7E 41 jle short D2Common.00A333C8
  00A33387 │. 83FE 07 cmp esi,7 ;3 bit=2^3 =7上限
  00A3338A │. 8BC6 mov eax,esi
  00A3338C │. 7C 05 jl short D2Common.00A33393
  00A3338E │. B8 07000000 mov eax,7 ;镶嵌的个数>7,使=7
  00A33393 │> 6A 03 push 3 ;已镶嵌的个数,3 bit=2^3 =7
  00A33395 │. 50 push eax
  00A33396 │. 53 push ebx
  00A33397 │. E8 64100200 call <jmp.&Fog.#10128>
修改
  00A33352 │. 6A 20 push 20
  00A33387 │. 83FE 07 cmp esi,7
  00A3338E │. B8 07000000 mov eax,7
  00A33393 │> 6A 03 push 3

  00A33352 │. 6A 1F push 1F
  00A33387 │. 83FE 0F cmp esi,0F
  00A3338E │. B8 0F000000 mov eax,0F
  00A33393 │> 6A 04 push 4
修改后,新建镶嵌15孔的物品,退出游戏,再进入游戏。测试通过。
  最后,还有一个尾巴,就是孔的显示问题。当孔数大于物品占格子数时,显示孔和镶嵌的宝石就不正常,还需要修改显示代码。设想新显示方法为一 4 X 4 矩阵,由上至下,再由左至右的排列。
孔的显示代码如下
  6FAE0DC0 83EC 60 sub esp,60
  6FAE0DC3 53 push ebx
  6FAE0DC4 55 push ebp
  │
  │
  6FAE0F1A 5D pop ebp
  6FAE0F1B 5B pop ebx
  6FAE0F1C 83C4 60 add esp,60
  6FAE0F1F C2 0800 retn 8
由于时间关系(N天上不了BBS),进行了3种修改。
修改1:将原显示代码中计算位置的代码去掉,换为新的定位代码。
  代码已包含在修改3中,略。效果图见末图2。
修改2:成功写出新的定位代码后,当孔数较少时用新的定位,显示不能居中,难看。进行修改2。原孔定位不变,加孔数大于物品占格子数时采用新的定位代码。效果图见末图1。
对应孔的显示代码,修改
  6FAE0E55 E9 3FB60800 jmp d2client.6FB6C499
  6FAE0E5A 90 nop
  6FAE0E9F B9 0E000000 mov ecx,0E
  6FAE0F12 0F82 E8B50800 jb d2client.6FB6C500
在代码段末尾加代码
  6FB6C499 ^ 0F84 794AF7FF je d2client.6FAE0F18
  6FB6C49F 8BC8 mov ecx,eax
  6FB6C4A1 8A4424 1C mov al,byte ptr ss:[esp+1C]
  6FB6C4A5 33D2 xor edx,edx
  6FB6C4A7 8A5424 20 mov dl,byte ptr ss:[esp+20]
  6FB6C4AB 0FAFC2 imul eax,edx
  6FB6C4AE 3BC8 cmp ecx,eax
  6FB6C4B0 ^ 0F86 AF49F7FF jbe d2client.6FAE0E65 ;孔数小于物品占格子数,回
  6FB6C4B6 B0 4E mov al,4E ;设置用新码标志,'N'
  6FB6C4B8 894424 60 mov dword ptr ss:[esp+60],eax
  6FB6C4BC 8B4424 78 mov eax,dword ptr ss:[esp+78]
  6FB6C4C0 894424 68 mov dword ptr ss:[esp+68],eax
  6FB6C4C4 83C0 60 add eax,60
  6FB6C4C7 894424 6C mov dword ptr ss:[esp+6C],eax
  6FB6C4CB 8B5C24 74 mov ebx,dword ptr ss:[esp+74]
  6FB6C4CF 895C24 64 mov dword ptr ss:[esp+64],ebx
  6FB6C4D3 8B4424 68 mov eax,dword ptr ss:[esp+68]
  6FB6C4D7 8B5C24 64 mov ebx,dword ptr ss:[esp+64]
  6FB6C4DB 3B4424 6C cmp eax,dword ptr ss:[esp+6C]
  6FB6C4DF 7C 07 jl short d2client.6FB6C4E8
  6FB6C4E1 8B4424 78 mov eax,dword ptr ss:[esp+78]
  6FB6C4E5 83C3 1D add ebx,1D
  6FB6C4E8 83C0 1D add eax,1D
  6FB6C4EB 895C24 64 mov dword ptr ss:[esp+64],ebx
  6FB6C4EF 894424 68 mov dword ptr ss:[esp+68],eax
  6FB6C4F3 8BF0 mov esi,eax
  6FB6C4F5 8B15 345EBB6F mov edx,dword ptr ds:[6FBB5E34]
  6FB6C4FB ^ E9 9F49F7FF jmp d2client.6FAE0E9F
  6FB6C500 8B7424 60 mov esi,dword ptr ss:[esp+60]
  6FB6C504 83FE 4E cmp esi,4E ;标志'N'?
  6FB6C507 ^ 74 CA je short d2client.6FB6C4D3
  6FB6C509 ^ E9 4F49F7FF jmp d2client.6FAE0E5D ;否,回
下面为加入代码的二进制复制:
  0F 84 79 4A F7 FF 8B C8 8A 44 24 1C 33 D2 8A 54 24 20 0F AF C2 3B C8 0F 86 AF
  49 F7 FF B0 4E 89
  44 24 60 8B 44 24 78 89 44 24 68 83 C0 60 89 44 24 6C 8B 5C 24 74 89 5C 24 64
  8B 44 24 68 8B 5C
  24 64 3B 44 24 6C 7C 07 8B 44 24 78 83 C3 1D 83 C0 1D 89 5C 24 64 89 44 24 68
  8B F0 8B 15 34 5E
  BB 6F E9 9F 49 F7 FF 8B 74 24 60 83 FE 4E 74 CA E9 4F 49 F7 FF
以上的加入代码用了镜像地址的引用,要修改重载列表,需要插入、删除、修改DLL文件,而D2Client.dll没重载,可以不改,故略去(怕我说明不清,但是我的是修改了的)。
修改3:针对显示物品属性时会遮挡孔的显示,进行修改3。将原显示代码中计算位置的代码去掉,换为新的定位代码。将孔的显示位置左移或右移。同时加上一底色,并加强孔的显示图案(将显示函数重写了一半以上)。效果图见末图3。
以下为新的显示函数的完整代码:
  6FAE0DC0 83EC 60 sub esp,60
  6FAE0DC3 53 push ebx
  6FAE0DC4 55 push ebp
  6FAE0DC5 56 push esi
  6FAE0DC6 57 push edi
  6FAE0DC7 68 4C97B76F push d2client.6FB7974C
  6FAE0DCC 8BD9 mov ebx,ecx
  6FAE0DCE 68 5E040000 push 45E
  6FAE0DD3 8BFA mov edi,edx
  6FAE0DD5 6A 10 push 10
  6FAE0DD7 53 push ebx
  6FAE0DD8 897C24 24 mov dword ptr ss:[esp+24],edi
  6FAE0DDC 895C24 34 mov dword ptr ss:[esp+34],ebx
  6FAE0DE0 E8 99A00800 call <jmp.&D2Common.#10707>
  6FAE0DE5 85C0 test eax,eax
  6FAE0DE7 0F84 2B010000 je d2client.6FAE0F18
  6FAE0DED 8B43 60 mov eax,dword ptr ds:[ebx+60]
  6FAE0DF0 50 push eax
  6FAE0DF1 E8 7A9C0800 call <jmp.&D2Common.#10277>
  6FAE0DF6 8D4C24 1C lea ecx,dword ptr ss:[esp+1C]
  6FAE0DFA 894424 18 mov dword ptr ss:[esp+18],eax
  6FAE0DFE 8B4424 78 mov eax,dword ptr ss:[esp+78]
  6FAE0E02 894424 68 mov dword ptr ss:[esp+68],eax
  6FAE0E06 83C0 60 add eax,60 ; >1D X (4-1行)=57
  6FAE0E09 894424 6C mov dword ptr ss:[esp+6C],eax
  6FAE0E0D 8B5C24 74 mov ebx,dword ptr ss:[esp+74]
  6FAE0E11 895C24 64 mov dword ptr ss:[esp+64],ebx
  6FAE0E15 33F6 xor esi,esi
  6FAE0E17 897424 10 mov dword ptr ss:[esp+10],esi
  6FAE0E1B EB 53 jmp short d2client.6FAE0E70 ;不改就是方法1,NOP这行就是方法3
  6FAE0E1D 8B0D 48A7BB6F mov ecx,dword ptr ds:[6FBBA748]
  6FAE0E23 33D2 xor edx,edx
  6FAE0E25 BA 82000000 mov edx,82
  6FAE0E2A 03D1 add edx,ecx
  6FAE0E2C 3BDA cmp ebx,edx
  6FAE0E2E 7C 1A jl short d2client.6FAE0E4A ;左边,右移
  6FAE0E30 81C2 B8010000 add edx,1B8
  6FAE0E36 3BDA cmp ebx,edx
  6FAE0E38 7C 08 jl short d2client.6FAE0E42 ;中间,左移
  6FAE0E3A 81EB 90010000 sub ebx,190
  6FAE0E40 EB 0E jmp short d2client.6FAE0E50 ;最右边2列,左左移
  6FAE0E42 81EB 91000000 sub ebx,91
  6FAE0E48 EB 06 jmp short d2client.6FAE0E50
  6FAE0E4A 81C3 57000000 add ebx,57
  6FAE0E50 83C0 15 add eax,15
  6FAE0E53 83C3 74 add ebx,74
  6FAE0E56 6A 02 push 2 ;25 %透明(0:75%.1:50%,3.4.6部分颜色透明,5:普通)
  6FAE0E58 68 A0000000 push 0A0 ;底色
  6FAE0E5D 50 push eax
  6FAE0E5E 53 push ebx
  6FAE0E5F 83E8 74 sub eax,74
  6FAE0E62 83EB 74 sub ebx,74
  6FAE0E65 50 push eax
  6FAE0E66 53 push ebx
  6FAE0E67 E8 D8A90800 call <jmp.&D2gfx.#10055>
  6FAE0E6C 895C24 64 mov dword ptr ss:[esp+64],ebx
  6FAE0E70 8B4424 68 mov eax,dword ptr ss:[esp+68]
  6FAE0E74 8B5C24 64 mov ebx,dword ptr ss:[esp+64]
  6FAE0E78 3B4424 6C cmp eax,dword ptr ss:[esp+6C]
  6FAE0E7C 7C 07 jl short d2client.6FAE0E85
  6FAE0E7E 8B4424 78 mov eax,dword ptr ss:[esp+78]
  6FAE0E82 83C3 1D add ebx,1D
  6FAE0E85 83C0 1D add eax,1D
  6FAE0E88 895C24 64 mov dword ptr ss:[esp+64],ebx
  6FAE0E8C 894424 68 mov dword ptr ss:[esp+68],eax
  6FAE0E90 8BF0 mov esi,eax
  6FAE0E92 8B15 345EBB6F mov edx,dword ptr ds:[6FBB5E34]
  6FAE0E98 B9 0E000000 mov ecx,0E
  6FAE0E9D 33C0 xor eax,eax
  6FAE0E9F 8D7C24 28 lea edi,dword ptr ss:[esp+28]
  6FAE0EA3 F3:AB rep stos dword ptr es:[edi]
  6FAE0EA5 B9 05000000 mov ecx,5 ;普通显示,加强孔的效果
  6FAE0EAA 90 nop
  6FAE0EAB 90 nop
  6FAE0EAC 50 push eax
  6FAE0EAD 894424 38 mov dword ptr ss:[esp+38],eax
  6FAE0EB1 894424 34 mov dword ptr ss:[esp+34],eax
  6FAE0EB5 51 push ecx
  6FAE0EB6 6A FF push -1
  6FAE0EB8 8D43 FF lea eax,dword ptr ds:[ebx-1]
  6FAE0EBB 56 push esi
  6FAE0EBC 8D4C24 38 lea ecx,dword ptr ss:[esp+38]
  6FAE0EC0 50 push eax
  6FAE0EC1 51 push ecx
  6FAE0EC2 895424 44 mov dword ptr ss:[esp+44],edx
  6FAE0EC6 E8 85A90800 call <jmp.&D2gfx.#10072>
  6FAE0ECB 8B7C24 18 mov edi,dword ptr ss:[esp+18]
  6FAE0ECF 85FF test edi,edi
  6FAE0ED1 74 25 je short d2client.6FAE0EF8
  6FAE0ED3 57 push edi
  6FAE0ED4 E8 8B9B0800 call <jmp.&D2Common.#10305>
  6FAE0ED9 33D2 xor edx,edx
  6FAE0EDB 8B4C24 14 mov ecx,dword ptr ss:[esp+14]
  6FAE0EDF 8A51 15 mov dl,byte ptr ds:[ecx+15]
  6FAE0EE2 8BC8 mov ecx,eax
  6FAE0EE4 2BF2 sub esi,edx
  6FAE0EE6 8BD3 mov edx,ebx
  6FAE0EE8 56 push esi
  6FAE0EE9 E8 32940700 call d2client.6FB5A320
  6FAE0EEE 57 push edi
  6FAE0EEF E8 769B0800 call <jmp.&D2Common.#10304>
  6FAE0EF4 894424 18 mov dword ptr ss:[esp+18],eax
  6FAE0EF8 8B7424 10 mov esi,dword ptr ss:[esp+10]
  6FAE0EFC 8B5424 24 mov edx,dword ptr ss:[esp+24]
  6FAE0F00 46 inc esi
  6FAE0F01 52 push edx
  6FAE0F02 897424 14 mov dword ptr ss:[esp+14],esi
  6FAE0F06 E8 CFA00800 call <jmp.&D2Common.#10816>
  6FAE0F0B 25 FF000000 and eax,0FF
  6FAE0F10 3BF0 cmp esi,eax
  6FAE0F12 ^ 0F82 58FFFFFF jb d2client.6FAE0E70
  6FAE0F18 5F pop edi
  6FAE0F19 5E pop esi
  6FAE0F1A 5D pop ebp
  6FAE0F1B 5B pop ebx
  6FAE0F1C 83C4 60 add esp,60
  6FAE0F1F C2 0800 retn 8
下面为新显示函数的二进制复制:
  83 EC 60 53 55 56 57 68 4C 97 B7 6F 8B D9 68 5E 04 00 00 8B FA 6A 10 53 89 7C
  24 24 89 5C 24 34
  E8 99 A0 08 00 85 C0 0F 84 2B 01 00 00 8B 43 60 50 E8 7A 9C 08 00 8D 4C 24 1C
  89 44 24 18 8B 44
  24 78 89 44 24 68 83 C0 60 89 44 24 6C 8B 5C 24 74 89 5C 24 64 33 F6 89 74 24
  10 EB 53 8B 0D 48
  (24 78 89 44 24 68 83 C0 60 89 44 24 6C 8B 5C 24 74 89 5C 24 64 33 F6 89 74
  24 10 90 90 8B 0D 48)(NOP,后)
  A7 BB 6F 33 D2 BA 82 00 00 00 03 D1 3B DA 7C 1A 81 C2 B8 01 00 00 3B DA 7C 08
  81 EB 90 01 00 00
  EB 0E 81 EB 91 00 00 00 EB 06 81 C3 57 00 00 00 83 C0 15 83 C3 74 6A 02 68 A0
  00 00 00 50 53 83
  E8 74 83 EB 74 50 53 E8 DD A9 08 00 89 5C 24 64 8B 44 24 68 8B 5C 24 64 3B 44
  24 6C 7C 07 8B 44
  24 78 83 C3 1D 83 C0 1D 89 5C 24 64 89 44 24 68 8B F0 8B 15 34 5E BB 6F B9 0E
  00 00 00 33 C0 8D
  7C 24 28 F3 AB B9 05 00 00 00 90 90 50 89 44 24 38 89 44 24 34 51 6A FF 8D 43
  FF 56 8D 4C 24 38
  50 51 89 54 24 44 E8 85 A9 08 00 8B 7C 24 18 85 FF 74 25 57 E8 8B 9B 08 00 33
  D2 8B 4C 24 14 8A
  51 15 8B C8 2B F2 8B D3 56 E8 32 94 07 00 57 E8 76 9B 08 00 89 44 24 18 8B 74
  24 10 8B 54 24 24
  46 52 89 74 24 14 E8 CF A0 08 00 25 FF 00 00 00 3B F0 0F 82 58 FF FF FF 5F 5E
  5D 5B 83 C4 60 C2
  08 00
以上新显示函数用了镜像地址的引用,修改下面重载列表(D2Client.dll没重载,可以不改)
  修改
  6FB9F2FC 08 3E 4A 3E 91 3E
  为
  6FB9F2FC 1F 3E 00 00 94 3E
选一显示方法修改后,将孔的上限改为15个就算成功了。当然,想有超过6孔的东西只对公式打孔有效,如果想物品生成时也能超过6孔(这样就可以买到和打到过6孔的东西),还要修改一些地方,这就是下一步的工作。设想在物品生成代码中,到此代码中找到限制:
修改
  6FC4D6F0 56 push esi
  6FC4D6F1 E8 E8E40C00 call <jmp.&D2Common.#10815> ;获取物品孔数上限
  6FC4D6F6 25 FF000000 and eax,0FF
  6FC4D6FB 8BF8 mov edi,eax
  6FC4D6FD 33C0 xor eax,eax
  6FC4D6FF 8A43 6D mov al,byte ptr ds:[ebx+6D] ;难度
  6FC4D702 83E8 00 sub eax,0
  6FC4D705 74 1E je short D2Game.6FC4D725 ;转普通
  6FC4D707 48 dec eax
  6FC4D708 74 0F je short D2Game.6FC4D719 ;转噩梦
  6FC4D70A 48 dec eax
  6FC4D70B 75 24 jnz short D2Game.6FC4D731
  6FC4D70D 83FF 06 cmp edi,6 ;地狱中,孔数<6 ?
  6FC4D710 7C 1F jl short D2Game.6FC4D731
  6FC4D712 BF 06000000 mov edi,6 ;孔数>=6,设打6孔
  6FC4D717 EB 20 jmp short D2Game.6FC4D739
  6FC4D719 83FF 04 cmp edi,4 ;噩梦中,孔数<4 ?
  6FC4D71C 7C 13 jl short D2Game.6FC4D731
  6FC4D71E BF 04000000 mov edi,4 ;孔数>=4,设打4孔
  6FC4D723 EB 14 jmp short D2Game.6FC4D739
  6FC4D725 83FF 03 cmp edi,3 ;普通中,孔数<3 ?
  6FC4D728 7C 07 jl short D2Game.6FC4D731
  6FC4D72A BF 03000000 mov edi,3 ;孔数>=3,设打3孔
  6FC4D72F EB 08 jmp short D2Game.6FC4D739
  6FC4D731 85FF test edi,edi
  6FC4D733 0F8E C1000000 jle D2Game.6FC4D7FA
改为
  6FC4D710 EB 1F jmp short D2Game.6FC4D731
  6FC4D71C EB 13 jmp short D2Game.6FC4D731
  6FC4D728 EB 07 jmp short D2Game.6FC4D731
以上代码在D2Game.dll(1.10)中,为物品生成带孔时根据游戏难度限制孔数。改完后,屏蔽掉难度限制。当然也可以对应难度改高限制。
  退出游戏,再进入游戏。到NPC处买东西,发现仍然未突破6孔。估计难度限制后还有限制。在调用修改物品属性前找到限制:
00A2D5FD BD 06000000 mov ebp,6 ;上限
  │
  00A2D63D 0FAFC1 imul eax,ecx ;计算格子(宽X高)限制
  00A2D640 83F8 06 cmp eax,6 ;比对哪个限制小
  00A2D643 7F 02 jg short D2Common.00A2D647
  00A2D645 8BE8 mov ebp,eax
  │
  00A2D666 83C0 FC add eax,-4 ;品质-4
  00A2D669 83F8 05 cmp eax,5 ;
  00A2D66C 77 4C ja short D2Common.00A2D6BA ;品质小于4,跳转
  00A2D66E FF2485 A8D7A200 jmp dword ptr ds:[eax*4+A2D7A8];对应品质查表跳转
  00A2D675 6A 00 push 0 ;品质5/7, SET/UNIQUE
  00A2D677 68 C2000000 push 0C2
  00A2D67C 57 push edi
  00A2D67D E8 AEA50100 call D2Common.#10519
  00A2D682 85C0 test eax,eax ;测试有没有孔
  00A2D684 7E 06 jle short D2Common.00A2D68C;没有,跳转
  00A2D686 894424 14 mov dword ptr ss:[esp+14],eax;有,存
  00A2D68A EB 2E jmp short D2Common.00A2D6BA
  00A2D68C 83FD 01 cmp ebp,1 ;孔数<1 ?
  00A2D68F 7C 29 jl short D2Common.00A2D6BA
  00A2D691 BD 01000000 mov ebp,1 ;孔数>=1,设打1孔
  00A2D696 EB 22 jmp short D2Common.00A2D6BA
  00A2D698 83FD 02 cmp ebp,2 ;品质6,RARE,孔数<2?
  00A2D69B 7C 1D jl short D2Common.00A2D6BA
  00A2D69D BD 02000000 mov ebp,2 ;孔数>=2,设打2孔
  00A2D6A2 EB 16 jmp short D2Common.00A2D6BA
  00A2D6A4 83FD 04 cmp ebp,4 ;品质4,MAG,孔数<4?
  00A2D6A7 7C 11 jl short D2Common.00A2D6BA
  00A2D6A9 BD 04000000 mov ebp,4 ;孔数>=4,设打4孔
  00A2D6AE EB 0A jmp short D2Common.00A2D6BA
  00A2D6B0 83FD 03 cmp ebp,3 ;品质8/9,CRAFT/TEMPER,孔数<3?
  00A2D6B3 7C 05 jl short D2Common.00A2D6BA
  00A2D6B5 BD 03000000 mov ebp,3 ;孔数>=3,设打3孔
修改上限为
  00A2D5FD BD 0F000000 mov ebp,0F
  00A2D643 EB 02 jmp short D2Common.00A2D647
品质限制改为
  00A2D68F EB 29 jmp short D2Common.00A2D6BA
  00A2D69B EB 1D jmp short D2Common.00A2D6BA
  00A2D6A7 EB 11 jmp short D2Common.00A2D6BA
  00A2D6B3 EB 05 jmp short D2Common.00A2D6BA

  以上代码在D2Common.dll(1.10)中,是D2Common.#10817函数,功能是随机设置孔数。前面有一些限制(TXT中的限制略去),用最小的上限计算孔数,方法是:孔数=
  种子/上限+1。算出随机孔数后,再进行品质限制。这里改高了上限,屏蔽了品质限制。当然也可以修改品质限制。
  改完,退出游戏,再进入游戏。到NPC处买东西,有些东西已经超出6孔限制。再出城杀怪,也能掉出出6孔的东西。证明物品生成时也能超过6孔,目的达到。
再接下来,把任务打孔的上限也改高。
任务打孔代码:
  6FCCA4B3 │. 53 push ebx
  6FCCA4B4 │. E8 25170500 call <jmp.&D2Common.#10815> ;获取物品孔数上限
  6FCCA4B9 │. 25 FF000000 and eax,0FF
  6FCCA4BE │. 8BE8 mov ebp,eax
  6FCCA4C0 │. 53 push ebx
  6FCCA4C1 │. 896C24 18 mov dword ptr ss:[esp+18],ebp
  6FCCA4C5 │. E8 26140500 call <jmp.&D2Common.#10695> ;获取物品品质
  6FCCA4CA │. 83F8 04 cmp eax,4
  6FCCA4CD │. 74 17 je short D2Game.6FCCA4E6
  6FCCA4CF │. 0F8E 81000000 jle D2Game.6FCCA556
  6FCCA4D5 │. 83F8 09 cmp eax,9
  6FCCA4D8 │. 7F 7C jg short D2Game.6FCCA556
  6FCCA4DA │. 83FD 01 cmp ebp,1 ;品质5-9,SET、RARE、UNI、CRAFT、TEMPER,孔数<1?
  6FCCA4DD 7C 77 jl short D2Game.6FCCA556
  6FCCA4DF │. BD 01000000 mov ebp,1 ;孔数>=1,设打1孔
  6FCCA4E4 │. EB 70 jmp short D2Game.6FCCA556
  6FCCA4E6 │> 83FD 02 cmp ebp,2 ;品质4,MAG,孔数<2 ?
  6FCCA4E9 7C 09 jl short D2Game.6FCCA4F4
  6FCCA4EB │. BD 02000000 mov ebp,2 ;孔数>=2,设打2孔
  自己对应改高上限吧。
到此为止,6孔变15孔上限的修改可以说全完了。如果对15孔还有意见,可以再通过的修改再改为31(5bit)孔,有2种方法扩展。前提是物品代码最后一位符号不超过3F,原版的最后一位同一是20,所以可以再压缩物品代码出2bit,加上原来3bit,共5bit=31孔。
  
  一、完整的方法(工作列表):
  1、根据上面代码的注释对应5bit修改读取后解编、写入前编制的代码
  2、根据上面代码的注释对应5bit修改D2Common.#10822函数,使有足够堆栈进行修改ITEM的属性索引地址和插满孔后的神符之语检测。原代码中的空间只能就地修改,则能加(7C-3C)/4=10H=16个。因为要加
  25 X 4 =100 =64H的堆栈,+3C后=A0,所以原代码中的空间不足,不能直接修改堆栈大小,要重写D2Common.#10822函数。当然,如果不让可以做神符之语的物品的孔数小于等于16+6=22个,就可以直接修改。不能做神符之语的品质没关系。
  注意:难度限制孔数和品质限制对合成打孔法没用。
  3、根据上面代码的注释对应5bit修改打孔限制。同时要修改Itemstatcost.tXT中的储存限制。
  4、自愿修改显示代码(如用显示3),同样,原来已经几乎用尽显示孔代码的空间,不能直接修改,要重写。
  5、自愿修改物品生成时的限制代码和任务打孔的限制。
二、简单一点的方法:
  通过属性叠加突破4bit限制。对第三个工作改为修改或建立一个带孔属性的宝石或符文,镶上后孔数就叠加了。
根据完整的方法改完(2、4、5仍然没改,还是15孔的)没改生成了一个戒指。
以上涉及到的DLL文件是D2Common.dll(镜像地址为00Axxxxx)、D2Client.dll(镜像地址为6FAxxxxx
  6FBxxxxx)、D2Game.dll(6fcxxxxx)。当修改文件时用 镜像地址 - 009D0000
  、 镜像地址 - 6FAA0000 或 镜像地址 - 6FC30000 计算偏移地址OFFSET。所有的DLL文件为原1.10文件,进行测试时的也是在原1.10单机游戏中(只对TXT文件修改了一下)。
修补:
  由于修改D2Common.#10822函数是7天前,只是对错误进行修正,治标不治本。可以通过插入一段孔数的检测代码,当孔数大于6时跳过检测(因为神符之语最多要6孔)。则不管改为几个孔,都不怕堆栈溢出。修改和加入代码见下:
  修改:
  00A2DA03 83F8 04 cmp eax,4
  00A2DA06 7C 05 jl short D2Common.00A2DA0D
  00A2DA08 83F8 09 cmp eax,9
  00A2DA0B 7E 73 jle short D2Common.00A2DA80 ;大于等于品质4(magic)
  ;小于等于品质9(temper)退出检测

  00A2DA03 83F8 03 cmp eax,3
  00A2DA06 7F 78 jg short D2Common.00A2DA80 ;大于品质3(superior)退出检测
  00A2DA08 E9 6DFB0200 jmp D2Common.00A5D57A ;孔数检测
  二进制复制:
  83 F8 03 7F 78 E9 6D FB 02 00
在以下地址增加:(开始地址为afj666根据SG的方法修改的D2Common.dll(1.10),末尾的解除level.txt限制附加代码后)
  00A5D57A 53 push ebx
  00A5D57B 52 push edx
  00A5D57C 53 push ebx
  00A5D57D E8 FEFFFCFF call D2Common.#10816 ;获取孔数
  00A5D582 5A pop edx
  00A5D583 5B pop ebx
  00A5D584 83F8 06 cmp eax,6
  00A5D587 ^ 0F8F F304FDFF jg D2Common.00A2DA80 ;大于6孔退出检测
  00A5D58D ^ E9 7B04FDFF jmp D2Common.00A2DA0D ;回去继续检测
  二进制复制:
  53 52 53 E8 FE FF FC FF 5A 5B 83 F8 06 0F 8F F3 04 FD FF E9 7B 04 FD FF
我又针对31孔的显示写了一显示函数,就是另外建一窗口显示宝石的方法3,不过这里是由左至右,再由上至下的排列,效果图见图5:
  6FAE0DC0 83EC 60 sub esp,60
  6FAE0DC3 53 push ebx
  6FAE0DC4 55 push ebp
  6FAE0DC5 56 push esi
  6FAE0DC6 57 push edi
  6FAE0DC7 68 4C97B76F push d2client.6FB7974C
  6FAE0DCC 8BD9 mov ebx,ecx
  6FAE0DCE 68 5E040000 push 45E
  6FAE0DD3 8BFA mov edi,edx
  6FAE0DD5 6A 10 push 10
  6FAE0DD7 53 push ebx
  6FAE0DD8 897C24 24 mov dword ptr ss:[esp+24],edi
  6FAE0DDC 895C24 34 mov dword ptr ss:[esp+34],ebx
  6FAE0DE0 E8 99A00800 call <jmp.&D2Common.#10707>
  6FAE0DE5 85C0 test eax,eax
  6FAE0DE7 0F84 2B010000 je d2client.6FAE0F18
  6FAE0DED 8B43 60 mov eax,dword ptr ds:[ebx+60]
  6FAE0DF0 50 push eax
  6FAE0DF1 E8 7A9C0800 call <jmp.&D2Common.#10277>
  6FAE0DF6 8D4C24 1C lea ecx,dword ptr ss:[esp+1C]
  6FAE0DFA 894424 18 mov dword ptr ss:[esp+18],eax
  6FAE0DFE 8B5C24 74 mov ebx,dword ptr ss:[esp+74]
  6FAE0E02 8B4424 78 mov eax,dword ptr ss:[esp+78]
  6FAE0E06 8B0D 48A7BB6F mov ecx,dword ptr ds:[6FBBA748]
  6FAE0E0C 33D2 xor edx,edx
  6FAE0E0E BA 82000000 mov edx,82
  6FAE0E13 03D1 add edx,ecx
  6FAE0E15 3BDA cmp ebx,edx
  6FAE0E17 7C 1A jl short d2client.6FAE0E33
  6FAE0E19 81C2 B8010000 add edx,1B8
  6FAE0E1F 3BDA cmp ebx,edx
  6FAE0E21 7C 08 jl short d2client.6FAE0E2B
  6FAE0E23 81EB AD010000 sub ebx,1AD
  6FAE0E29 EB 0E jmp short d2client.6FAE0E39
  6FAE0E2B 81EB AE000000 sub ebx,0AE
  6FAE0E31 EB 06 jmp short d2client.6FAE0E39
  6FAE0E33 81C3 3A000000 add ebx,3A
  6FAE0E39 894424 68 mov dword ptr ss:[esp+68],eax
  6FAE0E3D 895C24 64 mov dword ptr ss:[esp+64],ebx
  6FAE0E41 53 push ebx
  6FAE0E42 50 push eax
  6FAE0E43 83C3 60 add ebx,60
  6FAE0E46 895C24 74 mov dword ptr ss:[esp+74],ebx
  6FAE0E4A 33F6 xor esi,esi
  6FAE0E4C 897424 18 mov dword ptr ss:[esp+18],esi
  6FAE0E50 83C3 31 add ebx,31
  6FAE0E53 05 CD000000 add eax,0CD
  6FAE0E58 90 nop
  6FAE0E59 59 pop ecx
  6FAE0E5A 5A pop edx
  6FAE0E5B 6A 02 push 2
  6FAE0E5D 68 A0000000 push 0A0
  6FAE0E62 50 push eax
  6FAE0E63 53 push ebx
  6FAE0E64 83E9 1D sub ecx,1D
  6FAE0E67 83C2 1D add edx,1D
  6FAE0E6A 51 push ecx
  6FAE0E6B 52 push edx
  6FAE0E6C E8 D3A90800 call <jmp.&D2gfx.#10055>
  6FAE0E71 8B4424 68 mov eax,dword ptr ss:[esp+68]
  6FAE0E75 8B5C24 64 mov ebx,dword ptr ss:[esp+64]
  6FAE0E79 3B5C24 6C cmp ebx,dword ptr ss:[esp+6C]
  6FAE0E7D 7C 06 jl short d2client.6FAE0E85
  6FAE0E7F 83EB 74 sub ebx,74
  6FAE0E82 83C0 1D add eax,1D
  6FAE0E85 83C3 1D add ebx,1D
  6FAE0E88 895C24 64 mov dword ptr ss:[esp+64],ebx
  6FAE0E8C 894424 68 mov dword ptr ss:[esp+68],eax
  6FAE0E90 8BF0 mov esi,eax
  6FAE0E92 8B15 345EBB6F mov edx,dword ptr ds:[6FBB5E34]
  6FAE0E98 B9 0E000000 mov ecx,0E
  6FAE0E9D 33C0 xor eax,eax
  6FAE0E9F 8D7C24 28 lea edi,dword ptr ss:[esp+28]
  6FAE0EA3 F3:AB rep stos dword ptr es:[edi]
  6FAE0EA5 B9 05000000 mov ecx,5
  6FAE0EAA 90 nop
  6FAE0EAB 90 nop
  6FAE0EAC 50 push eax
  6FAE0EAD 894424 38 mov dword ptr ss:[esp+38],eax
  6FAE0EB1 894424 34 mov dword ptr ss:[esp+34],eax
  6FAE0EB5 51 push ecx
  6FAE0EB6 6A FF push -1
  6FAE0EB8 8D43 FF lea eax,dword ptr ds:[ebx-1]
  6FAE0EBB 56 push esi
  6FAE0EBC 8D4C24 38 lea ecx,dword ptr ss:[esp+38]
  6FAE0EC0 50 push eax
  6FAE0EC1 51 push ecx
  6FAE0EC2 895424 44 mov dword ptr ss:[esp+44],edx
  6FAE0EC6 E8 85A90800 call <jmp.&D2gfx.#10072>
  6FAE0ECB 8B7C24 18 mov edi,dword ptr ss:[esp+18]
  6FAE0ECF 85FF test edi,edi
  6FAE0ED1 74 25 je short d2client.6FAE0EF8
  6FAE0ED3 57 push edi
  6FAE0ED4 E8 8B9B0800 call <jmp.&D2Common.#10305>
  6FAE0ED9 33D2 xor edx,edx
  6FAE0EDB 8B4C24 14 mov ecx,dword ptr ss:[esp+14]
  6FAE0EDF 8A51 15 mov dl,byte ptr ds:[ecx+15]
  6FAE0EE2 8BC8 mov ecx,eax
  6FAE0EE4 2BF2 sub esi,edx
  6FAE0EE6 8BD3 mov edx,ebx
  6FAE0EE8 56 push esi
  6FAE0EE9 E8 32940700 call d2client.6FB5A320
  6FAE0EEE 57 push edi
  6FAE0EEF E8 769B0800 call <jmp.&D2Common.#10304>
  6FAE0EF4 894424 18 mov dword ptr ss:[esp+18],eax
  6FAE0EF8 8B7424 10 mov esi,dword ptr ss:[esp+10]
  6FAE0EFC 8B5424 24 mov edx,dword ptr ss:[esp+24]
  6FAE0F00 46 inc esi
  6FAE0F01 52 push edx
  6FAE0F02 897424 14 mov dword ptr ss:[esp+14],esi
  6FAE0F06 E8 CFA00800 call <jmp.&D2Common.#10816>
  6FAE0F0B 25 FF000000 and eax,0FF
  6FAE0F10 3BF0 cmp esi,eax
  6FAE0F12 ^ 0F82 59FFFFFF jb d2client.6FAE0E71
  6FAE0F18 5F pop edi
  6FAE0F19 5E pop esi
  6FAE0F1A 5D pop ebp
  6FAE0F1B 5B pop ebx
  6FAE0F1C 83C4 60 add esp,60
  6FAE0F1F C2 0800 retn 8
  二进制复制:
  83 EC 60 53 55 56 57 68 4C 97 B7 6F 8B D9 68 5E 04 00 00 8B FA 6A 10 53 89 7C
  24 24 89 5C 24 34
  E8 99 A0 08 00 85 C0 0F 84 2B 01 00 00 8B 43 60 50 E8 7A 9C 08 00 8D 4C 24 1C
  89 44 24 18 8B 5C
  24 74 8B 44 24 78 8B 0D 48 A7 BB 6F 33 D2 BA 82 00 00 00 03 D1 3B DA 7C 1A 81
  C2 B8 01 00 00 3B
  DA 7C 08 81 EB AD 01 00 00 EB 0E 81 EB AE 00 00 00 EB 06 81 C3 3A 00 00 00 89
  44 24 68 89 5C 24
  64 53 50 83 C3 60 89 5C 24 74 33 F6 89 74 24 18 83 C3 31 05 CD 00 00 00 90 59
  5A 6A 02 68 A0 00
  00 00 50 53 83 E9 1D 83 C2 1D 51 52 E8 D3 A9 08 00 8B 44 24 68 8B 5C 24 64 3B
  5C 24 6C 7C 06 83
  EB 74 83 C0 1D 83 C3 1D 89 5C 24 64 89 44 24 68 8B F0 8B 15 34 5E BB 6F B9 0E
  00 00 00 33 C0 8D
  7C 24 28 F3 AB B9 05 00 00 00 90 90 50 89 44 24 38 89 44 24 34 51 6A FF 8D 43
  FF 56 8D 4C 24 38
  50 51 89 54 24 44 E8 85 A9 08 00 8B 7C 24 18 85 FF 74 25 57 E8 8B 9B 08 00 33
  D2 8B 4C 24 14 8A
  51 15 8B C8 2B F2 8B D3 56 E8 32 94 07 00 57 E8 76 9B 08 00 89 44 24 18 8B 74
  24 10 8B 54 24 24
  46 52 89 74 24 14 E8 CF A0 08 00 25 FF 00 00 00 3B F0 0F 82 59 FF FF FF 5F 5E
  5D 5B 83 C4 60 C2
  08 00
最后祝大家玩的愉快!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|网站地图|联系我们|关于我们|隐私条款|免责声明|小黑屋|D2home暗黑1.09战网 ( 鲁ICP备2020047197号 )

GMT+8, 2024-11-28 13:01 , Processed in 0.206747 second(s), 21 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表