thumb2 是 thumb 指令集的扩展,以前是未定义的指令,现在其中一些已定义。arm 是一个完全不同的指令集。如果工具链没有给你留下关于什么代码是 thumb vs arm 的线索,那么弄清楚它的唯一方法是从入口点的假设开始,然后从那里按执行顺序反汇编,即使在那里你也可能不知道一些的代码。
您无法仅通过位模式将 arm 指令与 thumb 或 thumb+thumb2 扩展区分开来。还要记住 arm 指令在 4 字节边界上对齐,其中 thumb 是 2 字节,而 thumb 2 扩展不必与其父 thumb 处于相同的 4 字节边界,这使得这一切变得更加有趣。(thumb+thumb2 是由 16 位值的倍数组成的可变长度指令集)
如果您的所有代码都是拇指并且其中没有 arm 指令,那么您仍然会遇到可变长度指令集的问题,并且要正确执行,您必须按执行顺序遍历代码。例如,在 .text 中嵌入一个看起来像 thumb2 扩展的前半部分的数据值并不难,然后是一个真正的 thumb 2 扩展,导致你的反汇编程序脱轨。基本的可变字长反汇编问题(以及击败简单反汇编程序的基本方法)。
16 位字 A、B、C、D
如果 C + D 是通过解码 C 已知的拇指 2 指令,A 是拇指指令,B 是类似于拇指 2 扩展的前半部分的数据值,然后通过 ram A 线性解码是拇指指令 B 和 C被解码为 thumb2 扩展,而实际上是 thumb2 扩展的后半部分的 D 现在被解码为指令的前 16 位,并且所有关于它如何解码或者它是否会导致以下所有或许多指令的赌注都已关闭被解码错误。
所以开始看看精灵是否告诉你一些事情,如果没有,那么你必须按照执行顺序通过代码(你必须对入口点做出假设)遵循所有可能的分支和线性执行来标记16 位部分作为指令的第一个或附加块,未标记的块不一定确定为指令与数据,必须小心。
是的,可以玩其他游戏来击败反汇编程序,故意分支到 thumb2 指令的后半部分,该指令是手工制作的有效拇指指令或拇指 2 的开始。
固定长度的指令集,如 arm 和 mips,您可以线性解码,一些数据解码为奇怪或未定义的指令,但您的反汇编程序不会偏离轨道并且无法完成其工作。可变长度指令集,反汇编充其量只是一个猜测......真正解码的唯一方法是像处理器一样执行指令。