【问题标题】:Bypass/Switch between/Select weak symbols绕过/切换/选择弱符号
【发布时间】:2020-07-13 16:56:57
【问题描述】:

举个简单的例子:

#include <stdio.h>
#include <stdlib.h>

int main() {
   void* test = malloc(10);
   printf("%p\n", test);
   return 0;
}

当我使用gdb 进入malloc 时,我最终进入libc

#0  __GI___libc_malloc (bytes=10) at malloc.c:3028
#1  0x000055555555469c in main () at test.c:7

如果我使用 ASan gcc -fsanitize=address -g test.c -o test 编译,我最终会被 ASan 拦截:

#0  0x00007ffff6ef8a80 in malloc () from /usr/lib/x86_64-linux-gnu/libasan.so.4
#1  0x000055555555495c in main () at test.c:7

这是因为首先加载 ASan 并导出一个弱符号:

$ readelf -W -a /usr/lib/x86_64-linux-gnu/libasan.so.4
...
   314: 00000000000dea80   479 FUNC    WEAK   DEFAULT   12 malloc
...
$ readelf -W -a test
...
Dynamic section at offset 0xd70 contains 30 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libasan.so.4]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
...
$ readelf -W -a /lib/x86_64-linux-gnu/libc.so.6
...
  1229: 00000000000970e0   923 FUNC    GLOBAL DEFAULT   13 malloc@@GLIBC_2.2.5
...

是否可以通过 pin malloc 调用 libc 版本而不是 ASan?

我尝试了以下但没有成功:

#include <stdio.h>
#include <stdlib.h>

__asm__(".symver malloc,malloc@GLIBC_2.2.5");
int main() {
   void* test = malloc(10);
   printf("%p\n", test);
   return 0;
}
$ ./test
ASAN:DEADLYSIGNAL
=================================================================
==4616==ERROR: AddressSanitizer: SEGV on unknown address 0x55f589f7294a (pc 0x55f589f72820 bp 0x7fff24457f70 sp 0x7fff24457f58 T0)
==4616==The signal is caused by a WRITE memory access.
    #0 0x55f589f7281f  (/home/vagrant/symbol-ver/test+0x81f)
    #1 0x55f589f7295b in main /home/vagrant/symbol-ver/test.c:7
    #2 0x7f5abfddeb96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #3 0x55f589f72869 in _start (/home/vagrant/symbol-ver/test+0x869)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/home/vagrant/symbol-ver/test+0x81f)
==4616==ABORTING

【问题讨论】:

  • 比较readelf libc 输出和__asm__ 语句,1 vs 2 @ 字符有什么不同吗?
  • 实际上想要达到什么目的?

标签: c linker ld address-sanitizer weak-symbol


【解决方案1】:

是否可以固定 malloc 来调用 libc 版本而不是 ASan?

当然:您可以dlopen("libc.so.6", ...) 并使用dlsym("malloc", ...)

但是,在 ASan 二进制文件中这样做是没有用的:正如您发现的那样,它会彻底破坏 ASan 内存记帐,从而导致崩溃或虚假报告。

【讨论】:

  • 谢谢!那么dlsym("malloc", ...)__asm__(".symver malloc,malloc@GLIBC_2.2.5");差不多吗?
  • @AnastasiosAndronidis 不,完全没有
猜你喜欢
  • 1970-01-01
  • 2021-03-19
  • 2017-08-18
  • 1970-01-01
  • 1970-01-01
  • 2016-10-31
  • 2022-08-16
  • 2021-05-17
  • 2013-12-24
相关资源
最近更新 更多