gdb 显示的地址与代码中的地址不同 [英] gdb showing different address than in code

查看:18
本文介绍了gdb 显示的地址与代码中的地址不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实施缓冲区溢出攻击,我需要知道我试图溢出的缓冲区的地址.

I am trying to implement a buffer overflow attack and I need to know the address of my buffer that I am trying to overflow.

使用 GDB 显示的地址与我刚刚在代码中显示的地址不同:

The address that is displayed using GDB is different than if I just did this in the code:

具体代码:

#include<stdio.h>

int main() {
   char buffer[20];
   printf("%p
", buffer); // 0xbffff320

   return 0;
}

但是,如果我这样做,在 gdb 中:

However, in gdb if I do:

p &buffer

我得到:0xbffff330

为什么会有区别,它会破坏我的缓冲区溢出攻击吗?

Why is there a difference and will it mess up my buffer overflow attack?

我禁用了 ALSR 和堆栈保护.

I have ALSR and stack guard disabled.

谢谢.

编辑 1:即使我单步执行 gdb 并遇到打印行,我也会得到 0xbffff320 作为地址

EDIT 1: Even when I step through gdb and it encounters the print line, I get 0xbffff320 as the address

编辑 2:

环境:Ubuntu Linux 9 映像在 Windows 7 上的虚拟机中运行.

Environment: Ubuntu Linux 9 image running in virtual box on windows 7.

gdb 版本:6.8-debian

The gdb version: 6.8-debian

使用GCC编译如:gcc -g -fno-stack-protector filename.c立即执行:./a.out打印地址:0xbffff320

Compiled using GCC such as: gcc -g -fno-stack-protector filename.c execute immediately: ./a.out address printed: 0xbffff320

然后像这样在调试器中打开:gdb ./a.out然后输入 b main然后 运行然后 p &buffer

Then open in debugger like this: gdb ./a.out then enter b main then run then p &buffer

那么地址就是0xbffff330

Then address is 0xbffff330

编辑 3:

这是重现行为的 gdb 日志:

This is the gdb log to reproduce behavior:

$ gdb ./a.out

$ gdb ./a.out

b 主要

运行

p &buffer/* 这里的地址与我运行可执行文件时显示的不同 */

p &buffer /* address here is different than what is shown if I run executable */

单步执行程序到 printf 语句/* 这里的地址与 p &buffer 相同,但与程序运行时打印的不同 */

step through program to printf statement /* address here is same as p &buffer but different than what is printed when program is ran */

推荐答案

问题,据我了解,为什么main中的一个局部变量的地址在程序从shell 与从 gdb 启动时的对比.

The question, as I understand it, is why the address of a local variable in main is different when the program is started from the shell versus when it is started from gdb.

这里有一个示例程序来显示差异:

Here's a sample program to show the difference:

mp@ubuntu:~$ cat s.c
#include<stdio.h>

int main(int argc, char **argv) {
  char buffer[20];
  system("env");
  printf("%s %p
", argv[0], buffer);

  return 0;
}

我们将在干净的环境中运行它.(我也禁用了 ASLR).

We'll run it in a clean environment. (I also disabled ASLR).

mp@ubuntu:~$ env -i sh
$ ./s
PWD=/home/mp
./s 0xbffffe48

 

$ gdb ./s
(gdb) run
Starting program: /home/mp/s 
COLUMNS=80
PWD=/home/mp
LINES=42
/home/mp/s 0xbffffe08

gdb 的 print &buffer 命令的输出与程序的地址思想相同,但与程序在 shell 中运行时的不同.

The output from gdb's print &buffer command is the same as the program's idea of the address, but they're both different from when the program was run in the shell.

(gdb) b 6
Breakpoint 1 at 0x804849c: file s.c, line 6.
(gdb) run
Starting program: /home/mp/s 
COLUMNS=80
PWD=/home/mp
LINES=42

Breakpoint 1, main (argc=1, argv=0xbffffed4) at s.c:6
6      printf("%s %p
", argv[0], buffer);
(gdb) p &buffer
$1 = (char (*)[20]) 0xbffffe08
(gdb) n
/home/mp/s 0xbffffe08
8      return 0;

造成这种差异的原因有两点:

There are a couple of things contributing to the difference:

  • gdb 使用绝对路径名调用程序,因此 argv 数组更大.
  • gdb 设置(或在本例中添加)两个环境变量.这是在 readline/shell.c:sh_set_lines_and_columns() 中完成的.所以 environ 数组更大.
  • gdb is invoking the program with an absolute pathname, so the argv array is bigger.
  • gdb sets (or in this case, adds) two environment variables. This is done in readline/shell.c:sh_set_lines_and_columns(). So the environ array is bigger.

要从环境中删除这两个变量,您可以使用 未设置环境,或 设置 exec-wrapper 来运行 env -u ....这样,程序在 gdb 下的地址与在 shell 中运行时的地址相同(如果我们使用绝对路径名).

To remove those two variables from the environment, you can use unset environment, or set exec-wrapper to run env -u .... That way, the program's addresses under gdb are the same as when it's run in the shell (if we use an absolute pathname).

$ `pwd`/s
PWD=/home/mp
/home/mp/s 0xbffffe28

$ gdb `pwd`/s
(gdb) set exec-wrapper env -u LINES -u COLUMNS
(gdb) run
Starting program: /home/mp/s 
PWD=/home/mp
/home/mp/s 0xbffffe28

这篇关于gdb 显示的地址与代码中的地址不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