Linux动态链接库.so的生成与使用

Linux动态链接库.so的生成与使用

用到以下三个文件,为以后展开相关攻击过程做铺垫。

main.c

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <unistd.h>

int print_test();

int main(){
while(1){
print_test();
sleep(5);
}
}

lib_ptrace_normal.c

1
2
3
4
5
6
7
#include <stdio.h>

int print_test()
{
printf("I am good guy");
return 0;
}

lib_ptrace_attack.c

1
2
3
4
5
6
7
#include <stdio.h>

int print_test()
{
printf("I am bad guy :P");
return 0;
}

使用如下命令编译so文件:

1
2
test@ubuntu:~/ptrace$ gcc -fPIC -shared lib_ptrace_normal.cpp  -o lib_normal.so
test@ubuntu:~/ptrace$ gcc -fPIC -shared lib_ptrace_attack.cpp -o lib_attack.so

参数说明:

如果想创建一个动态链接库,可以使用 GCC 的-shared选项。输入文件可以是源文件、汇编文件或者目标文件。

另外还得结合-fPIC选项。-fPIC 选项作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code);这样一来,产生的代码中就没有绝对地址了,全部使用相对地址,所以代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。

编辑/etc/ld.so.conf.d/libc.conf,在文件末尾添加生成so文件的目录,然后执行sudo ldconfig使设置生效。

之后执行来将 main.clib_normal.so 一起编译成main.out,当 main.out 运行时,会动态地加载链接库 lib_normal.so

1
gcc main.c -L. -l_normal -o main.out

参数说明:

  • -L:指定lib文件的目录,本例中lib_normal.somain.c处于同一目录下,所以使用.表示当前目录,如需指定其他目录可以写成:-L/usr/lib/xxx的形式
  • -l:指定lib文件的文件名称,在本例中将lib_normal.so分解为三部分:lib + _normal + .so,-l参数之后仅需写这三部分的中间部分即_normal

执行ldd命令查看main.out的链接情况,可以看到系统可以找到lib_normal.so的位置:

1
2
3
4
5
test@ubuntu:~/ptrace$ ldd main.out 
linux-vdso.so.1 => (0x00007fff045df000)
lib_normal.so => /home/test/ptrace/lib_normal.so (0x00007fa8428c0000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa8424f7000)
/lib64/ld-linux-x86-64.so.2 (0x000055ca59221000)

此时运行main.out,运行结果:

1
2
3
4
5
test@ubuntu:~/ptrace$ ./main.out 

I am good guy
I am good guy
I am good guy

此处有一点疑问,为何在程序刚运行时缺少了一次print_test()的调用,直接打印了\n?个人猜想是虚拟环境磁盘IO性能差导致此函数在so文件未被成功加载的时候跳过了?

Done!🍟

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×