Function 为什么提前移动调用函数1个字节会导致其出现故障?要修改什么来解决它?

Function 为什么提前移动调用函数1个字节会导致其出现故障?要修改什么来解决它?,function,assembly,disassembly,dosbox,hex-editors,Function,Assembly,Disassembly,Dosbox,Hex Editors,我正在尝试创建一个内联codecave来修改一个非常旧的dosgame(ROTK2)。但是,far调用无法重新定位-将函数调用的机器代码提前移动1个字节会导致其发生故障。我需要重新调整哪些参数来纠正问题 为了更具体地完成所需的任务,我需要创建3字节的空间来添加装配线。因此,我需要重新定位代码(codecaving可能不是一个可能的选项,因为脚本中缺少资源,我必须内联找到3个字节) 整个程序中的代码行太多,我不完全理解,但我正在使用带断点的dosbox调试器来精确定位相关行: 代码的这个位置打印出

我正在尝试创建一个内联codecave来修改一个非常旧的dosgame(ROTK2)。但是,far调用无法重新定位-将函数调用的机器代码提前移动1个字节会导致其发生故障。我需要重新调整哪些参数来纠正问题

为了更具体地完成所需的任务,我需要创建3字节的空间来添加装配线。因此,我需要重新定位代码(codecaving可能不是一个可能的选项,因为脚本中缺少资源,我必须内联找到3个字节)

整个程序中的代码行太多,我不完全理解,但我正在使用带断点的dosbox调试器来精确定位相关行:

代码的这个位置打印出游戏中当前时间点的年、月和季节。从第4EE8行开始,两次按下ax将光标移动到屏幕上的位置(2,4),以便年位于[0x44],月号位于bl[0x46],然后需要修改该数字,以在其他地方的文本中引用月。然后打印出字符串,并重复该过程。


00004EDF 0E推送cs
00004EE0 E80500呼叫0x4ee8
00004EE3 0E推送cs
00004EE4 E85101呼叫0x5038
00004EE7 CB retf
00004EE8 B80400 mov ax,0x4
00004EEB 50推力轴
00004EEC B80200 mov ax,0x2
00004EEF 50推力轴
00004EF0 9A3404EF03呼叫0x3ef:0x434
00004EF5 83C404添加sp,字节+0x4
00004EF8 FF364400推送字[0x44]
00004EFC 8A1E4600 mov bl,[0x46]
00004F00 2分接头bh,bh
00004F02 D1E3 shl bx,1
00004F04 FFB71C36推送字[bx+0x361c]
00004F08 B8B834移动轴,0x34b8
00004F0B 50推力轴
00004F0C 9AE806EF03调用0x3ef:0x6e8
00004F11 83C406添加sp,字节+0x6
00004F14 B80C00移动轴,0xc
00004F17 50推力轴
00004F18 B80500移动轴,0x5
00004F1B 50推力轴
00004F1C 9A3404EF03呼叫0x3ef:0x434
00004F21 83C404添加sp,字节+0x4
00004F24 A04600移动铝[0x46]
00004F27 B103 mov cl,0x3
00004F29 2AE4子ah,ah
00004F2B F6F1分区cl
00004F2D 8AD8 mov bl,al
00004F2F 2分接头bh,bh
00004F31 D1E3 shl bx,1
00004F33 FFB7D634推送字[bx+0x34d6]
00004F37 B8CC34移动轴,0x34cc
00004F3A 50推力轴
00004F3B 9AE806EF03调用0x3ef:0x6e8
00004F40 83C404添加sp,字节+0x4
00004F43 CB retf

通过这样做,我可以在不破坏代码的情况下使代码更加“简洁”:
...
00004EDF 0E推送cs
00004EE0 E80500呼叫0x4ee8
00004EE3 0E推送cs
00004EE4 E85101呼叫0x5038
00004EE7 CB retf
00004EE8 B80400 mov ax,0x4
00004EEB 50推力轴
00004EEC D1E8 shr ax,1
00004EEE 50推轴;很好,前一个数字是双倍的
00004EEF 90 nop
00004EF0 9A3404EF03呼叫0x3ef:0x434
00004EF5 83C404添加sp,字节+0x4
00004EF8 FF364400推送字[0x44]
00004EFC 8A1E4600 mov bl,[0x46]
00004F00 2分接头bh,bh
00004F02 D1E3 shl bx,1
00004F04 FFB71C36推送字[bx+0x361c]
00004F08 B8B834移动轴,0x34b8
00004F0B 50推力轴
00004F0C 9AE806EF03调用0x3ef:0x6e8
00004F11 83C406添加sp,字节+0x6
00004F14 B80C00移动轴,0xc
00004F17 50推力轴
00004F18 B80500移动轴,0x5
00004F1B 50推力轴
00004F1C 9A3404EF03呼叫0x3ef:0x434
00004F21 83C404添加sp,字节+0x4
00004F24 A04600移动铝[0x46]
00004F27 B103 mov cl,0x3
00004F29 2AE4子ah,ah
00004F2B F6F1分区cl
00004F2D 8AD8 mov bl,al
00004F2F 2分接头bh,bh
00004F31 D1E3 shl bx,1
00004F33 FFB7D634推送字[bx+0x34d6]
00004F37 B8CC34移动轴,0x34cc
00004F3A 50推力轴
00004F3B 9AE806EF03调用0x3ef:0x6e8
00004F40 83C404添加sp,字节+0x4
00004F43 CB retf

但是,一旦我将函数调用提前移动一个字节(而不是将nop放在调用0x3ef:0x434之前,而是先调用0x3ef:0x434,然后调用nop),所有功能都会停止工作

nop优先:dosbox记录器输出
07D2:0000039F nop
EAX:00000002 EBX:00000054 ECX:00000000 EDX:000003CF ESI:00003431 EDI:00000107 EBP:0000E424 ESP:0000E416 DS:32C3 ES:A000 FS:0000 GS:0000 SS:32C3 CF:0 ZF:0 SF:0 OF:0 AF:1 PF:0 IF:1
07D2:000003A0呼叫070C:0434
EAX:00000002 EBX:00000054 ECX:00000000 EDX:000003CF ESI:00003431 EDI:00000107 EBP:0000E424 ESP:0000E416 DS:32C3 ES:A000 FS:0000 GS:0000 SS:32C3 CF:0 ZF:0 SF:0 OF:0 AF:1 PF:0 IF:1

无nop:
07D2:0000039F呼叫20EF:0434