[04.dos程序代码的内存修改]
基本的修改办法是在要修改处放一个跨段的call或jmp,直接跳到我们设置的新空间去,完成所需修改,有时还需要运行被跳转语句覆盖的代码,再跳回或返回修改处。注意需做好寄存器、flag、函数临时变量空间等状态的保护
一个跨段修改的演示,原始内容为:
seg002:3721 1E push ds
seg002:3722 68 D4 2F push offset aKOanxDkmkp ; 玩家军队状况
seg002:3725 6A 00 push 0 ; 按钮数
seg002:3727 9A 42 32 F6 0C call _sub_ShowMsg ; 玩家军队状况
seg002:372C 83 C4 06 add sp, 6
此处是玩家回合开始后显示“玩家军队状况”信息框,push 0表示是无按钮的,想让它加个确认按钮,点击确认后才继续,即需要把push 0改为push 1,16进制代码改从6a 00改为6a 01。我们可以直接将seg002:3725处的 6A 00改为6A 01。现在我们不这样改,跳走到新空间处去改出这个功能
那可以在地址3721那里加个jmp,跳走到[sg08]段,加一个修改处
[m33]
caption=回合信息01
s=1e68d42f6a00
r=ea0000[sg08]90
offset=20641
mode=normal
caption=回合信息01,这个是给我们自己看的,设置成什么都可以
offset=20641是在ida中看到的current location,即内存位置
s=1e68d42f6a00 是搜索在该处的原始内容,用于校验。因为jmp长跳转需要占用5字节,在本修改中占用3条汇编指令,增加本跳转会覆盖掉push ds; push offset aKOanxDkmkp; push 0
r=ea0000[sg08]90 对应的汇编指令为 jmp [sg08]:0000; nop; ,sg08在前述段信息中为3dc7,即跳走到3dc7:0000
mode=normal一行表示正常状态,检查s行的待搜索内容无误后才会替换。改为mode=off表示关闭本修改,即不管检查结果对不对均不修改。改为mode=force表示强制修改,即不管检查结果对不对均强制修改。
接下来需要在3dc7:0000处拼接出修改内容
[m34]
caption=回合信息02
s=0000000000000000000000
r=1e68d42f6a01ea2737[sg03]
offset=3dc70
mode=normal
offset=3dc70,需要计算得出,即16进制下 段址*10+偏移,本例是3dc7*10+0=3dc70
s=0000000000000000000000,此处应为0,如检查到不为0,需要在exe文件尾同步增加全0内容
r=1e68d42f6a01ea2737[sg03],拆解一下:
1e68d42f对应 push ds;push offset aKOanxDkmkp
6a01对应 push 01,是我们本次要修改的内容,相当于替换了原来的push 0,将函数调用参数从无按钮改为有一个按钮
ea2737[sg03]对应jmp [sg03]:3727,跳回到调用函数处,注意到sg03对应了ida中看到的段seg002,因为本修改器脚本的下标是从1开始,ida里面显示的段是从0开始。
修改代码后,到玩家回合后,效果显现,需要点一下确认才继续向下进行。不想修改了,在doxbox game trainer中点击恢复内存代码。
附上dosbox game trainer及三国英杰传示例脚本
更新:1005版本支持在offset中使用段名称,修复在扩容程序中会崩溃的bug
0220更新1010版:
offset中可使用常规偏移地址,或段地址+偏移地址
修改模式增加了basic模式,即修改后不再恢复
增加查看内存功能,目前可显示两块内存,在程序关联后即可使用
。其中段地址支持307d等直接的数字,也可以用[sg07],两者效果一样;偏移1可以是正常的地址,如5508,与前面的段地址配合,则显示类似307d:5508处开始的数据,也可以用p5508、P5508、*5508表示这是一个段指针,这时会从类似307d:5508处取段数据,再配合后面的偏移2显示该处数据。
[ 本帖最后由 likelove 于 2025-2-20 23:48 编辑 ]