全局符号介入
全局符号介入是一种机制,允许一个符号(通常是一个函数)被另一个同名符号替换或覆盖。这通常发生在动态链接过程中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*
# ALLOCATED CHUNKS
# +---------------------------+
# | METADATA |
# |---------------------------| <-- Pointer returned by malloc points to
# | | the user data section of the chunk
# | USER DATA |
# | |
# |---------------------------|
# | METADATA |
# +---------------------------+ } Chunk 1
# +---------------------------+
# | METADATA |
# |---------------------------|
# | |
# | USER DATA |
# | |
# |---------------------------|
# | METADATA |
# +---------------------------+ } Chunk 2
*/
假设有这样一个场景
- A.so和B.so都有一个header.h的文件,各自include这个文件到cpp中,这个文件里有一个info结构体,实现了info.reset()方法
- B.so中,使用new Data()创建一个data对象,这个时候其实分两步走了
- sizeof(data), 这个行为是编译时,所以这个内部info的size是在编译时确定的
- new (mem) Data(), 里面会调用info.reset(),这个行为是在运行时,所以这个info.reset()是在运行时确定的
- 此时,执行这个构造的时候,先找到了A.so中的info.reset(),然后执行了A.so中的info.reset(),后面的B.so中的info.reset()都会被忽略
因此,他用了自己的info结构体,执行了别人的构造函数,这就是全局符号介入的问题。如果
新结构体的reset函数里额外的成员赋值导致了写入内存超过了老结构体的size,堆内存越界
怎么调查
ldd查看链接顺序,具体的符号查看nm, 找到相同的符号,这个符号一般是W的,弱符号。
REF
This post is licensed under CC BY 4.0 by the author.