简体   繁体   中英

ARM reverse engineering ROM dump

I ve old embedded system, with ARM cpu core, I dumped ROM, extracted with binwalk, and loaded on IDA pro. I found in some routine routine, BX not with LR but with general purpose register(R2, R3 etc..)in pseudo code became like some this "memory[0xCC1232](a3, v4)" it is example. I thought that it is like ARM compiler build C pointer function. could it be? Anyway my main question is this, how can I found this subroutine (memoryx..)with only rom dump?because the address is ram address, so without ram dump, can't I find reference to this subroutine?I thought to find routine that write value to this particular address, but it is almost impossible thank you

depending on the compiler settings and what core is being targetted bx with out lr is very common, if not required as the older cores pop (ldmia usually) of lr does not work for switching between arm and thumb modes so the compilers will generate pop to like r3 then bx r3.

extern unsigned int more_fun ( void );
unsigned int fun ( void )
{
    return(more_fun()+1);
}

00000000 <fun>:
   0:   b510        push    {r4, lr}
   2:   f7ff fffe   bl  0 <more_fun>
   6:   3001        adds    r0, #1
   8:   bc10        pop {r4}
   a:   bc02        pop {r1}
   c:   4708        bx  r1
   e:   46c0        nop         ; (mov r8, r8)

vs

00000000 <fun>:
   0:   b508        push    {r3, lr}
   2:   f7ff fffe   bl  0 <more_fun>
   6:   3001        adds    r0, #1
   8:   bd08        pop {r3, pc}
   a:   bf00        nop

r4 vs r3 as the dummy register doesnt matter here, it is interesting that the compiler does this, but they are just being used to make the stack aligned, not to preserve the register.

this is thumb mode of course, arm mode

00000000 <fun>:
   0:   e92d4010    push    {r4, lr}
   4:   ebfffffe    bl  0 <more_fun>
   8:   e8bd4010    pop {r4, lr}
   c:   e2800001    add r0, r0, #1
  10:   e12fff1e    bx  lr

you would expect to see lr used with a bx lr

or this for newer, but gcc at least defaults to thumb mode and you have to force it to generate arm code like this

00000000 <fun>:
   0:   e92d4010    push    {r4, lr}
   4:   ebfffffe    bl  0 <more_fun>
   8:   e2800001    add r0, r0, #1
   c:   e8bd8010    pop {r4, pc}

As far as finding what is in ram you have to do more work and it might not be possible. if this is an embedded system and everything is in non-volatile memory (flash/rom/etc) then at some point if code is in ram then it is copied or decompressed or other into ram before being branched to. On the other hand you may have disassembled some code that is there to be able to call code in ram but that code in ram may come from a download, basically some external source that is not ultimately on board/chip. Like a bootloader that has code to download a program over the uart and then branch to it, doesnt mean that code is used normally and certainly means you cant predict or know what that code is going to be, much less find it and disassemble it.

A bx of not lr can be used by hand to launch into such code if I download into 0x20000000 and somehow know this is thumb code not arm then I need to orr the address with a 1 in some way then bx to that, sometimes you do that with a register, sometimes not.

you will also see a bx used by the linker to patch up something far away or for changing modes:

unsigned int more_fun ( void )
{
    return(3);
}

the linker adds the trampoline for you:

00000000 <fun>:
   0:   e92d4010    push    {r4, lr}
   4:   eb000003    bl  18 <__more_fun_from_arm>
   8:   e8bd4010    pop {r4, lr}
   c:   e2800001    add r0, r0, #1
  10:   e12fff1e    bx  lr

00000014 <more_fun>:
  14:   2003        movs    r0, #3
  16:   4770        bx  lr

00000018 <__more_fun_from_arm>:
  18:   e59fc000    ldr r12, [pc]   ; 20 <__more_fun_from_arm+0x8>
  1c:   e12fff1c    bx  r12
  20:   00000015    andeq   r0, r0, r5, lsl r0
  24:   00000000    andeq   r0, r0, r0

and in this case used r12.

In general case, it is not possible to determine actual jump address without disassembling and analysing code. However, several tips and tricks are possible.

  1. Very often part of ROM is copied to RAM at very early startup. Try to find that copy routine in initialisation. If you're lucky, you'll be able initial contents of RAM location you're interested in. And if you're very lucky, that location is not rewritten in runtime, and it will be actual data. (See below)
  2. Try to disassemble portion of code before. In most cases address is fetched from some table in ROM then stored in local variable, and address of that table is there.
  3. In most cases subroutine code bodies reside at start of ROM back to back, starting with entry point and ended with BX LR . You can find all or most subroutine entry points just by scanning through ROM, suspecting that entry point to next subroutine is next to 'BX LR' of previous. To determine if specific subroutine is called indirectly try to search if its plain address exist somewhere in ROM, or it is loaded with 'MOVW'+'MOVT' pair. This give you idea where it may be used.
  4. In several cases subroutine address is passed as a parameter to subroutine call. So try to search if any caller is referring to some address in code.
  5. There could be procedure tables, looking like long runs of words pointing to ROM code area (possibly interleaved with nulls). Try to find them and determine which one could be used in your case.

An example RAM initialisation code taken from GNAT's runtime:

        movw    r0,#:lower16:__data_start ; __data_start points to RAM
        movt    r0,#:upper16:__data_start ; (often it is start of RAM)
        movw    r1,#:lower16:__data_words
        movw    r2,#:lower16:__data_load  ; __data_load points to ROM
        movt    r2,#:upper16:__data_load  ; right after code and readonly data
        cbz     r1,1f
0:      ldr     r4,[r2],#4
        str     r4,[r0],#4
        subs    r1,r1,#1
        bne     0b
1:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM