欢迎光临散文网 会员登陆 & 注册

实现词缀的自定义

2022-11-19 13:25 作者:螺丝刀_汗颜  | 我要投稿

它是按大神573650245分享的脚本上调整而来,大家记住,最核心的部分是573650245大佬完成且无偿无私分享出来,文章的开关应该向之致敬。这是极破坏游戏的修改,但也极有借鉴学习意义,无论是为了拯救动不动就脆求词缀存档者,还是为了让某些野心家少赚点不当收入,还是分享吧。

下图是整个脚本的构造:

实现的功能是:

将无词缀装备扔到地面上,会增加自定义词缀,并自动完成鉴定(可选)

脚本因使用全局定义,所以大家按顺序复制并依次建立相应的脚本吧,不然可能出错。


1, 定义全局变量, 多脚本调用此变量,所以这个脚本必须放最前面, "置顶"使用.

[ENABLE]

globalalloc(CT1,256)

// 存储自定义数据

//  +0 byte 为词缀孔洞顺序, +1 byte 为调整的技能等级或上下限的孔洞序号

//  +4 为启用词缀修改   

//  +10 起存储修改的词缀原数据,为还原之用,否则因词缀被破坏,游戏无法再打出正常词缀

[DISABLE]



2, 给地面物品附加词缀时,调整其装备等级,否则可能生成词缀数量不足5洞

如果要给不能生成5洞的部件附加5洞,应该还要调整装备类型改为戒指或手镯等等

这一点,也是本注入地址的函数之中,请自行下断分析后调整.

[ENABLE]

alloc(newmem,2048)

label(returnhere)

label(originalcode)

label(exit)

newmem:

mov eax,[eax+74]

originalcode:

cmp [CT1+4],1       

jne exit                              //不是扔背包装备时,不予以调整等级,使用原数值

mov eax,7

exit:

mov [ebp-1C],eax

jmp returnhere

"gamesvr.exe"+60C4E:

jmp newmem

nop

returnhere: 

[DISABLE]

dealloc(newmem)

"gamesvr.exe"+60C4E:

mov eax,[eax+74]

mov [ebp-1C],eax

//Alt: db 8B 40 74 89 45 E4



3, 丢弃装备时,给它附加词缀;   

代码注入点是判断有无词缀之处,如果想附加全部装备,需要更改注入在跳转之后的语句处。

注意,不要随便更改注入地址,有词缀的装备需要先清除原词缀数据,否则保存游戏重登录时可能会引起词缀错乱。

[ENABLE]

alloc(newmem,2048)

label(returnhere)

newmem:

jne returnhere

mov [CT1],0               // 每次必清计数器,这样就能保证从第1洞开始修改

mov [CT1+4],1          //  启用词缀修改标志, 修改的调整才不影响到杀怪爆的词缀

lea ecx,[ebp-000000AC]       // 地面物品数据地址

push 5                                  // 参数2  生成词缀的总孔洞数量

push ecx                              // 参数1   地面物品 不能是背包物品,因为数据长度不一样

call gamesvr.exe+60B90

xor ecx,ecx

mov eax,CT1

mov [eax+4],ecx                    // 关闭词缀修改标志        


_loop:                                   // 以下是还原记录到的词缀数据,如果有记录的话

inc ecx

cmp ecx,6

jnl _end_loop                      // 最多有6条记录

lea eax,[eax+10]

mov edx,[eax]                     // 读出原词缀的地址

test edx,edx

je _loop                                //  无记录

push ecx                             // 临时征用ecx寄存器来中转数据

mov ecx,[eax+4]                       

mov [edx],ecx                      // 还原词缀编号

mov ecx,[eax+8]

mov [edx+C],ecx                 //  还原词缀技能数据

mov [eax],0                        //  清0,以示已处理

pop ecx                              // 还原计数器的循环次数

jmp _loop


_end_loop:

jmp gamesvr.exe+983AB

"gamesvr.exe"+9830F:

jmp newmem

nop

returnhere: 

