计算机系统基础日志No.6
缓冲区溢出演示
一,程序,编译运行及汇编
1.源程序
/* Demonstration of buffer overflow */
#include <stdio.h>
#include <stdlib.h>
/* Implementation of library function gets() */
char *gets(char *dest)
{
int c = getchar();
char *p = dest;
while (c != EOF && c != '\n') {
*p++ = c;
c = getchar();
}
*p = '\0';
return dest;
}
/* Read input line and write it back */
void echo()
{
char buf[4]; /* Way too small! */
gets(buf);
puts(buf);
}
void call_echo()
{
echo();
}
/*void smash()
{
printf("I've been smashed!\n");
exit(0);
}
*/
int main()
{
printf("Type a string:");
call_echo();
return 0;
}
2.编译运行
1>结果
l
wh@lwh-virtual-machine:~$ gcc bufdemo.c -o bufdemo
lwh@lwh-virtual-machine:~$ ./bufdemo
输入用户自定义数字
Type a string:0123
0123
lwh@lwh-virtual-machine:~$ ./bufdemo
Type a string:01234
01234
*** stack smashing detected ***: <unknown> terminated
已放弃 (核心已转储)
2>分析
当输入01234时出现问题,经过查询知道这一般都是程序有内存操作错误并产生SIGSEGV信号, 并在目录下生成名字叫做core的文件.
排查程序发现char buf[4]存储太小,用户键盘输入的字符极易超出其范围
3>汇编及汇编程序
为整理后所得,非虚拟机原结果
lwh@lwh-virtual-machine:~$ gcc -S -o bufdemo.text bufdemo.c
gets:
pushq %rbp
movq %rsp, %rbp
subq $32, %rsp
movq %rdi, -24(%rbp)
call getchar@PLT
movl %eax, -12(%rbp)
movq -24(%rbp), %rax
movq %rax, -8(%rbp)
jmp .L2
.L4:
movq -8(%rbp), %rax
leaq 1(%rax), %rdx
movq %rdx, -8(%rbp)
movl -12(%rbp), %edx
movb %dl, (%rax)
call getchar@PLT
movl %eax, -12(%rbp)
.L2:
cmpl $-1, -12(%rbp)
je .L3
cmpl $10, -12(%rbp)
jne .L4
.L3:
movq -8(%rbp), %rax
movb $0, (%rax)
movq -24(%rbp), %rax
leave
ret
echo:
pushq %rbp
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movq %fs:40, %rax
movq %rax, -8(%rbp)
xorl %eax, %eax
leaq -12(%rbp), %rax
movq %rax, %rdi
call gets
leaq -12(%rbp), %rax
movq %rax, %rdi
call puts@PLT
nop
movq -8(%rbp), %rax
xorq %fs:40, %rax
je .L7
call __stack_chk_fail@PLT
.L7:
leave
ret
call_echo:
pushq %rbp
movq %rsp, %rbp
movl $0, %eax
call echo
nop
popq %rbp
ret
.LC0:
.string “Type a string:”
.text
.globl main
.type main, @function
main:
pushq %rbp
movq %rsp, %rbp
leaq .LC0(%rip), %rdi
movl $0, %eax
call printf@PLT
movl $0, %eax
call call_echo
movl $0, %eax
popq %rbp
ret
lwh@lwh-virtual-machine:~$ objdump -s bufdemo
bufdemo: 文件格式 elf64-x86-64
Contents of section .interp:
0238 2f6c6962 36342f6c 642d6c69 6e75782d /lib64/ld-l