我需要想出一些通配符来匹配某些指令。
例如,在 x86 上,要匹配大多数 CALL 指令,以下模式就足够了:
E8 ?? ?? ?? ??
其中E8是操作码,接下来的 4 个字节是要跳转到的相对地址。
但是arm64的操作码,特别是A64指令集似乎更令人困惑,比如,我有这两个指令:
0A696938 ldrb w10, [x8, x9] ;
EB834039 ldrb w11, [sp, #0xc0 + var_A0]
如果您只查看编码0A696938和EB834039,则没有明显的关系。如何获取此ldrb指令的操作码以创建类似于 x86 的模式?
感觉操作码不像 x86 那样占用整个字节
没错,ARM64 指令编码方案比 x86 上复杂得多。事实上,操作码并不总是在同一个字节中找到,甚至不是在同一组位中找到,甚至也不是在 32 位指令字中的连续位组中找到。
指令编码规则在 Armv8-A 架构参考手册的 C4 章中定义,当您观察到本章长达 328 页时,它会让您对所面临的情况有所了解。然而,如果您只是想识别某些特定的指令或指令类别,那可能还不错。有一个粗略的层次分组。例如,所有分支指令的位 26-28 均为 101。如果另外位 29-30 为 00,则它是到立即地址的无条件分支。如果另外位 31 为 1,则它是 BL。
100101
因此,在 x86 上查找操作码 E8 的等效方法是在指令字的第 26-31 位中查找。其他一些团体则更难。例如,所有加载和存储的位 27 中为 1,位 25 中为 0,但操作码的其余部分分散在位 10-11、16-21、23-24、26 和 28-31 中。
如果您需要更广泛地识别指令而不仅仅是识别几个特定的指令,您可能需要使用现有的反汇编库,例如Capstone。