我正在试图拆解一个ELF可执行文件,我使用arm-linux-gnueabihf编译了这个可执行文件,以针对thumb-2。然而,ARM指令编码使我在调试反汇编程序时感到困惑。让我们考虑以下说明:
mov.w fp,#0
我用objdump和hopper作为拇指-2指令进行分解。指令以4ff0000b的形式出现在内存中,这意味着它实际上是0b00f04f(小endian)。因此,指令的二进制编码是:
0000 1011 0000 1111 0000 0100 1111
根据ARM架构手册,似乎所有的拇指-2指令应该从111[10|01|11]开始.因此,上述编码不对应于任何拇指-2指令.此外,它与A8.8.102节(第484页)中的任何编码都不匹配。
我是不是遗漏了什么?
发布于 2015-10-08 16:45:44
我认为你忽略了宽拇指-2编码不是像ARM编码那样的32位字的微妙区别,它们是一对16位半字(注意ARM编码图上方的位号)。因此,虽然半字本身是小的,他们仍然存储在‘正常’的顺序相对于彼此。如果内存中的字节是4ff0000b,那么实际编码的指令是f04f 0b00。
发布于 2015-10-08 19:04:10
thumb2是拇指指令集的扩展,以前是未定义的指令,现在已经定义了其中的一些指令。arm是一个完全不同的指令集。如果工具链没有给您留下关于什么代码是拇指代码和arm代码的线索,那么解决它的唯一方法就是从入口点的假设开始,然后从那里开始按执行顺序分解,即使在那里,您也可能找不出其中的一些代码。
您不能简单地通过位模式将arm指令与拇指或thumb+thumb2扩展区分开来。还请记住,arm指令是在4字节的边界上对齐的,其中拇指是2字节,而拇指2扩展不需要与其父拇指处于相同的4字节边界中,这使得这一切变得更加有趣。(thumb+thumb2是由16位值的倍数组成的可变长度指令集)
如果您的所有代码都是大拇指,并且没有arm指令,那么您仍然会遇到可变长度指令集的问题,要正确地执行,您必须按照执行顺序执行代码。例如,在.text中嵌入一个类似于thumb2扩展的前半部分的数据值并不困难,然后用一个真正的拇指2扩展来执行,这会导致反汇编程序偏离轨道。基本变量字长反汇编问题(以及击败简单反汇编程序的基本方法)。
16位字A,B,C,D
如果C +D是解码C所知的拇指2指令,则说A是拇指指令,B是类似于thumb2扩展的前半部分的数据值,则通过ram A线性解码的是拇指指令B和C被解码为thumb2扩展,而实际上是thumb2扩展的后半部分的D现在被解码为指令的前16位,并且所有的赌注都被排除在如何解码或是否导致以下所有或多个指令被解码错误。
因此,首先看看精灵是否告诉了你什么,如果没有,那么您必须按照执行顺序遍历代码(您必须对入口点做一个假设),在所有可能的分支和线性执行之后,将16位段标记为指令的第一个或附加块,不一定要将未标记的块确定为指令与数据,必须小心。
是的,可以玩其他游戏来击败反汇编器,故意将分支到thumb2指令的后半部分,该指令是手工制作的,是有效的拇指指令或thumb2的命令。
固定长度的指令集,如arm和mips,您可以线性解码,一些数据解码为奇怪的或未定义的指令,但您的反汇编程序不会偏离轨道,不能完成它的工作。可变长度指令集,反汇编充其量不过是guess...the真正解码的唯一方法,就是按照处理器的方式执行指令。
https://stackoverflow.com/questions/33021393
复制相似问题