计算机系统基础日志No.6

本文是计算机系统基础系列的第六篇,关注于程序的编译运行和汇编过程。通过一个缓冲区溢出的例子,分析了源代码在执行时可能出现的问题,解释了编译、运行及汇编程序的步骤。同时,对比了getchar()、gets()和scanf()在读取输入时的区别和注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

计算机系统基础日志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-linux-
 0248 7838362d 36342e73 6f2e3200           x86-64.so.2.    
Contents of section .note.ABI-tag:
 0254 04000000 10000000 01000000 474e5500  ............GNU.
 0264 00000000 03000000 02000000 00000000  ................
Contents of section .note.gnu.build-id:
 0274 04000000 14000000 03000000 474e5500  ............GNU.
 0284 a765fa96 cecfd876 056d40e6 1fba94bf  .e.....v.m@.....
 0294 1855972d                             .U.-            
Contents of section .gnu.hash:
 0298 02000000 0a000000 01000000 06000000  ................
 02a8 00000041 00000000 0a000000 00000000  ...A............
 02b8 9947977c                             .G.|            
Contents of section .dynsym:
 02c0 00000000 00000000 00000000 00000000  ................
 02d0 00000000 00000000 6c000000 20000000  ........l... ...
 02e0 00000000 00000000 00000000 00000000  ................
 02f0 10000000 12000000 00000000 00000000  ................
 0300 00000000 00000000 15000000 12000000  ................
 0310 00000000 00000000 00000000 00000000  ................
 0320 26000000 12000000 00000000 00000000  &...............
 0330 00000000 00000000 44000000 12000000  ........D.......
 0340 00000000 00000000 00000000 00000000  ................
 0350 2d000000 12000000 00000000 00000000  -...............
 0360 00000000 00000000 88000000 20000000  ............ ...
 0370 00000000 00000000 00000000 00000000  ................
 0380 97000000 20000000 00000000 00000000  .... ...........
 0390 00000000 00000000 35000000 22000000  ........5..."...
 03a0 00000000 00000000 00000000 00000000  ................
 03b0 0b000000 12000e00 6a070000 00000000  ........j.......
 03c0 50000000 00000000                    P.......        
Contents of section .dynstr:
 03c8 006c6962 632e736f 2e360067 65747300  .libc.so.6.gets.
 03d8 70757473 005f5f73 7461636b 5f63686b  puts.__stack_chk
 03e8 5f666169 6c007072 696e7466 00676574  _fail.printf.get
 03f8 63686172 005f5f63 78615f66 696e616c  char.__cxa_final
 0408 697a6500 5f5f6c69 62635f73 74617274  ize.__libc_start
 0418 5f6d6169 6e00474c 4942435f 322e3400  _main.GLIBC_2.4.
 0428 474c4942 435f322e 322e3500 5f49544d  GLIBC_2.2.5._ITM
 0438 5f646572 65676973 74657254 4d436c6f  _deregisterTMClo
 0448 6e655461 626c6500 5f5f676d 6f6e5f73  neTable.__gmon_s
 0458 74617274 5f5f005f 49544d5f 72656769  tart__._ITM_regi
 0468 73746572 544d436c 6f6e6554 61626c65  sterTMCloneTable
 0478 00                                   .               
Contents of section .gnu.version:
 047a 00000000 02000300 02000200 02000000  ................
 048a 00000200 0100                        ......          
Contents of section .gnu.version_r:
 0490 01000200 01000000 10000000 00000000  ................
 04a0 1469690d 00000300 56000000 10000000  .ii.....V.......
 04b0 751a6909 00000200 60000000 00000000  u.i.....`.......
Contents of section .rela.dyn:
 04c0 a00d2000 00000000 08000000 00000000  .. .............
 04d0 60070000 00000000 a80d2000 00000000  `......... .....
 04e0 08000000 00000000 20070000 00000000  ........ .......
 04f0 08102000 00000000 08000000 00000000  .. .............
 0500 08102000 00000000 d80f2000 00000000  .. ....... .....
 0510 06000000 01000000 00000000 00000000  ................
 0520 e00f2000 00000000 06000000 05000000  .. .............
 0530 00000000 00000000 e80f2000 00000000  .......... .....
 0540 06000000 07000000 00000000 00000000  ................
 0550 f00f2000 00000000 06000000 08000000  .. .............
 0560 00000000 00000000 f80f2000 00000000  .......... .....
 0570 06000000 09000000 00000000 00000000  ................
Contents of section .rela.plt:
 0580 b80f2000 00000000 07000000 02000000  .. .............
 0590 00000000 00000000 c00f2000 00000000  .......... .....
 05a0 07000000 03000000 00000000 00000000  ................
 05b0 c80f2000 00000000 07000000 04000000  .. .............
 05c0 00000000 00000000 d00f2000 00000000  .......... .....
 05d0 07000000 06000000 00000000 00000000  ................
Contents of section .init:
 05e0 4883ec08 488b05fd 09200048 85c07402  H...H.... .H..t.
 05f0 ffd04883 c408c3                      ..H....         
Contents of section .plt:
 0600 ff35a209 2000ff25 a4092000 0f1f4000  .5.. ..%.. ...@.
 0610 ff25a209 20006800 000000e9 e0ffffff  .%.. .h.........
 0620 ff259a09 20006801 000000e9 d0ffffff  .%.. .h.........
 0630 ff259209 20006802 000000e9 c0ffffff  .%.. .h.........
 0640 ff258a09 20006803 000000e9 b0ffffff  .%.. .h.........
Contents of section .plt.got:
 0650 ff25a209 20006690                    .%.. .f.        
Contents of section .text:
 0660 31ed4989 d15e4889 e24883e4 f050544c  1.I..^H..H...PTL
 0670 8d053a02 0000488d 0dc30100 00488d3d  ..:...H......H.=
 0680 8d010000 ff155609 2000f40f 1f440000  ......V. ....D..
 0690 488d3d79 09200055 488d0571 09200048  H.=y. .UH..q. .H
 06a0 39f84889 e5741948 8b052a09 20004885  9.H..t.H..*. .H.
 06b0 c0740d5d ffe0662e 0f1f8400 00000000  .t.]..f.........
 06c0 5dc30f1f 4000662e 0f1f8400 00000000  ]...@.f.........
 06d0 488d3d39 09200048 8d353209 20005548  H.=9. .H.52. .UH
 06e0 29fe4889 e548c1fe 034889f0 48c1e83f  ).H..H...H..H..?
 06f0 4801c648 d1fe7418 488b05f1 08200048  H..H..t.H.... .H
 0700 85c0740c 5dffe066 0f1f8400 00000000  ..t.]..f........
 0710 5dc30f1f 4000662e 0f1f8400 00000000  ]...@.f.........
 0720 803de908 20000075 2f48833d c7082000  .=.. ..u/H.=.. .
 0730 00554889 e5740c48 8b3dca08 2000e80d  .UH..t.H.=.. ...
 0740 ffffffe8 48ffffff c605c108 2000015d  ....H....... ..]
 0750 c30f1f80 00000000 f3c3660f 1f440000  ..........f..D..
 0760 554889e5 5de966ff ffff5548 89e54883  UH..].f...UH..H.
 0770 ec204889 7de8e8c5 feffff89 45f4488b  . H.}.......E.H.
 0780 45e84889 45f8eb19 488b45f8 488d5001  E.H.E...H.E.H.P.
 0790 488955f8 8b55f488 10e8a2fe ffff8945  H.U..U.........E
 07a0 f4837df4 ff740683 7df40a75 db488b45  ..}..t..}..u.H.E
 07b0 f8c60000 488b45e8 c9c35548 89e54883  ....H.E...UH..H.
 07c0 ec106448 8b042528 00000048 8945f831  ..dH..%(...H.E.1
 07d0 c0488d45 f44889c7 e88dffff ff488d45  .H.E.H.......H.E
 07e0 f44889c7 e827feff ff90488b 45f86448  .H...'....H.E.dH
 07f0 33042528 00000074 05e822fe ffffc9c3  3.%(...t..".....
 0800 554889e5 b8000000 00e8acff ffff905d  UH.............]
 0810 c3554889 e5488d3d a8000000 b8000000  .UH..H.=........
 0820 00e80afe ffffb800 000000e8 d0ffffff  ................
 0830 b8000000 005dc366 0f1f8400 00000000  .....].f........
 0840 41574156 4989d741 5541544c 8d254e05  AWAVI..AUATL.%N.
 0850 20005548 8d2d4e05 20005341 89fd4989   .UH.-N. .SA..I.
 0860 f64c29e5 4883ec08 48c1fd03 e86ffdff  .L).H...H....o..
 0870 ff4885ed 742031db 0f1f8400 00000000  .H..t 1.........
 0880 4c89fa4c 89f64489 ef41ff14 dc4883c3  L..L..D..A...H..
 0890 014839dd 75ea4883 c4085b5d 415c415d  .H9.u.H...[]A\A]
 08a0 415e415f c390662e 0f1f8400 00000000  A^A_..f.........
 08b0 f3c3                                 ..              
Contents of section .fini:
 08b4 4883ec08 4883c408 c3                 H...H....       
Contents of section .rodata:
 08c0 01000200 54797065 20612073 7472696e  ....Type a strin
 08d0 673a00                               g:.             
Contents of section .eh_frame_hdr:
 08d4 011b033b 50000000 09000000 2cfdffff  ...;P.......,...
 08e4 9c000000 7cfdffff c4000000 8cfdffff  ....|...........
 08f4 6c000000 96feffff dc000000 e6feffff  l...............
 0904 fc000000 2cffffff 1c010000 3dffffff  ....,.......=...
 0914 3c010000 6cffffff 5c010000 dcffffff  <...l...\.......
 0924 a4010000                             ....            
Contents of section .eh_frame:
 0928 14000000 00000000 017a5200 01781001  .........zR..x..
 0938 1b0c0708 90010710 14000000 1c000000  ................
 0948 18fdffff 2b000000 00000000 00000000  ....+...........
 0958 14000000 00000000 017a5200 01781001  .........zR..x..
 0968 1b0c0708 90010000 24000000 1c000000  ........$.......
 0978 88fcffff 50000000 000e1046 0e184a0f  ....P......F..J.
 0988 0b770880 003f1a3b 2a332422 00000000  .w...?.;*3$"....
 0998 14000000 44000000 b0fcffff 08000000  ....D...........
 09a8 00000000 00000000 1c000000 5c000000  ............\...
 09b8 b2fdffff 50000000 00410e10 8602430d  ....P....A....C.
 09c8 06024b0c 07080000 1c000000 7c000000  ..K.........|...
 09d8 e2fdffff 46000000 00410e10 8602430d  ....F....A....C.
 09e8 0602410c 07080000 1c000000 9c000000  ..A.............
 09f8 08feffff 11000000 00410e10 8602430d  .........A....C.
 0a08 064c0c07 08000000 1c000000 bc000000  .L..............
 0a18 f9fdffff 26000000 00410e10 8602430d  ....&....A....C.
 0a28 06610c07 08000000 44000000 dc000000  .a......D.......
 0a38 08feffff 65000000 00420e10 8f02420e  ....e....B....B.
 0a48 188e0345 0e208d04 420e288c 05480e30  ...E. ..B.(..H.0
 0a58 8606480e 3883074d 0e40720e 38410e30  ..H.8..M.@r.8A.0
 0a68 410e2842 0e20420e 18420e10 420e0800  A.(B. B..B..B...
 0a78 10000000 24010000 30feffff 02000000  ....$...0.......
 0a88 00000000 00000000                    ........        
Contents of section .init_array:
 200da0 60070000 00000000                    `.......        
Contents of section .fini_array:
 200da8 20070000 00000000                     .......        
Contents of section .dynamic:
 200db0 01000000 00000000 01000000 00000000  ................
 200dc0 0c000000 00000000 e0050000 00000000  ................
 200dd0 0d000000 00000000 b4080000 00000000  ................
 200de0 19000000 00000000 a00d2000 00000000  .......... .....
 200df0 1b000000 00000000 08000000 00000000  ................
 200e00 1a000000 00000000 a80d2000 00000000  .......... .....
 200e10 1c000000 00000000 08000000 00000000  ................
 200e20 f5feff6f 00000000 98020000 00000000  ...o............
 200e30 05000000 00000000 c8030000 00000000  ................
 200e40 06000000 00000000 c0020000 00000000  ................
 200e50 0a000000 00000000 b1000000 00000000  ................
 200e60 0b000000 00000000 18000000 00000000  ................
 200e70 15000000 00000000 00000000 00000000  ................
 200e80 03000000 00000000 a00f2000 00000000  .......... .....
 200e90 02000000 00000000 60000000 00000000  ........`.......
 200ea0 14000000 00000000 07000000 00000000  ................
 200eb0 17000000 00000000 80050000 00000000  ................
 200ec0 07000000 00000000 c0040000 00000000  ................
 200ed0 08000000 00000000 c0000000 00000000  ................
 200ee0 09000000 00000000 18000000 00000000  ................
 200ef0 1e000000 00000000 08000000 00000000  ................
 200f00 fbffff6f 00000000 01000008 00000000  ...o............
 200f10 feffff6f 00000000 90040000 00000000  ...o............
 200f20 ffffff6f 00000000 01000000 00000000  ...o............
 200f30 f0ffff6f 00000000 7a040000 00000000  ...o....z.......
 200f40 f9ffff6f 00000000 03000000 00000000  ...o............
 200f50 00000000 00000000 00000000 00000000  ................
 200f60 00000000 00000000 00000000 00000000  ................
 200f70 00000000 00000000 00000000 00000000  ................
 200f80 00000000 00000000 00000000 00000000  ................
 200f90 00000000 00000000 00000000 00000000  ................
Contents of section .got:
 200fa0 b00d2000 00000000 00000000 00000000  .. .............
 200fb0 00000000 00000000 16060000 00000000  ................
 200fc0 26060000 00000000 36060000 00000000  &.......6.......
 200fd0 46060000 00000000 00000000 00000000  F...............
 200fe0 00000000 00000000 00000000 00000000  ................
 200ff0 00000000 00000000 00000000 00000000  ................
Contents of section .data:
 201000 00000000 00000000 08102000 00000000  .......... .....
Contents of section .comment:
 0000 4743433a 20285562 756e7475 20372e33  GCC: (Ubuntu 7.3
 0010 2e302d32 37756275 6e747531 7e31382e  .0-27ubuntu1~18.
 0020 30342920 372e332e 3000               04) 7.3.0. 

3.拓展

getchar()与gets(),scanf()

可参考yonggangsong

最重要的区别是gets读一行,getchar()读一个字符。

先看原型:
char * gets(char * ptr);
int getchar(void);

作用是:

gets()用于从标准输入流stdin读入一个整行(以’\n’或EOF)结束,写入ptr指向的字符数组,并返回这个指针;出错或遇到文件结束时则返回NULL。行末的’\n’从流中取出,但不写入数组。gets()不检查被写入的数组大小。

getchar()用于从标准输入流stdin读入一个字符,并返回这个字符。如果读到文件结尾,则返回EOF。注意到EOF不能用char类型表示,所以getchar()函数返回的是一个int型的数。使用时也应该注意这一点。
用scanf来读取一个字符串时,字符串中是不可以出现空格的,一旦出现空格,后面的数据就会舍弃残留在缓冲区中。
详细可以参考https://blog.youkuaiyun.com/zqixiao_09/article/details/50189477

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值