缓冲区溢出不应该发生(?)

use*_*171 2 c c++ gdb buffer-overflow disassembly

我有以下程序

 1  #include <stdio.h>
 2  #include <stdlib.h>
 3  #include <string.h>
 4  
 5  int check_authentication(char *password){
 6  char password_buffer[16];
 7  int auth_flag =0;
 8  
 9  
10  strcpy(password_buffer, password);
11  
12  if(strcmp(password_buffer, "brillig" ) == 0 )
13  auth_flag = 1;
14  if(strcmp(password_buffer, "outgrabe") == 0)
15  auth_flag = 1;
16  
17  return auth_flag;
18  }
19  
20  int main(int argc, char *argv[]){
21  if (argc<2){
22  printf("Usage: %s <password>\n", argv[0]);
23  exit(0);
24  }
25  
26  if(check_authentication(argv[1])){
27      printf("\n-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n");
28      printf("    Access Granted.\n");
29      printf("\n-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n");
30      }
31  else {
32  printf("\n Access Denied. \n");
33  }
34  }
Run Code Online (Sandbox Code Playgroud)

我正在运行它通过gdb提供30个字节的As ...我正在设置以下断点

(gdb) break 9
Breakpoint 1 at 0x80484c1: file auth_overflow2.c, line 9.
(gdb) break 16
Breakpoint 2 at 0x804850f: file auth_overflow2.c, line 16.
(gdb) run AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.一切都顺利,直到下一个断点

Breakpoint 1, check_authentication (password=0xbffff6d2 'A' <repeats 30 times>)
at auth_overflow2.c:10
10  strcpy(password_buffer, password);
(gdb) x/s password_buffer 
 0xbffff484:    "\364\237\374\267\240\205\004\b\250\364\377\277\245",            <incomplete      sequence \352\267>
 (gdb) x/x &auth_flag
 0xbffff494:    0x00
Run Code Online (Sandbox Code Playgroud)

现在我们看到以下信息:

变量auth_flag位于地址0xbffff494中,变量缓冲区位于地址0xbffff484中.由于var auth_flag的地址大于缓冲区的地址,并且堆栈朝向较低的地址增长,这意味着缓冲区变量中的额外(缓冲区溢出)字节将不会超过auth_flag.对 ?

但是gdb有不同的看法......

(gdb) cont
Continuing.

Breakpoint 2, check_authentication (
password=0xbf004141 <Address 0xbf004141 out of bounds>)
at auth_overflow2.c:17
17  return auth_flag;
(gdb) x/s password_buffer 
0xbffff484: 'A' <repeats 30 times>
(gdb) x/x &auth_flag
0xbffff494: 0x41
Run Code Online (Sandbox Code Playgroud)

和......

(gdb) x/16xw &auth_flag
0xbffff494: 0x41414141  0x41414141  0x41414141  0xbf004141
0xbffff4a4: 0x00000000  0xbffff528  0xb7e8bbd6  0x00000002
0xbffff4b4: 0xbffff554  0xbffff560  0xb7fe1858  0xbffff510
0xbffff4c4: 0xffffffff  0xb7ffeff4  0x080482bc  0x00000001
Run Code Online (Sandbox Code Playgroud)

我们看到auth_flag被这些0x41(= A)覆盖,尽管这个变量位于堆栈的较低位置.为什么会这样?

小智 5

堆栈增长方向与超出缓冲区时额外字节的位置无关.从超限strcpy总是将是为更高的地址(除非到目前为止超限你缠绕到地址0,这是非常不可能的)