Linux 上 64 位进程中的地址
addresses in a 64-bit process on Linux
我写了一个(为了显示问题)一个简单的 C-pgm,它在源代码中有一个函数 func(),在共享库中有另一个函数 funcs();编译完成:
$ gcc -shared -fPIC -o libfuncs.so -m64 -g funcs.c
$ gcc -g -m64 -fPIC -o stack stack.c -L. -lfuncs
即这是一个 64 位编译的 phm 和共享库:
$ file stack libfuncs.so
stack: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.0.0, BuildID[sha1]=bf7a7e15181e110789a4ee0b237f3a8ec58d4823, not stripped
libfuncs.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=f1ffa166db952b92479c36169252e5ddff01e19e, not stripped
当我用 gdb 检查这个时,我有以下问题:为什么 64 位地址 char *p
显示为 0x400734 或在 malloc() 之后显示为 0x602010,我希望共享库中的 char *p
有 8 个字节,显示为 0x7ffff7bd9609:
Breakpoint 1, main () at stack.c:12
12 char *p = "hello";
(gdb) n
14 p = (char *) malloc(10);
(gdb) p p
= 0x400734 "hello"
(gdb) n
16 func(p, "foo");
(gdb) p p
= 0x602010 ""
(gdb) s
func (p=0x602010 "", s=0x40073a "foo") at stack.c:25
25 char *a = "bla";
(gdb) n
27 }
(gdb) p a
= 0x40073e "bla"
(gdb) n
main () at stack.c:17
17 funcs(p, "foo"); // this is a shared lib
(gdb) s
funcs (a=0x602010 "", b=0x40073a "foo") at funcs.c:8
8 char *p = "bar";
(gdb) n
10 }
(gdb) p p
= 0x7ffff7bd9609 "bar"
当代码在 gdb 下运行时,address space layout randomization 被禁用以便于调试和重现。这使得将所有相关分配位打包到前 32 位地址中变得更加容易。
它没有什么特别之处,如果分配足够大,您将开始看到更高的地址。
尝试在代码中而不是在 gdb 中打印指针,看看效果如何。
注意:评估space布局随机化并不一定意味着分配不能驻留在低32位地址,只是随机化占据了space。另外,还要看实际的地址随机化算法。
我写了一个(为了显示问题)一个简单的 C-pgm,它在源代码中有一个函数 func(),在共享库中有另一个函数 funcs();编译完成:
$ gcc -shared -fPIC -o libfuncs.so -m64 -g funcs.c
$ gcc -g -m64 -fPIC -o stack stack.c -L. -lfuncs
即这是一个 64 位编译的 phm 和共享库:
$ file stack libfuncs.so
stack: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.0.0, BuildID[sha1]=bf7a7e15181e110789a4ee0b237f3a8ec58d4823, not stripped
libfuncs.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=f1ffa166db952b92479c36169252e5ddff01e19e, not stripped
当我用 gdb 检查这个时,我有以下问题:为什么 64 位地址 char *p
显示为 0x400734 或在 malloc() 之后显示为 0x602010,我希望共享库中的 char *p
有 8 个字节,显示为 0x7ffff7bd9609:
Breakpoint 1, main () at stack.c:12
12 char *p = "hello";
(gdb) n
14 p = (char *) malloc(10);
(gdb) p p
= 0x400734 "hello"
(gdb) n
16 func(p, "foo");
(gdb) p p
= 0x602010 ""
(gdb) s
func (p=0x602010 "", s=0x40073a "foo") at stack.c:25
25 char *a = "bla";
(gdb) n
27 }
(gdb) p a
= 0x40073e "bla"
(gdb) n
main () at stack.c:17
17 funcs(p, "foo"); // this is a shared lib
(gdb) s
funcs (a=0x602010 "", b=0x40073a "foo") at funcs.c:8
8 char *p = "bar";
(gdb) n
10 }
(gdb) p p
= 0x7ffff7bd9609 "bar"
当代码在 gdb 下运行时,address space layout randomization 被禁用以便于调试和重现。这使得将所有相关分配位打包到前 32 位地址中变得更加容易。
它没有什么特别之处,如果分配足够大,您将开始看到更高的地址。
尝试在代码中而不是在 gdb 中打印指针,看看效果如何。
注意:评估space布局随机化并不一定意味着分配不能驻留在低32位地址,只是随机化占据了space。另外,还要看实际的地址随机化算法。