ARM逆向工程ROM转储

问题描述 投票:0回答:2

我已经老嵌入式系统,采用ARM CPU内核,我甩ROM,用binwalk提取,并加载IDA亲。我在一些例行程序找到,BX不与LR但通用寄存器(R2,R3等)中的伪代码变得像一些这种“记忆[0xCC1232](A3,V4)”这是示例。我认为它像ARM编译器编译C指针功能。会是什么?反正我的主要问题是,我怎么能找到这个子程序(memoryx ..)只有ROM转储?因为地址RAM地址,所以无需RAM转储,我无法找到参考这个子程序?我以为找到常规该值写入这个特定的地址,但它几乎是不可能谢谢

c pointers arm reverse rom
2个回答
1
投票

这取决于编译器设置和什么核心对象而定BX用了LR是很常见的,如果不需要,因为LR的较旧的核心POP(LDMIA通常)为ARM和Thumb模式之间进行切换,因此编译器会生成弹出来不工作像R3则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作为虚拟寄存器不事关在这里,有趣的是,编译器这样做,但他们只是被用来做堆栈对齐,不保存寄存器。

这当然是拇指模式,臂模式

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

你希望看到一个BX LR使用LR

这或为较新的,但GCC至少默认为拇指模式,你必须迫使它产生这样的ARM代码

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

至于找到你所拥有的是在RAM中做更多的工作,它可能是不可能的。如果这是一个嵌入式系统,一切都在非易失性存储器(闪存/ ROM /等),然后在某一时刻,如果代码是在RAM中。然后它被复制或者被分支到之前解压缩或其他到RAM中。在另一方面,你可能已经拆解了一些代码,那里能够调用的代码在内存中,但在RAM中的代码可能来自下载,基本上不是最终对板/片的一些外部源。正如那代码下载一个程序在UART,然后跳转到它,并不意味着这些代码被正常使用,当然意味着你不能预测或者知道是什么代码将是,更不用说找到它,并拆解引导程序。

没有LR的BX可以用手使用,如果我下载到0x20000000发射到这样的代码,不知怎么知道这是Thumb代码武装不了那么我就需要ORR以某种方式1的地址,然后BX到,有时你做与寄存器,有时没有。

你还会看到使用的连接器修补的东西远或改变模式的BX:

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

链接器增加了蹦床为您提供:

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

在这种情况下使用R12。


0
投票

在一般情况下,无法确定实际的跳转地址,而无需拆卸和分析代码。然而,一些技巧和窍门是可能的。

  1. 很多时候ROM的一部分是在非常早期启动复制到RAM中。试图找到初始化该副本程序。如果幸运的话,你会你感兴趣的RAM位置能够初始内容。如果你很幸运,那个位置是不是在运行时改写,这将是实际数据。 (见下文)
  2. 尝试之前拆卸的代码部分。在大多数情况下,地址取得从ROM一些表,然后存储在本地变量,并且该表的地址是存在的。
  3. 在大多数情况下,子程序代码机构驻留在ROM背靠背,从入口点开始,并与BX LR结束。您只需通过扫描ROM找到全部或大部分子程序的入口点,怀疑切入点下一子程序旁边之前的“BX LR”。要确定具体的子程序被称为间接地尝试,如果它的平原地址在ROM中存在的地方进行搜索,或者装载有“MOVW” +“MOVT”对。这让你知道它在哪儿可以使用。
  4. 在一些情况下子程序地址作为参数调用子程序传递。因此,尝试,如果任何调用方指的是一些地址代码进行搜索。
  5. 有可能是程序表,看起来像指着ROM代码区域(可能与空交错)字样的长期运行。试着找到他们,并确定哪些人可以在你的情况下使用。

从GNAT的运行时抽取的RAM初始化代码:

        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:
© www.soinside.com 2019 - 2024. All rights reserved.