【问题标题】:What kind of C code can be compiled into assembly code like "LDR R3,[R4,#0x18]", where R3 is a pointer什么样的C代码可以编译成像“LDR R3,[R4,#0x18]”这样的汇编代码,其中R3是一个指针
【发布时间】:2021-02-18 18:52:57
【问题描述】:

我用 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 SUBS 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 R3,[R4,#0x18]) 处的 LDR 指令。

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

【问题讨论】:

  • 结构外的函数指针
  • 谢谢。结构中确实包含函数指针。

标签: arm reverse-engineering ida


【解决方案1】:
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

只需要它想要使用基址加偏移寻址来读取函数的地址然后调用它。 blx 进行调用,因此值是函数指针,因此代码与函数指针相关。如果没有该结构,它可能不会执行 base + offset 而是执行 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 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

链接器填充直接偏移量,因此没有寄存器加偏移量寻址。根本没有ldr,因为可以用分支链接处理。

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

【讨论】:

  • 请注意这里的拼写,尤其是包含撇号的单词。以下是一些正确的拼写,以及您的帖子历史记录中的拼写错误数量:不要 (765)、不要 (488)、不能 (306)、不会 (217)、不是 (148) .这里对不以英语为第一语言的人有一定的容忍度,但文体和故意拼写错误违背了网站的目标,并且是为志愿编辑特意做的大量工作。您的浏览器中有拼写检查器吗?
猜你喜欢
  • 2015-01-31
  • 2019-02-27
  • 2019-09-09
  • 1970-01-01
  • 2017-07-05
  • 2021-07-18
  • 1970-01-01
  • 2014-11-08
  • 1970-01-01
相关资源
最近更新 更多