[DISABLE]

dealloc(newmem)

"gamesvr.exe"+9830F:

je gamesvr.exe+983AB

//Alt: db 0F 84 96 00 00 00



4, 自定义词缀的类型,并记录原数据

[ENABLE]

alloc(newmem,2048)

label(returnhere)

label(originalcode)

label(exit)

newmem:

cmp [CT1+4],1       

jne originalcode                // 非丢弃装备时,不启用词缀调整

inc byte ptr [CT1]             // 词缀孔洞序号 +1, 每次都是从第1洞开始处理

//记录词缀原始数据

movzx edx,byte ptr [CT1]

imul edx,10

lea ecx,[CT1+edx]

mov eax,[edi+1C]

mov [ecx],eax

mov edx,[eax]

mov [ecx+4],edx

mov edx,[eax+C]

mov [ecx+8],edx


movzx edx,byte ptr [CT1]         

//读出孔洞序号后,比较.   判断的默认值是第1洞,即不是2~5,其它数字全则看作是1

cmp dl,2

je JN2

cmp dl,3

je JN3

cmp dl,4

je JN4

cmp dl,5

je JN5

mov [eax],09     //词缀1的编号,  09 为烈火

// 注大佬群中,也有群友整理出全部词缀编号等数据,请加群获取.

mov [eax+C],000F0001         //烈火技能的词缀数据,须跟09编号配套使用

jmp originalcode

JN2:

mov [eax],12     //词缀2的编号

mov [eax+C],001A0001

jmp originalcode

JN3:

mov [eax],13     //词缀3的编号

mov [eax+C],001B0001

jmp originalcode

JN4:

mov [eax],2B     //词缀4的编号

mov [eax+C],00311000

jmp originalcode

JN5:

mov [eax],2C    //词缀5的编号

mov [eax+C],00321000


originalcode:   //游戏原代码

mov eax,[edi+1C]

mov eax,[eax]


exit:

jmp returnhere

"gamesvr.exe"+102CD:

jmp newmem

returnhere:

[DISABLE]

dealloc(newmem)

"gamesvr.exe"+102CD:

mov eax,[edi+1C]

mov eax,[eax]

//Alt: db 8B 47 1C 8B 00



5,  调整范围类词缀的上下限

// 与大佬直接修改上下限数值不同,这里是直接调整后续调用函数的参数值

[ENABLE]

alloc(newmem,2048)

label(returnhere)

label(originalcode)

label(exit)

newmem:

// ebx == 最小值 + 最大值    00 XX 00 YY 

// FF FF == 最大值 65535

cmp [CT1+4],1              // 非丢弃装备时,不启用调整

jne originalcode

inc byte ptr[CT1+1]             // 孔洞计数器

cmp byte ptr [CT1+1],1

je _lv1

cmp byte ptr [CT1+1],2

je _lv2

cmp byte ptr [CT1+1],3

je _lv3

cmp byte ptr [CT1+1],4

je _lv4

// 这里是默认的第5孔洞的数据

mov ebx, 00020008

jmp originalcode

_lv1:

mov ebx, 000A000B

jmp originalcode

_lv2:

mov ebx, 000B000C

jmp originalcode

_lv3:

mov ebx, 000C000D

jmp originalcode

_lv4:

mov ebx, 00030007

jmp originalcode

originalcode:

movzx eax,word ptr [ecx+0E]

mov ecx,[ebp-04]

exit:

jmp returnhere

"gamesvr.exe"+10376:

jmp newmem

nop 2

returnhere: 

[DISABLE]

//code from here till the end of the code will be used to disable the cheat

dealloc(newmem)

"gamesvr.exe"+10376:

movzx eax,word ptr [ecx+0E]

mov ecx,[ebp-04]

//Alt: db 0F B7 41 0E 8B 4D FC



6, 设置加成是非范围的词缀的增益值(幸运,技能等级,掉落等等)

[ENABLE]

alloc(newmem,2048)

label(returnhere)

label(exit)

newmem:

