根据user stack 数据分析函数调用栈

 stack 数据如下:

0xbefffca8:	0x0000000f	0x00000019	0x00000005	0x00000014
0xbefffcb8:	0x0000000f	0x00000019	0x00000000	0x00010440
0xbefffcc8:	0x00010430	0xb6ea8e7c	0xb6fcb000	0xbefffe24
0xbefffcd8:	0x00000001	0x00010430	0xb6fec71c	0xb6fff884
0xbefffce8:	0xe9b42e1e	0xe1a15cf6	0x00000000	0x00000000
0xbefffcf8:	0x00010294	0x00000000	0x00000000	0x00000000
0xbefffd08:	0xb6fff000	0x00000000	0x00000000	0x00000000
0xbefffd18:	0x00000000	0x00000000	0x00000000	0x00000000

寄存器信息:

r0             0x19	25
r1             0xf	15
r2             0x14	20
r3             0xf	15
r4             0xbefffce8	3204447464
r5             0x0	0
r6             0x10294	66196
r7             0x0	0
r8             0x0	0
r9             0x0	0
r10            0xb6fff000	3070226432
r11            0x0	0
r12            0xb6fcb000	3070013440
sp             0xbefffca8	0xbefffca8
lr             0x10428	66600
pc             0x103d4	0x103d4 <add+12>
cpsr           0x600d0010	1611464720

当前正在执行的函数的汇编代码:

Dump of assembler code for function add:
   0x000103c8 <+0>:	sub	sp, sp, #8
   0x000103cc <+4>:	str	r0, [sp, #4]
   0x000103d0 <+8>:	str	r1, [sp]
=> 0x000103d4 <+12>:	ldr	r2, [sp, #4]
   0x000103d8 <+16>:	ldr	r3, [sp]
   0x000103dc <+20>:	add	r3, r2, r3
   0x000103e0 <+24>:	mov	r0, r3
   0x000103e4 <+28>:	add	sp, sp, #8
   0x000103e8 <+32>:	bx	lr

从第一个指令可知,add()调用者函数所在的栈的结束地址为 $sp + 8 = 0xbefffcb0.

add() 函数调用的位置为:

(gdb) x /i $lr-4
   0x10424 <foo+56>:	bl	0x103c8 <add>

再看 foo()的汇编:

   0x000103ec <+0>:	push	{lr}		; (str lr, [sp, #-4]!)
   0x000103f0 <+4>:	sub	sp, sp, #20
   0x000103f4 <+8>:	str	r0, [sp, #4]
   0x000103f8 <+12>:	str	r1, [sp]
   0x000103fc <+16>:	ldr	r2, [sp, #4]
   0x00010400 <+20>:	ldr	r3, [sp]
   0x00010404 <+24>:	add	r3, r2, r3
   0x00010408 <+28>:	str	r3, [sp, #12]
   0x0001040c <+32>:	ldr	r2, [sp, #4]
   0x00010410 <+36>:	ldr	r3, [sp]
   0x00010414 <+40>:	rsb	r3, r3, r2
   0x00010418 <+44>:	str	r3, [sp, #8]
   0x0001041c <+48>:	ldr	r0, [sp, #12]
   0x00010420 <+52>:	ldr	r1, [sp, #8]
   0x00010424 <+56>:	bl	0x103c8 <add>
   0x00010428 <+60>:	add	sp, sp, #20
   0x0001042c <+64>:	pop	{pc}		; (ldr pc, [sp], #4)

由此可知, $lr 在栈上保存的位置为:

$sp + 8 + 20  = 0xbefffcc4

根据 user stack 数据可知, 0xbefffcc4上的位置的值为

0x00010440
这个即是调用 foo()后的返回地址。

所以,调用  foo()的位置为 0x00010440 -4 = 0x0001043c

(gdb) x /i 0x1043c
   0x1043c <main+12>:	bl	0x103ec <foo>

再看 main()的汇编:

   0x00010430 <+0>:	push	{r3, lr}
   0x00010434 <+4>:	mov	r0, #20
   0x00010438 <+8>:	mov	r1, #5
   0x0001043c <+12>:	bl	0x103ec <foo>
   0x00010440 <+16>:	mov	r3, #0
   0x00010444 <+20>:	mov	r0, r3
   0x00010448 <+24>:	pop	{r3, pc}

由此可知,main()的 lr在栈上的位置为:

$sp + 8 + 20 +8 = 0xbefffccc

这里加上8, 是因为, push {r3, lr}是先 push lr, 后 push r3.

再根据 user stack, 查出,在 0xbefffcc8位置,保存的值为:

0xb6ea8e7c

 这个是main()的  lr值。 

 x /i 0xb6ea8e7c - 4
   0xb6ea8e78 <__libc_start_main+272>:	blx	r3

栈的结构如下图:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值