无意义的反汇编 ARM 指令

逆向工程 艾达 手臂
2021-07-05 12:47:23

我一直在跟踪我的二进制文件并将其转换为 C 代码,以便我可以轻松理解它。当我浏览指令和函数时,我不断发现没有意义的代码。例如:

ROM:080004B8                 CMNNE.W         R4, #1
ROM:080004BC                 BEQ.W           loc_80007DE

此代码永远不会分支。另一个例子:

STRB.W          R0, [SP,#0x18+var_18] @ where var_18 is -0x18

这类似于在 C 中索引数组,如“array[5-5]”。为什么会这样?这是反汇编吗?一种试图让我感到沮丧的混淆代码形式?一个糟糕的编译器?

1个回答

扩展 Rad Lexus 的评论,它很好地描述了情况,但如果没有示例可能无法理解:

在函数中,堆栈指针在大多数情况下不是常量。当函数/方法/子例程的参数被推送时,当程序员使用诸如 之类的东西alloca以及其他原因时,它可能会发生变化,具体取决于编译器和处理器。

这使得跟踪参数和局部变量的位置变得非常困难。例如,类似的代码f(i++)可能会导致类似的结果

mov r0, [sp, #8]     ; read the variable
mov [sp], r0          ; put it on the argument stack
sub sp, sp, #4        ; adjust the stack pointer
add r0, r0, #1        ; calculate the ++
mov [sp, #12], r0    ; write back result

这是一个使更改sp可见的版本通常,该更改将隐藏在类似stmfd sp!, {r0}

在这种情况下,很难看到“读取”和“写入”操作访问内存中的相同地址而sp值已更改。

这就是像 IDA 这样的反编译器为这些位置分配名称的原因 - 作为示例,让我们假设在我的示例中变量的命名var_4值为 4。

现在 IDA 可以发出

mov r0, [sp, var_4+#4]     ; read the variable
mov [sp, var_4+#8], r0     ; write back result

var_4在“相同的变量”,并且暗示#4/#8在从偏移[sp],需要被加入到var_4在每一种情况下。