rand()是一个libc函数,如果一个具有相同函数名的共享库被加载到二进制程序中,它将代替真实的函数。
正常的业务代码:hello.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
int a = rand();
printf("a = %d\n", a);
return 0;
}
用于劫持的共享库:rand_hijiack.c
int printf (const char *__restrict __fmt, ...);
int rand(void)
{
printf("call hijack rand()\n");
return 404;
}
编译:
gcc hello.c -o hello
gcc -fPIC -shared rand_hijack.c -o rand_hijack.so
第一个选项是-FPIC
选项。此选项将二进制文件编译为“位置无关代码”(Position Independent Code),这通常是您如何构建共享库的方式。这会使代码被加载到随机地址空间中,并阻止其尝试对跳转或调用固定地址。
第二个选项是-shared
选项,它告诉gcc将其构建为共享库ELF。
运行:
LD_PRELOAD=./rand_hijack.so ./hello
call hijack rand()
a = 404
设置一个名为LD_PRELOAD的环境变量,并将其值设置为共享库的相对路径或共享库的绝对路径。