cmp [CT1+4],1          // 非丢弃装备时,不启用调整

jne exit

inc byte ptr[CT1+1]              // 孔洞计数器

cmp byte ptr [CT1+1],1

je _lv1

cmp byte ptr [CT1+1],2

je _lv2

cmp byte ptr [CT1+1],3

je _lv3

cmp byte ptr [CT1+1],4

je _lv4

// 默认孔洞也是第5孔

mov edx,5

jmp returnhere

_lv1:

mov edx,4

jmp returnhere

_lv2:

mov edx,2

jmp returnhere

_lv3:

mov edx,1

jmp returnhere

_lv4:

mov edx,4

jmp returnhere

exit:

inc ecx

idiv ecx

add edx,esi

jmp returnhere

"gamesvr.exe"+103D2:

jmp newmem

returnhere: 

[DISABLE]

dealloc(newmem)

"gamesvr.exe"+103D2:

inc ecx

idiv ecx

add edx,esi

//Alt: db 41 F7 F9 03 D6



7,  捡起地面物品时,自动完成鉴定.

有缺陷,词缀名称不显示,所以只适合用来调试.

这里演示了如何自定义一个功能函数.

[ENABLE]

alloc(newmem,2048)

label(returnhere)

label(originalcode)

label(exit)

newmem:

call gamesvr.exe+402F0   // 游戏原代码, 捡物品向C端发回物品数据

push edi           // 背包物品地址, 注意不是地面物品地址

mov ecx,esi     // 人物地址

call JD_cizui    // 实现全鉴定的自定义自定义函数

originalcode:

exit:

jmp returnhere


JD_cizui:    

 //注意看自定义函数代码的放置位置

// 放在注入的自定义代码的后面,且在游戏注入地址的前面

// +8 参数1 == 背包物品地址

push ebp

mov ebp,esp

sub esp,20

push ebx

push esi

push edi

mov edi,[ebp+8]

mov [ebp-4],ecx

mov dl,[edi+56]

and dl,01

je _get_item_type

mov edx,[edi+4C]

mov ecx,[gamesvr.exe+1CEA1C]

call gamesvr.exe+D4240               // 解密读取词缀存储的编号

mov esi,eax

movzx edx,byte ptr [edi+24]

movzx ecx,byte ptr [gamesvr.exe+1CEA13]

call gamesvr.exe+D4240             // 解密读取物品的类型

jmp _is_eqt_not

_get_item_type:

movzx eax, byte ptr[edi+24]

mov esi,[edi+4C]

mov ecx,eax

_is_eqt_not:

call gamesvr.exe+6A8C0   // 是否是装备

test al,al

je __end__JD_cizui          // 非装备,跳

movzx eax,si

test eax,eax

je __end__JD_cizui       // 无词缀,跳

xor esi,esi

inc esi

//取出词缀序号后

push eax     //序号

mov ecx,[ebp-4]  // chr

call gamesvr.exe+8DEB0 //取出词缀数据

mov [ebp-14],eax

test eax,eax

je __end__JD_cizui


//核心函数

push 6   //设置已鉴定的词缀数目,最多是6洞

push 15    // 固定数值

mov ecx,[ebp-14] // 词缀 ptr

call gamesvr.exe+104A0 // 设置鉴定状态

push [ebp-14]

mov ecx,[ebp-4]     // 人物地址

call gamesvr.exe+8DEF0 // 让C端同步词缀鉴定状态

//函数尾

__end__JD_cizui:

pop edi

pop esi

pop ebx

mov esp,ebp

pop ebp

ret 4


gamesvr.exe+91470:

jmp newmem

returnhere:


[DISABLE]

dealloc(newmem)

gamesvr.exe+91470:

call gamesvr.exe+402F0



再次感谢573650245的分享!也祝愿所有爱学习单机修改的朋友,学有所成!

记得到希望BM上分享你们的学习成果,传播BM火种!


实现词缀的自定义的评论 (共 条)

分享到微博请遵守国家法律