为什么 libc.so 符号表中没有main_arena,而glibc2.23的malloc.c中却有一个?



我正在研究glibc的堆。

libc.o中没有main_arena符号,即使我尝试用pwntool倾倒它。但是,当我调试测试程序时,我可以打印main_arena结构。

gdb-peda$ p main_arena
$1 = {
    mutex = 0x0, 
    flags = 0x0, 
    fastbinsY = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 
    top = 0x0, 
    last_remainder = 0x0, 
    bins = {0x0 <repeats 254 times>}, 
    binmap = {0x0, 0x0, 0x0, 0x0}, 
    next = 0x7ffff7dd1b20 <main_arena>, 
    next_free = 0x0, 
    attached_threads = 0x1, 
    system_mem = 0x0, 
    max_system_mem = 0x0
}

此外,当我使用-m32编译测试程序时,也找不到main_arena。

main_arena是本地符号,是专门未导出的。导出符号的列表通过GLIBC源树中的Version文件控制。通过设计,这是为了防止人们能够与Glibc内部使用的随机符号链接(以免按POSIX和其他标准污染名称空间)。

gdb可以找到它,因为您有可用的调试符号... c lib未剥离,或者您在 /usr/lib/debug/中有拆分调试符号,而gdb正在找到这些符号。当您启动GDB时,它将告诉您Reading symbols from /usr/lib/debug/xxxxx

能够链接到符号的唯一方法是从源重建GLIBC并修改导出列表。

另外,您可以在应用程序中编写一些代码,以表现为GDB。也就是说,打开调试文件,处理其中的精灵/矮人信息,使用主动加载的库信息应用重新安置(请参阅dl_iterate_phdr),然后直接开始戳内存。

如果工作太多,则可能是针对您自己的流程的fork() popen() GDB,并以批处理模式运行以转储符号信息。

char *cmd;
FILE *fp;
asprintf(&cmd, "gdb -q -p %i -batch -ex 'p &main_arena'", getpid());
fp = popen(cmd, "r");
// parse the output of |fp| here looking for the address.
free(cmd);
fclose(fp);

libc.so.6被剥离。它的调试版本不是。这就是为什么readelf不显示main_arena。

我仍然想知道gdb即使删除了库,也知道符号名称。

相关内容

  • 没有找到相关文章