我正在对使用 Z80 处理器的嵌入式系统进行逆向工程。我使用 IDA 作为反汇编程序。我遇到了一个绝对跳转 (JP),它似乎跳转到另一条指令的中间。我未定义并将目标位置重新定义为代码,并将其反汇编为有效指令,但它们似乎没有做任何事情。我想知道我是否可以得到一些帮助来理解这一点,或者我是否忽略了一些东西。
编辑:此跳转是循环的退出点。
源 + Bin + IDB 文件可以在这里找到
跳转代码:
使用 IDA 自动反汇编跳转目标:
将121取消定义并重新定义为代码后跳转目标:
我正在对使用 Z80 处理器的嵌入式系统进行逆向工程。我使用 IDA 作为反汇编程序。我遇到了一个绝对跳转 (JP),它似乎跳转到另一条指令的中间。我未定义并将目标位置重新定义为代码,并将其反汇编为有效指令,但它们似乎没有做任何事情。我想知道我是否可以得到一些帮助来理解这一点,或者我是否忽略了一些东西。
编辑:此跳转是循环的退出点。
源 + Bin + IDB 文件可以在这里找到
跳转代码:
使用 IDA 自动反汇编跳转目标:
将121取消定义并重新定义为代码后跳转目标:
没有任何背景,我们只能猜测......
但是jp (hl)
通常用于:
跳转到指针
这很明显hl
指向您要跳转到的内存位置。你可以用它做很多事情,例如你想决定如何处理一些输入,你有更多的处理程序选择,所以你可以评估使用哪个,hl
最后直接跳转到它。这同样适用于mode
程序的......例如你有渲染文本或某事的更多的方式,你想轻松地对整个方案在两者之间切换...然后简单地存储在某些指针所选择的程序,需要跳转到它时, ...
我对您的代码没有任何上下文,但这是最有可能的情况:
286Eh
是选定的模式处理程序,使用hl
读取该位置ix
并最后例行跳转到该位置。我猜决赛ret
在某个地方的例行公事中。
使用非标准调用约定调用/返回到/从子例程
有时操作数以非标准方式(不在堆栈上)传递给子程序,这会阻止使用call
或ret
直接使用。在这种情况下jp (hl)
可以解决此类问题。
例如,看看这个 x86 示例:
在printl
呼叫之后直接期待打印字符串......
call printl
db 'SPEKTRA software & hardware',0
这节省了输入数据指针设置,而且它更舒适,因为打印文本直接使用它(不在数据部分的某些表中),而且您不需要标签。如您所见,printl
无法直接返回存储在堆栈中的地址。相反,它需要在文本之后跳转,这是jp (hl)
示例的理想用法(但是我的 x86 代码由于不同的指令集而有所不同)。
解决自修改代码问题
可配置程序没有静态跳转/调用地址,因此jp (hl)
可用于可配置跳转...
现在回到跳到教学中间
这可能是也可能不是。如果您使用反汇编程序,则它不知道ORG
每个代码段的语句在哪里。所以它从文件的开头开始翻译。当您进行跟踪时,它将PC
作为起始位置并从中进行相对转换,因此如果您滚动列表,您可能会错误地反汇编代码的其他部分。然而,在几个连续的单字节指令之后,代码再次对齐,因此大部分代码将被正确翻译。
但也有我们故意跳到教学中间的情况。有时,时间敏感的代码需要[T]
在某些例程上花费确切数量的节拍,并且在某些指令中间跳转可以解决[T]
某些条件行为后丢失的状态。
实际上,JP (HL) 用词不当;它不会跳转到 (HL) 但它会跳转到 HL。代码跳转到 28D3,其中包含一个 21(LD HL,imm),这完全有道理。