在我尝试让“Steam for Linux”在 Debian 上运行时,我遇到了一个问题。libcef
(Chromium Embedded Framework)可以很好地使用GLIBC_2.13
(Debian 测试中的 eglibc 可以提供),但需要一个讨厌的额外功能GLIBC_2.15
(eglibc 无法提供):
$ readelf -s libcef.so | grep -E "@GLIBC_2\.1[4567]"
1037: 00000000 0 FUNC GLOBAL DEFAULT UND __fdelt_chk@GLIBC_2.15 (49)
2733: 00000000 0 FUNC GLOBAL DEFAULT UND __fdelt_chk@@GLIBC_2.15
我的攻击计划是LD_PRELOAD
创建一个仅提供这些功能的 shim 库。这似乎不起作用。我真的很想避免安装GLIBC_2.17
(因为它在 Debian 实验中;即使 Debian sid 仍然有GLIBC_2.13
)。
这是我尝试过的。
fdelt_chk.c
基本上是从 GNU C 库中偷来的:
#include <sys/select.h>
# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
# define _strong_alias(name, aliasname) \
extern __typeof (name) aliasname __attribute__ ((alias (#name)));
unsigned long int
__fdelt_chk (unsigned long int d)
{
if (d >= FD_SETSIZE)
__chk_fail ();
return d / __NFDBITS;
}
strong_alias (__fdelt_chk, __fdelt_warn)
我的Versions
脚本如下所示:
GLIBC_2.15 {
__fdelt_chk; __fdelt_warn;
};
然后我按如下方式构建库:
$ gcc -m32 -c -fPIC fdelt_chk.c -o fdelt_chk.o
$ gcc -m32 -shared -nostartfiles -Wl,-s -Wl,--version-script Versions -o fdelt_chk.so fdelt_chk.o
但是,如果我然后运行 Steam(首先使用一堆额外的东西让它工作),加载器仍然拒绝找到符号:
% LD_LIBRARY_PATH="/home/tinctorius/.local/share/Steam/ubuntu12_32" LD_PRELOAD=./fdelt_chk.so:./steamui.so ./steam
./steam: /lib/i386-linux-gnu/i686/cmov/libc.so.6: version `GLIBC_2.15' not found (required by /home/tinctorius/.local/share/Steam/ubuntu12_32/libcef.so)
.so
但是,我刚刚构建的版本也提供了版本符号:
% readelf -s fdelt_chk.so
Symbol table '.dynsym' contains 8 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FUNC GLOBAL DEFAULT UND __chk_fail@GLIBC_2.3.4 (3)
2: 0000146c 0 NOTYPE GLOBAL DEFAULT ABS _edata
3: 0000146c 0 NOTYPE GLOBAL DEFAULT ABS _end
4: 00000310 44 FUNC GLOBAL DEFAULT 11 __fdelt_warn@@GLIBC_2.15
5: 00000310 44 FUNC GLOBAL DEFAULT 11 __fdelt_chk@@GLIBC_2.15
6: 00000000 0 OBJECT GLOBAL DEFAULT ABS GLIBC_2.15
7: 0000146c 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
在这一点上,我不知道我能做些什么来欺骗加载程序(谁?)选择我的符号。我是否朝着正确的方向前进?