1

I am looking at an unstripped ARM elf firmware file using IDA Pro. There is an init() function and a main() function. From my understanding of the logic, it's probably structured like this:

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

or the main() itself contains a super loop. However, the strange things are 1) I am not able to find any calling references for the main(). 2) Nor can I identify a super loop structure inside main().

The main() is like this:

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

The init() is like this (directly following main()):

  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 are line numbers added by myself here for easier explanation.

First off, IDA Pro shows "Three are no refs to main()" when using "Jumps to xrefs to operand..." function. And line A2 is the only place in the whole firmware disassembly that references main(). However , it put address main+1 to R0 which I don't understand. It looks like R0 is not used after jumping to RN_end_of_main, and the init() will just return using the originally pushed LR which will go nowhere.

Anything missing in my understanding of this code? And is there some hidden way that main() can be called?

  • What about the caller of init()? Is there any code after calling init()? – Igor Skochinsky Apr 21 '14 at 22:47
  • What does the entry point (e_entry) field of the ELF header show? Perhaps it is main, and some external piece of code (like a bootloader, or linker/loader) is calling it? – Jonathon Reinhart Apr 21 '14 at 22:59
  • @IgorSkochinsky No. There's no further code after init() returns, just some data there. – Penghe Geng Apr 21 '14 at 23:28
  • @JonathonReinhart Using objdump, I can see the start address is 0x10000, which just puts CPU in user mode and BX to init(). The following code after BX is some data – Penghe Geng Apr 21 '14 at 23:32
  • I would then go about searching for the address of main. – Jonathon Reinhart Apr 21 '14 at 23:35
3

Finally I think I might have one explanation for this.

The ARM elf format firmware file is further converted to a hex bin file which is used by the boot loader to program into the on board flash. So my speculation is that both init and main probably are actually called by the boot loader code.

This speculation is possible because the elf file is still fully relocatable. The elf-->bin step might do a relocation process to make it callable by the already-present bootloader.

With this speculation, the init function doesn't call the main actually. Both just are called and returned normally by the bootloader.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.