fli*_*liX 1 stack gdb arm buffer-overflow raspbian
我想使用Raspberry PI和Raspbian OS为ARMv6指令集架构编写一个简单的缓冲区溢出示例.我首先看一下堆栈框架的布局.很遗憾,我无法找到回邮地址.请考虑以下示例:
void foo
(int b)
{
int c = 3;
}
int main
(int argc, char **argv)
{
int a = 1;
foo(2);
a = 4;
}
Run Code Online (Sandbox Code Playgroud)
我编译它:
gcc exploit_me.c -g -O0 -o exploit_me
Run Code Online (Sandbox Code Playgroud)
使用gdb调试代码可以获得以下信息:
gdb exploit_me
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "arm-linux-gnueabihf".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/pi/_development/buffer_overflow/exploit_me...done.
(gdb) b 4
Breakpoint 1 at 0x83a0: file exploit_me.c, line 4.
(gdb) run
Starting program: /home/pi/_development/buffer_overflow/exploit_me
Breakpoint 1, foo (b=2) at exploit_me.c:4
4 int c = 3;
(gdb) disas foo
Dump of assembler code for function foo:
0x00008390 <+0>: push {r11} ; (str r11, [sp, #-4]!)
0x00008394 <+4>: add r11, sp, #0
0x00008398 <+8>: sub sp, sp, #20
0x0000839c <+12>: str r0, [r11, #-16]
=> 0x000083a0 <+16>: mov r3, #3
0x000083a4 <+20>: str r3, [r11, #-8]
0x000083a8 <+24>: add sp, r11, #0
0x000083ac <+28>: pop {r11}
0x000083b0 <+32>: bx lr
End of assembler dump.
(gdb) info r
r0 0x2 2
r1 0xbefff804 3204446212
r2 0xbefff80c 3204446220
r3 0x1 1
r4 0x0 0
r5 0x0 0
r6 0x82e4 33508
r7 0x0 0
r8 0x0 0
r9 0x0 0
r10 0xb6fff000 3070226432
r11 0xbefff69c 3204445852
r12 0xb6fc0000 3069968384
sp 0xbefff688 0xbefff688
lr 0x83d8 33752
pc 0x83a0 0x83a0 <foo+16>
cpsr 0x60000010 1610612752
(gdb) disas main
Dump of assembler code for function main:
0x000083b4 <+0>: push {r11, lr}
0x000083b8 <+4>: add r11, sp, #4
0x000083bc <+8>: sub sp, sp, #16
0x000083c0 <+12>: str r0, [r11, #-16]
0x000083c4 <+16>: str r1, [r11, #-20]
0x000083c8 <+20>: mov r3, #1
0x000083cc <+24>: str r3, [r11, #-8]
0x000083d0 <+28>: mov r0, #2
0x000083d4 <+32>: bl 0x8390 <foo>
0x000083d8 <+36>: mov r3, #4
0x000083dc <+40>: str r3, [r11, #-8]
0x000083e0 <+44>: mov r0, r3
0x000083e4 <+48>: sub sp, r11, #4
0x000083e8 <+52>: pop {r11, pc}
End of assembler dump.
(gdb) x/12xw $sp
0xbefff688: 0x00000000 0x00000002 0x00008360 0x00008438
0xbefff698: 0xb6fc1b80 0xbefff6b4 0xbefff804 0x00000001
0xbefff6a8: 0x00000000 0x00000001 0x00000000 0xb6eac81c
Run Code Online (Sandbox Code Playgroud)
根据保存返回地址的链接寄存器设置为地址0x83d8
lr 0x83d8 33752
Run Code Online (Sandbox Code Playgroud)
这确实是main中下一条指令的正确地址:
0x000083d8 <+36>: mov r3, #4
Run Code Online (Sandbox Code Playgroud)
但是堆栈(请参阅gdb输出的结尾)不包含阻止缓冲区溢出攻击的返回地址.
是否按设计,返回地址仅保存在链接寄存器中,而不是被推入堆栈或我错过了什么?
小智 5
我不熟悉手臂架构,但Power PC也是如此.当你调用一个函数时,你的返回地址存储在lr中.如果再调用一个级别,则将前一个lr推入堆栈.基本上,lr始终包含您所在功能的返回地址.如果您需要在呼叫历史记录中更高,则需要查看堆栈.
所以...
void myFunc2( void)
{
myFunc3();
}
void myFunc1( void )
{
myFunc2();
}
Run Code Online (Sandbox Code Playgroud)
如果您在myFunc3中,则lr将包含myFunc2的返回地址.从myFunc2到myFunc1的返回地址位于堆栈的某处.我认为你可以做你正在尝试破坏myFunc1的返回地址,而不是你想要的myFunc2.
对于power pc,您可以通过阅读Power PC EABI来查看寄存器和堆栈的工作原理