【问题标题】:Catching output of linux command in background C++ program / bash script在后台 C++ 程序/bash 脚本中捕获 linux 命令的输出
【发布时间】:2016-05-16 16:01:05
【问题描述】:

我想创建将在后台运行的 c++ 程序或 bash 脚本,并且每当我使用所选命令时,例如

pwd 它将捕获该命令的输出,假设为~Desktop/folder1,并将该输出更改为You are in ~Desktop/folder1。所以结果将是该用户在使用命令pwd 后只会看到You are in ~Desktop/folder1

pwd 命令只是示例,我想修改其他命令的输出,如 ls、ps 等。

我希望脚本可以在所有终端中运行,也就是说,如果我打开另一个终端,它仍然会在该终端中捕获所选命令的输出。

问题:

是否有可能做 c++ 程序或 bash 脚本来做这样的事情?

【问题讨论】:

  • 当然可以。内核模块可以拦截所有写入。真正的问题是;你为什么要这个?
  • @JesperJuhl,当然,但是内核模块既不是 C++ 程序也不是 bash 脚本。
  • 或者,如果您下定决心要更改标准输出并且使用 c++ 进行编码,只需通过修改原始 src 代码并重新编译来重新设计输出。您可以为--old-style 添加一个标志以保留原始格式。再一次,真正的问题(这超出了 S.O. 的范围)是您为什么要这样做? ;-/ 祝你好运?
  • 我需要为我大学的实验室创建脚本或程序,这将对其他用户隐藏我的文件之一,我需要隐藏隐藏它的进程,所以我想我会抓住 ls命令并搜索我需要隐藏的文件并将其剪切掉,这样它就不会显示出来,与 ps 命令相同。然而问题是我不知道如何以及是否可以做到。编辑:修改原始 src 的问题是 ls 命令有 9000 行代码......真的很难找到我应该从哪里开始。
  • 非特权进程不能监控其他用户的进程,也不能干预他们的输出。但是,如果您的进程可以获得足够的权限,那么它可以简单地替换系统的ls 命令。它不需要掩饰自己,因为一旦它的工作(插入被黑的ls)完成,它就会退出。

标签: c++ linux bash background output


【解决方案1】:

您可以将 shell 函数定义放入您的 bash 环境配置脚本中,这将产生您描述的效果。例如,

~/.bash_profile:

# ...

pwd() {
  echo You are in $(command pwd)
}

export -f pwd

注意使用command 命令来避免shell 函数pwd 中的递归。还要注意 export -f 将函数导出到子进程。对于要覆盖的每个命令,您都需要一个类似的 sn-p。

根据您的系统和配置,将它们放在~/.bashrc 中可能更合适。或者,如果您希望它适用于每个用户,那么您可以将它们放在系统范围的 bash 配置脚本之一中。但请注意,用户将能够覆盖它。

【讨论】:

    【解决方案2】:

    首先,您的问题缺少两个重要参数。首先是哪些外壳需要受此影响。这是应该是系统范围的东西吗?只有一个用户?只是特定用户的几个特定 shell?

    第二个缺少的参数是需要什么权限。这是root应该做的事情吗?非特权用户?

    您希望拦截的每个此类命令都是一个系统调用。通常是execve,但有时它更具体(例如,pwd,根据定义,是一个内部 shell 命令)。假设您不希望编写内核模块(实现您想要的唯一真正方法),您将不得不更有创意。

    一种选择是将文件系统上的所有相关文件替换为您想要的替代版本。当然,如果您不是 root,这是不可能的。

    另一个更可能使用非特权用户的选项是使用ptrace 接口来控制您希望控制的shell 进程。但是请注意,这非常复杂,性能缓慢,并且只能在与运行 C++ 程序的用户相同的用户上工作。此外,最近的内核对简单地作为调试器附加到随机进程有进一步的保护,这意味着您需要禁用它(这需要 root),或者通过您的程序运行受影响的 shell。

    一个已经做了类似事情的程序是 fakeroot-ng。它设置了一个调试器,并附加到一个 shell,以便给它一个不同于真实系统的系统正在做什么的视图。你可以尝试破解代码来做你想做的事。使用multithreaded_debugger 分支可能会更容易,但它仍然不太稳定。

    【讨论】:

    • 它适用于系统范围,适用于所有用户。 permisson 没有真正的问题,因为我有 root 权限,因为我在自己的虚拟机上工作。我已经想更改命令的源代码并替换它们,但问题是简单的ls 命令有 9000 行代码,我不知道在哪里更改它。
    • @Nranir 最简单的方法是修改/重新编译bash(或您正在使用的任何外壳)
    • @Nranir,如果此时修改 9000 行 ls 对您来说挑战太大,那么我认为您可能会在更大的项目上不知所措。
    【解决方案3】:

    你问错问题了。

    如果您想要隐藏一组进程和文件,/etc/ld.so.preload 是您的朋友。

    您需要做的是编写一个共享对象文件,以确保如果有人试图获取您的“隐藏”文件所在目录的内容,您从回复中省略您的文件。同时,如果有人试图获取 /proc/ 目录的内容,则省略与您试图隐藏的进程对应的目录。

    您可以通过缓存其 inode/dev 对并检查它来轻松查看这是否是您希望更改响应的目录。这将对重命名、符号链接等具有弹性。

    在网上搜索如何编写 LD_PRELOAD 模块以获取有关如何以菊花链方式连接函数本身的说明。这明显比修改每个二进制文件要少。如果您知道自己在做什么,这可以包含在大约 200 行代码中。

    现在来了踢球者。您不需要将 LD_PRELOAD 环境变量放入每个进程。只需在/etc/ld.so.preload 中列出您的共享对象(使用 LD_PRELOAD 对其进行测试后),然后中提琴!您系统中的所有进程都会将您的库注入其中。

    不要忽视测试建议。在 /etc/ld.so.preload 中列出错误的文件可能会导致您的系统完全无法使用。

    为了额外的好处,一旦你完成了,安装chkrootkit 并运行它,然后看着它抱怨你的系统已被入侵。这是 rootkit 用来隐藏自身的(许多)技术之一。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-03
      • 1970-01-01
      • 2023-04-07
      • 2023-03-11
      • 1970-01-01
      • 2015-04-11
      • 2014-10-30
      相关资源
      最近更新 更多