我在两个程序中获取libc.so中函数“printf”的物理地址,并且两个物理地址不同。而且我读了两个不同的物理地址,内容几乎相同。这意味着函数“printf”在内存中有两个副本吗?
详细说明:
我的操作系统是32位Linux。
物理地址的读数为“/ proc / self / pagemap”。
使用fmem模块实现物理地址读取,其源代码位于git@github.com:NateBrune / fmem.git
答案 0 :(得分:1)
我得到了函数的物理地址" printf"在libc.so中有两个程序,两个物理地址不同。
你可能做错了(但很难猜到:你没有提供任何细节)。
特别要注意以下程序:
#include <stdio.h>
int main()
{
printf("&printf: %p\n", &printf);
return 0;
}
不打印printf
中libc.so.6
的实际地址,正如GDB可以看到的那样:
(gdb) start
Temporary breakpoint 1 at 0x8048426: file pagemap.c, line 5.
Starting program: /tmp/pagemap
Temporary breakpoint 1, main () at pagemap.c:5
5 printf("&printf: %p\n", &printf);
(gdb) n
&printf: 0x80482f0
6 return 0;
(gdb) info symbol 0x80482f0
printf@plt in section .plt of /tmp/pagemap
(gdb) p &printf
$1 = (<text variable, no debug info> *) 0xf7e5add0 <printf>
(gdb) info sym 0xf7e5add0
printf in section .text of /lib32/libc.so.6
请注意printf @0x80482f0
位于主可执行文件中,并且不应该共享(除了同时运行的同一个可执行文件的多个实例之间),并且不 printf
的代码实际存在的位置。
printf @0xf7e5add0
位于libc.so.6
,而 是printf
的代码实际所在的位置。 该页面应该由使用libc.so.6
的所有进程共享。
P.S。要在printf
中获取libc.so.6
的实际地址,可以使用此程序:
#include <stdio.h>
#include <dlfcn.h>
int main()
{
printf("&printf: %p\n", &printf);
printf("&printf: %p\n", dlsym(RTLD_NEXT, "printf"));
return 0;
}
gcc -g pagemap.c -o pagemap -m32 -ldl -D_GNU_SOURCE
(gdb) run
Starting program: /tmp/pagemap
&printf: 0x80483c0
&printf: 0xf7e55dd0
(gdb) info sym 0xf7e55dd0
printf in section .text of /lib32/libc.so.6