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\n", 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.
谢谢.
即使当我逐步遍历gdb并遇到打印行时,我也会获得0xbffff320作为地址
EDIT 1: Even when I step through gdb and it encounters the print line, I get 0xbffff320 as the address
环境:在Windows 7的虚拟框中运行的Ubuntu Linux 9映像.
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
然后run
然后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
这是用于重现行为的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
中的局部变量的地址在从外壳启动程序时与在启动时不同?是从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\n", 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\n", 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()
中完成的.因此,环境数组更大.
- 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-包装器以运行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屋!