在反汇编的固件中找不到主函数的调用者

逆向工程 艾达 拆卸 二元分析 手臂
2021-06-21 13:35:33

我正在使用 IDA Pro 查看未剥离的 ARM elf 固件文件。有一个init()功能和一个main()功能。根据我对逻辑的理解,它的结构可能是这样的:

init()
while (1) {
   main();  
}

或者main()本身包含一个超级循环。但是,奇怪的是 1) 我找不到main(). 2)我也无法识别main().里面的超级循环结构

main()是这样的:

  B1: PUSH    {R3-R7,LR}
  ...
RN_end_of_main:
  B2: POP     {R3-R7}
  B3: POP     {R3}
  B4: BX      R3
  (end of main)

init()是这样的(直接以下主要()):

  A1: PUSH    {R3-R7,LR}
      ...
  A2: LDR     R0, main+1    # This is the only place that references main()
  A3: B       RN_end_of_main
  (end of init)
  (data)

A1, A2, .. B3 是我自己在这里添加的行号,以便于解释。

首先,当使用“跳转到外部参照到操作数...”函数时,IDA Pro 显示“三个没有对 main() 的引用”。而A2行是整个固件拆解中唯一引用的地方main()然而,它把地址main+1R0我听不懂。R0跳转到 后好像没有使用RN_end_of_maininit()只会使用原来推送的返回LR, 不会去任何地方。

我对这段代码的理解有什么遗漏吗?是否有一些main()可以调用的隐藏方式

1个回答

最后,我想我可能对此有一个解释。

ARM elf 格式的固件文件被进一步转换为十六进制 bin 文件,引导加载程序使用它来编程到板载闪存中。所以我的猜测是,无论initmain可能实际上是由引导加载程序代码调用。

这种推测是可能的,因为 elf 文件仍然是完全可重定位的。elf-->bin 步骤可能会执行重定位过程,以使其可被已经存在的引导加载程序调用。

有了这种推测,该init函数main实际上并没有调用两者都只是由引导加载程序正常调用和返回。