如何解决什么样的C代码可以编译成汇编代码,例如“ LDR R3,[R4,#0x18]”,其中R3是指针
我使用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指令(LDR R3,[R4,#0x18])。
什么样的C代码可以编译成汇编代码,例如“ LDR R3,[R4,#0x18]”,其中R3是指针。
解决方法
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进行了调用,因此该值是函数指针,因此代码与函数指针相关。没有该结构,它可能不会做基数+偏移量,而是做pc相对负载。
不一定必须是全局的。
int (*fun)(int a,int b );
int fun2 ( int a,int b)
{
return((fun)(a,b)+1);
}
00000000 <fun2>:
0: e59f3018 ldr r3,#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,#1
1c: e12fff1e bx lr
20: 00000000 .word 0x00000000
因为我将其设置为全局,所以必须执行两次间接操作,因此它仍然是基数加偏移量(零)。
int fun3(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,#1
10: e12fff1e bx lr
链接器填写直接偏移量,因此无需寄存器加上偏移量寻址。根本没有ldr,因为它可以通过分支链接进行处理。
我认为这些是在链接时要解决的bl或在链接时要解决的池值的双间接选择。是否构造它是具有寄存器加偏移量的ldr(gnu反汇编程序如果为零则不显示偏移量)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。