加入收藏 | 设为首页 | 会员中心 | 我要投稿 开发网_新乡站长网 (https://www.0373zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

如何挟持动态库(4)-应用,查找内存泄露

发布时间:2023-01-12 11:10:05 所属栏目:Linux 来源:
导读:  前一篇文章提到的文件加密方案很有启发性,在应用层需要花费很多精力解决的需求,在更底层可以很彻底的解决。

  做 C 开发的同学对内存泄露一定非常熟悉,能否妥善高效的控制内存,几乎可以判断 C 语言开发
  前一篇文章提到的文件加密方案很有启发性,在应用层需要花费很多精力解决的需求,在更底层可以很彻底的解决。
 
  做 C 开发的同学对内存泄露一定非常熟悉,能否妥善高效的控制内存,几乎可以判断 C 语言开发工程师的水平。目前比较常见的做法是利用内存管理算法来解决内存泄露,这是另一个话题,可以参考我的专栏《恍然大明白》中 Python 的内存管理部分。
 
  对于一般的开发场景,难免会接手一些祖传代码,某些代码甚至部署在特殊的环境中,限制使用调试工具,一旦发生内存泄露就非常令人头疼。一些开发者就只能一行一行看代码,肉眼检测。
 
  黑掉 malloc 和 free
 
  我们已经可以非常熟练的挟持动态库,我们也可以通过相同的技术挟持 libc 的内存分配函数,在其中插入一些统计代码和日志,配合日志上下文,可以非常方便的找到内存泄露位置。
 
  下面是简单的代码实现:
 
  //fakemalloc.c
  ?
  #define _GNU_SOURCE
  ?
  #include
  #include
  #include
  #include
  ?
  void *malloc(size_t size) {
      printf("called..my malloc\n");
  ?
      void *(*glibc_malloc)(size_t size);
      // Find original malloc function
      glibc_malloc = dlsym(RTLD_NEXT, "malloc");
  ?
      if ( dlerror() != NULL)
      {
          puts("malloc symbol not found..\n");
          exit(1);
      }
  ?
      printf("This should call actual malloc now..\n");
      return (*glibc_malloc)(size);
  }
  ?
  ?
  void free(void * addr){
      if( NULL == addr){
          return;
      }
      printf("free memory at %p\n", addr);
  ?
      void (*glibc_free)(void *);
  ?
      glibc_free = dlsym(RTLD_NEXT, "free");
  ?
      if ( dlerror() != NULL)
      {
          puts("free symbol not found..");
          exit(1);
      }
  ?
      return glibc_free(addr);
  }
  这样每当申请、释放内存的时候都会打印一条信息,借助文本统计工具就可以很快确定内存泄露的大致位置,非常简单。
 
  总结
 
  个人的理解,动态库挟持是一种面向操作系统的开发思想,要求对操作系统有比较丰富的理解,从根本的角度提出一些解决方案,深度与操作系统合作,而非单纯的操作系统外层的 “用户”。
 
  简单回顾一下linux动态库,Linux 系统下可以通过 LD_PRELOAD 指定优先查找符号的动态库路径,让自己开发的动态库先于系统库函数被加载;再借助 dlsym(RTLD_NEXT, symbol) 代理默认库函数,完成库函数的代理。
 

(编辑:开发网_新乡站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!