加入收藏 | 设为首页 | 会员中心 | 我要投稿 济源站长网 (https://www.0391zz.cn/)- 数据工具、数据仓库、行业智能、CDN、运营!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

教你如何对一个可执行程序进行拦截和包装?

发布时间:2022-07-03 22:44:30 所属栏目:Linux 来源:互联网
导读:文中一共讨论了3种方法,来实现对【函数】进行拦截: 在编译阶段插桩; 在链接阶段插桩; 在执行阶段插桩; 昨天一个网友提了另外一个问题:如何对一个可执行程序进行拦截? 这里就引出一个问题了: 既然上面这6个命令都链接到systemctl,那么当systemctl被执行
  文中一共讨论了3种方法,来实现对【函数】进行拦截:
 
  在编译阶段插桩;
  在链接阶段插桩;
  在执行阶段插桩;
  昨天一个网友提了另外一个问题:如何对一个可执行程序进行拦截?

  这里就引出一个问题了:
 
  既然上面这6个命令都链接到systemctl,那么当systemctl被执行的时候,它是如何知道它是被哪一个命令调用的呢?
 
  看一下源码就知道了:通过参数 argv[0] 来获得的。
 
  我们知道,main函数通过argc和argv[]来获取所有的参数,如下:
 
  复制
  // 测试文件:test1.c
 
  #include <stdio.h>
 
  int main(int argc, char *argv[])
  {
      printf("argc = %d n", argc);
      for (int i = 0; i < argc; i++)
           printf("argv[%d] = %s n", i, argv[i]);
      return 0;
 
  可以看到:argv[0] = ./test1,因为我们是在命令行直接调用test可执行程序的,这很容易理解。
 
  那么:如果test是被一个软链接调用的呢?
 
  测试一下,创建软链接:
 
  复制
  $ ln -s test1 link1
  1.

  执行一下:
 
  此时,argv[0] = ./link1。
 
  也就是说:第一个参数存放的是软链接文件路径,systemctl 的道理也是如此!
 
  知道了这个原理,那我们就可以在reboot与systemc之间横叉一刀,增加一个中间可执行文件:
 
  为了便于描述,我们把这个中间文件创建为脚本pre_systemctl.sh,然后把root软链接到这个脚本。
 
  注意:在理解原理之前,建议不要直接用 reboot 等系统命令进行操作,可以自己写一些测试程序,例如上面的 test。
 
  创建了pre_systemctl.sh脚本之后,并且把reboot软链接到它,在脚本中输入如下内容:
 
  此时,在命令行中执行reboot命令,就会执行这个脚本,并且这个脚本也能够正确的把/sbin/root作为第0个参数传递给/bin/systemctl,如下图所示:
 
  在这个脚本中,可以在执行systemctl之前,做任何需要关机前需要处理的一些事情。
 
  问题似乎是解决了,但是好像还有一个问题:
 
  如果用户在执行命令时输入了一些其它的参数,这个脚本程序也应该透明的把这些参数传递给 systemctl 才可以!
 
  为了便于观察,我们在脚本中多打印个参数,并通过exec来启动systemctl,并且强制把参数$0设置为systemctl的第0个参数:
 
  这个脚本文件中的重点是最后一条命令:
 
  复制
  exec -a $0 /bin/systemctl $*
  1.
  此时,在命令行中执行reboot指令,输出如下:
 
  如此调用systemctl,就解决了刚才提出的问题,而且通过 $*,可以把任意多个参数透明的传递下去。

(编辑:济源站长网)

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

    热点阅读