我想拦截全局数据访问,并可能将全局数据访问重定向到另一个内存位置。我认为这可以通过用PIE二进制文件重写.got条目来完成。对于共享库,.got解析可能在运行时。让我们说示例代码:
// main.c
int a = 0x12;
extern void foo(void);
int main(int argc, char *argv[])
{
printf("a = 0x%x\n", a);
foo();
printf("a = 0x%x\n", a);
return 0;
}
// foo.c
extern int a;
void foo()
{
a++;
}
生成文件:
gcc -shared -fpic -Wl,-znow -g -o libfoo.so foo.c
gcc -o main main.c -Wl,-znow -g -fpie -pie -lfoo -L. -Wl,-rpath=.
汇编代码:
void foo()
{
550: 55 push %ebp
551: 89 e5 mov %esp,%ebp
553: e8 00 00 00 00 call 558 <foo+0x8>
558: 58 pop %eax
559: 81 c0 94 1a 00 00 add $0x1a94,%eax
55f: 8b 80 fc ff ff ff mov -0x4(%eax),%eax
a++;
565: 8b 08 mov (%eax),%ecx
567: 81 c1 01 00 00 00 add $0x1,%ecx
当共享库想要访问外部全局数据时,它将通过.got表访问。虽然.got表条目最初是ZERO。所以我的问题是加载器如何以及何时解析共享库的.got表?如果我想拦截这个,有没有办法做到这一点?比如使用LD_PRELOAD?