前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C/C++|链接|动态链接库

C/C++|链接|动态链接库

作者头像
朝闻君
发布2021-11-22 10:53:43
5820
发布2021-11-22 10:53:43
举报
文章被收录于专栏:用户9199536的专栏

我们经常在游戏目录下看见dll文件,这是windows下的动态链接库。在linux下我们可以使用-shared -fpic生成so文件。

动态链接的好处在于,当我们需要变更函数实现时,不需要重新编译整个可运行文件,只需要修改动态链接库即可,所以破解游戏的时候通常补丁就是一个dll而已。快忘光了,写个随笔复习一下,大一知识简单勿怪。

内存布局

  • GOT(Global offset table) - 动态函数入口,elf中位于.got段,不可执行数据
  • PLT(Procedure linkage table) - 桩函数,elf中位于.got.plt段,可执行代码
  • 动态链接库 - 包含函数和变量,有不可执行数据和可执行代码

原理

下面这个是函数调用原理,如果是变量的话直接获得地址就好。

  • PLT由调用GOT代码+桩代码组成。桩代码用于动态修改GOT表。
  • GOT初始指向桩代码,后来指向动态函数。
  • PLT索引 = 函数索引x+1
  • GOT索引 = 函数索引x+3

初次调用,惰性加载

  • 调用PLT[x+1]
  • 跳转*GOT[x+3](桩代码地址)
  • 传递动态链接函数索引x
  • 跳转PLT[0]
  • 传递动态链接表地址GOT[1]
  • 跳转*GOT[2](动态链接器函数地址)
  • 修改GOT[x+3]为动态函数地址

后续调用,直接跳转

  • 调用PLT[x+1]
  • 跳转*GOT[x+3](动态函数地址)

应用

代码语言:javascript
复制
 #include <dlfcn.h>
 void *dlopen(const char *filename, int flag) ;
			returns: ptr to handle if OK, NULL on error
 void *dlsym(void *handle, char *symbol) ;
			returns: ptr to symbol if OK, NULL on error
 int  dlclose(void *handle) ;
			returns: 0 if OK, -1 on error
 const char dlerror(void) ;
			returns: errormsg if previous call to
 			dlopen, dlysym, or dlclose failed,
 			NULL if previous call was OK

dlopen为mmap+解析符号表

  • RTLD_LAZY/RTLD_NOW决定是否惰性加载
  • RTLD_GLOBAL/RTLD_LOCAL决定符号是否为其他动态链接库可见
  • RTLD_DEEPBIND优先查找动态链接库的符号而非全局符号
  • RTLD_NOLOAD 不加载动态链接库,可用于修改之前的flag
  • RTLD_NODELETE close时不会卸载,因此静态变量在reopen时不会重新初始化

dpsym从符号表中寻址函数、变量

dlclose减少mmap引用计数,为0后munmap

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
int
main(int argc, char **argv)
{
    void *handle;
    double (*cosine)(double);
    char *error;
   handle = dlopen("libm.so", RTLD_LAZY);
    if (!handle) {
        fprintf(stderr, "%s\n", dlerror());
        exit(EXIT_FAILURE);
    }
   dlerror();
   *(void **) (&cosine) = dlsym(handle, "cos");
   if ((error = dlerror()) != NULL)  {
        fprintf(stderr, "%s\n", error);
        exit(EXIT_FAILURE);
    }
   printf("%f\n", (*cosine)(2.0));
   dlclose(handle);
   exit(EXIT_SUCCESS);
}

引用

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 内存布局
  • 原理
  • 应用
  • 引用
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档