我正在对使用Z80处理器的嵌入式系统进行逆向工程。我正在使用IDA作为反汇编程序。我遇到了绝对跳转(JP),似乎跳到了另一条指令的中间。我未定义目标位置并将其重新定义为代码,并且将其分解为有效的指令,但它们似乎无能为力。我想知道我是否可以从中获得帮助,或者是否忽略了某些内容。

源+ Bin + IDB文件可在此处找到

跳转代码:



IDA跳转目标自动反汇编:



在未定义和重新定义121代码后跳转目标:



评论

嗨,欢迎来到RE.SE。请张贴相关代码作为实际文本。这将确保可以对其进行搜索。图片很难搜索关键字。谢谢。

#1 楼

没有任何上下文,我们只能猜测...

但是jp (hl)通常用于:



跳转到指针

/>这很明显hl指向您要跳转到的存储位置。您可以用这种方法做很多事情,例如,您想决定如何处理一些输入,并且有更多的处理程序选择,因此您可以评估要在hl中使用的处理程序,最后直接跳转到它。程序的mode也是如此...例如,您有了更多呈现文本或其他内容的方式,并且想要在整个程序之间轻松地在它们之间进行切换...然后只需将所选例程存储在某个指针中,并在需要时跳转至它...

我的代码没有任何上下文,但这是最可能的情况:

286Eh是选定的模式处理程序,hl使用ix读取了该位置最后例行跳转。我猜最后一个ret在例程的某个位置。


使用非标准调用约定调用/返回子例程/从子例程返回/有时操作数会传递给子例程以非标准方式(不在堆栈上)以防止直接使用callret。在这种情况下,jp (hl)可以解决此类问题。

例如查看以下x86示例:


装配体8086中的图形模式

printl会在调用后直接期待打印的字符串...使用它的地方(不在数据部分的某些表中)也不需要标签。如您所见,printl无法直接返回到堆栈中存储的地址。取而代之的是,它需要跳转到jp (hl)示例的理想用法之后的文本后面(但是由于指令集不同,我的x86代码也会有所不同)。 >
可配置程序没有静态跳转/调用地址,因此jp (hl)可用于可配置跳转...


现在回到跳转到指令中间

这可能是正确的,也可能不是。如果使用反汇编程序,则它不知道每个代码段的ORG语句在哪里。因此,它从文件开头开始翻译。当您进行跟踪时,它将PC作为起始位置并进行相对转换,因此如果滚动列表,则可能会错误地反汇编其他代码部分。但是,在执行了几个连续的单字节指令之后,代码又重新对齐了,因此大多数代码将被正确翻译。有时,对时间敏感的代码需要一定数量的[T]指令来花在某些例程上,而在某些指令中间跳转可以解决某些条件行为后丢失的[T]状态。

评论


在这种情况下,它是#2场景,该跳转位于没有返回指令的子例程中。我应该在原始帖子中做更好的解释,但是28e6包含一个内存地址,其中包含另一个内存地址,解析为0121h。 0121h是跳转目标,位于另一条指令的中间。我在上面附加了代码和IDB文件作为上下文。

– Zman37
19年1月14日在22:06

@ Zman37我没有自己的模拟器,没有Z80反汇编程序,并且懒得将其转换为一个。无论如何,我指的是设备的用途,体系结构,ROM和RAM的存储位置是什么?正如我提到的那样,代码很有可能应在121h而不是11Fh开始,这可能只是从已知开始线性转换的原因,因此最后一个列表是有效的。无论如何,如果28E6和/或28D3在RAM中并且您的清单没有跟踪自我修改更改(我不知道IDA),您也可能会忽略自我修改,因此跳转地址可能会有所不同

– Spektre
19年1月15日在8:25



@ Zman37错误的代码启动通常是由例程之间的数据段引起的(反汇编程序无法区分哪些BYTES是数据以及哪些指令,除非至少执行了一次),有时会使用ORG指令,因此例程和/或数据位于特定位置和/或对齐以启用更简单的数学运算或由于硬件关系...

– Spektre
19年1月15日在8:28