Arm 什么样的C代码可以编译成汇编代码,比如;LDR R3,[R4,#0x18],“;,其中R3是指针

Arm 什么样的C代码可以编译成汇编代码,比如;LDR R3,[R4,#0x18],“;,其中R3是指针,arm,reverse-engineering,ida,Arm,Reverse Engineering,Ida,我用IDA Pro反转了一个ARM固件;部分汇编代码如下所示: ROM:08079B00 MOVS R1,R0 ROM:08079B02 BEQ loc_8079B14 ROM:08079B04 LDR R0[R4,#0x10] ROM:08079B06 LDR R2[R1,#4] ROM:08079B08接头R0,R0,#3 ROM:08079B0A STRH R0[R2,#0x10] ROM:08079B0C LDR R3[R4,#0x18] ROM:08079B0E LDR R2[R4

我用IDA Pro反转了一个ARM固件;部分汇编代码如下所示:


ROM:08079B00 MOVS R1,R0

ROM:08079B02 BEQ loc_8079B14

ROM:08079B04 LDR R0[R4,#0x10]

ROM:08079B06 LDR R2[R1,#4]

ROM:08079B08接头R0,R0,#3

ROM:08079B0A STRH R0[R2,#0x10]

ROM:08079B0C LDR R3[R4,#0x18]

ROM:08079B0E LDR R2[R4,#0x20]

ROM:08079B10 LDR R0[R5]

ROM:08079B12 BLX R3


偏移量0x08079B12处的指令是BLX R3,因此R3是指针;R3的值来自偏移量0x08079B0C处的LDR指令(LDR R3,[R4,#0x18])

什么样的C代码可以编译成汇编代码,如“LDR R3,[R4,#0x18]”,其中R3是指针。

typedef int(*fun)(int a,int b);
typedef   int (*fun)(int a , int b );
typedef  struct _str 
{
       int a;
       int b;
       fun op;
} STR;
STR funop;
int fun2 ( int a, int b)
{
    funop.a=a;
    funop.b=b;
    return(funop.op(a,b)+1);
}


00000000 <fun2>:
   0:   e59f3014    ldr r3, [pc, #20]   ; 1c <fun2+0x1c>
   4:   e92d4010    push    {r4, lr}
   8:   e5932008    ldr r2, [r3, #8]
   c:   e8830003    stm r3, {r0, r1}
  10:   e12fff32    blx r2
  14:   e2800001    add r0, r0, #1
  18:   e8bd8010    pop {r4, pc}
  1c:   00000000
类型定义结构 { INTA; int b; 趣味op; }STR; STR-funop; int fun2(int a,int b) { funop.a=a; funop.b=b; 返回(funop.op(a,b)+1); } 00000000 : 0:e59f3014 ldr r3[pc,#20];1c 4:e92d4010推送{r4,lr} 8:e5932008 ldr r2[r3,#8] c:e8830003 stm r3,{r0,r1} 10:E12FF32 blx r2 14:e2800001加上r0,r0,#1 18:e8bd8010 pop{r4,pc} 1c:00000000
只需要使用基址加偏移地址来读取函数的地址,然后调用它。blx执行调用,因此值是函数指针,因此代码与函数指针相关。如果没有结构,它可能不会执行基本+偏移,而是执行pc相对负载

它不一定是全球性的

int (*fun)(int a , int b );
int fun2 ( int a, int b)
{
    return((fun)(a,b)+1);
}
00000000 <fun2>:
   0:   e59f3018    ldr r3, [pc, #24]   ; 20 <fun2+0x20>
   4:   e92d4010    push    {r4, lr}
   8:   e5933000    ldr r3, [r3]
   c:   e1a0e00f    mov lr, pc
  10:   e12fff13    bx  r3
  14:   e8bd4010    pop {r4, lr}
  18:   e2800001    add r0, r0, #1
  1c:   e12fff1e    bx  lr
  20:   00000000    .word   0x00000000
int(*fun)(int a,int b);
int fun2(int a,int b)
{
返回((乐趣)(a、b)+1);
}
00000000 :
0:e59f3018 ldr r3,[pc,#24];20
4:e92d4010推送{r4,lr}
8:e5933000 ldr r3[r3]
c:e1a0e00f mov lr,pc
10:E12FF13 bx r3
14:e8bd4010 pop{r4,lr}
18:e2800001加上r0,r0,#1
1c:E12FF1E bx lr
20:00000000。字0x00000000
因为我使它是全局的,所以它必须做双间接的事情,所以它仍然是一个基数加偏移量(零)

intfun3(inta,intb);
int fun2(int a,int b)
{
内部(*fun)(内部a、内部b);
乐趣=乐趣3;
返回((乐趣)(a、b)+1);
}
00000000 :
0:e92d4010推送{r4,lr}
4:ebfffffe bl 0
8:e8bd4010 pop{r4,lr}
c:e2800001加上r0,r0,#1
10:E12FF1E bx lr
链接器填充直接偏移量,因此没有寄存器加偏移量寻址。根本没有ldr,因为它可以通过分支链接处理


我认为这些是在链接时解析的bl或在链接时解析的池值的双重间接选择。无论是否为结构,它都是一个带有寄存器加偏移量的ldr(如果为零,gnu反汇编程序不显示偏移量)。

函数指针指向结构谢谢。确实,该结构包含函数指针。请注意此处的拼写,尤其是包含撇号的单词。这里有一些正确的拼写,加上你的帖子历史记录中的拼写错误:不(765),不(488),不能(306),不会(217),不是(148)。对于那些没有英语作为第一语言的人来说,这里有一些宽容,但是文体和故意拼错的作品违背了网站的目标,并且是故意为志愿编辑做的大量工作。您的浏览器中有拼写检查程序吗?
int fun3(int a , int b );
int fun2 ( int a, int b)
{
    int (*fun)(int a , int b );
    fun=fun3;
    return((fun)(a,b)+1);
}

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