gdb 显示的地址与代码中的地址不同 [英] gdb showing different address than in code
问题描述
我正在尝试实施缓冲区溢出攻击,我需要知道我试图溢出的缓冲区的地址.
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屋!