我已经老嵌入式系统,采用ARM CPU内核,我甩ROM,用binwalk提取,并加载IDA亲。我在一些例行程序找到,BX不与LR但通用寄存器(R2,R3等)中的伪代码变得像一些这种“记忆[0xCC1232](A3,V4)”这是示例。我认为它像ARM编译器编译C指针功能。会是什么?反正我的主要问题是,我怎么能找到这个子程序(memoryx ..)只有ROM转储?因为地址RAM地址,所以无需RAM转储,我无法找到参考这个子程序?我以为找到常规该值写入这个特定的地址,但它几乎是不可能谢谢
这取决于编译器设置和什么核心对象而定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。
在一般情况下,无法确定实际的跳转地址,而无需拆卸和分析代码。然而,一些技巧和窍门是可能的。
BX LR
结束。您只需通过扫描ROM找到全部或大部分子程序的入口点,怀疑切入点下一子程序旁边之前的“BX LR”。要确定具体的子程序被称为间接地尝试,如果它的平原地址在ROM中存在的地方进行搜索,或者装载有“MOVW” +“MOVT”对。这让你知道它在哪儿可以使用。从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: