gdb调试[32bits--64bits]

首先大家先了解一下32位操作系统的内存结构分布:
http://m.blog.csdn.net/maikforever/article/details/17502261

gdb调试[32bits--64bits]_第1张图片
Paste_Image.png

32bits操作系统和64bits操作系统的寄存器是不同的,大致区别看下图,具体信息点我

gdb调试[32bits--64bits]_第2张图片
Paste_Image.png
gdb调试[32bits--64bits]_第3张图片
Paste_Image.png

在我们做栈溢出实验,用gdb调试的时候,我们主要关心的是下面几个寄存器

  • 32bits操纵系统:
    $esp,$ebp
  • 64bits操作系统:
    $rsp,$rbp

实验源代码如下:

64bits:

void function(int a, int b, int c){
   char buffer1[5];
   char buffer2[10];
   int *ret;
   ret = buffer1 + 21;
   (*ret) += 7;
}
void main(){
  int x;
  x = 0;
  function(1,2,3);
  x = 1;
  printf("%d\n",x);
}

我在自己的kali2.0 64位虚拟机下面运行的时候,输出的结果是0

gdb调试[32bits--64bits]_第4张图片
Paste_Image.png

32bits:

void function(int a, int b, int c){
   char buffer1[5];
   char buffer2[10];
   int *ret;
   ret = buffer1 + 12;
   (*ret) += 8;
}
void main(){
  int x;
  x = 0;
  function(1,2,3);
  x = 1;
  printf("%d\n",x);
}

使用gcc编译:

root@kali:~/桌面/BOF# gcc -g -o ovr_ret ovr_ret.c
ovr_ret.c: In function ‘function’:
ovr_ret.c:5:8: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
    ret = buffer1 + 21;
        ^
ovr_ret.c: In function ‘main’:
ovr_ret.c:13:3: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
   printf("%d\n",x);
   ^~~~~~
ovr_ret.c:13:3: warning: incompatible implicit declaration of built-in function ‘printf’
ovr_ret.c:13:3: note: include ‘’ or provide a declaration of ‘printf’

使用gdb调试:

root@kali:~/桌面/BOF# gdb ovr_ret
GNU gdb (Debian 7.12-6) 7.12.0.20161007-git
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
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 "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ovr_ret...done.
(gdb) b 5                           //在第5行设置断点
Breakpoint 1 at 0x6bd: file ovr_ret.c, line 5.
(gdb) r                              //运行
Starting program: /root/桌面/BOF/ovr_ret 

Breakpoint 1, function (a=1, b=2, c=3) at ovr_ret.c:5
5      ret = buffer1 + 21;
(gdb) x $rsp                      //显示rsp寄存器信息
0x7fffffffe110: 0xffffe130
(gdb) x $rbp                      //显示rbp寄存器信息
0x7fffffffe110: 0xffffe130             
(gdb) x buffer1                  //显示临时变量buffer1的信息
0x7fffffffe103: 0x00000000
(gdb) shell                          //在保持gdb的情况下,运行shell
root@kali:~/桌面/BOF# echo $[0x7fffffffe110-0x7fffffffe103+8]   
//$rbp-buffer1+8得到的是ret返回地址,为什么加8呢?因为实在64位操作系统里面,64=8*8,如果是32位操纵系统则+4
21
root@kali:~/桌面/BOF# exit
exit
(gdb) disas main
Dump of assembler code for function main:
   0x00005555555546db <+0>: push   %rbp
   0x00005555555546dc <+1>: mov    %rsp,%rbp
   0x00005555555546df <+4>: sub    $0x10,%rsp
   0x00005555555546e3 <+8>: movl   $0x0,-0x4(%rbp)
   0x00005555555546ea <+15>:    mov    $0x3,%edx
   0x00005555555546ef <+20>:    mov    $0x2,%esi
   0x00005555555546f4 <+25>:    mov    $0x1,%edi
   0x00005555555546f9 <+30>:    callq  0x5555555546b0 
   0x00005555555546fe <+35>:    movl   $0x1,-0x4(%rbp)
   0x0000555555554705 <+42>:    mov    -0x4(%rbp),%eax
   0x0000555555554708 <+45>:    mov    %eax,%esi
   0x000055555555470a <+47>:    lea    0x93(%rip),%rdi        # 0x5555555547a4
   0x0000555555554711 <+54>:    mov    $0x0,%eax
   0x0000555555554716 <+59>:    callq  0x555555554560 
   0x000055555555471b <+64>:    nop
   0x000055555555471c <+65>:    leaveq 
   0x000055555555471d <+66>:    retq   
End of assembler dump.
(gdb) shell
root@kali:~/桌面/BOF# echo $[0x0000555555554705-0x00005555555546fe]
//计算x=1这条语句的返回地址和之前ret的差值
7
root@kali:~/桌面/BOF# ./ovr_ret
//最后修改过的代码,运行结果不为1而是0,因为跳过了x=1;这条语句的执行
0
root@kali:~/桌面/BOF# 

你可能感兴趣的:(gdb调试[32bits--64bits])