简体   繁体   English

在后台C ++程序/ bash脚本中捕获linux命令的输出

[英]Catching output of linux command in background C++ program / bash script

I want to create c++ program or bash script that will run in background and whenever i use chosen command for example 我想创建将在后台运行的c ++程序或bash脚本,例如,每当我使用选择的命令时

pwd it will catch output of that command which will be let's say ~Desktop/folder1 and it will change that output to You are in ~Desktop/folder1 . pwd它将捕获该命令的输出,即~Desktop/folder1 ,它将输出更改为You are in ~Desktop/folder1 So the result would be that user, after using command pwd will see only You are in ~Desktop/folder1 . 因此,结果是该用户在使用命令pwd将仅看到You are in ~Desktop/folder1

Pwd command is just example, i want to modify output of other commands like, ls, ps, and so on. pwd命令只是示例,我想修改其他命令(如ls,ps等)的输出。

I want the script to work in all terminals, by that i mean if i open another terminal it would still catch output of chosen commands in that terminal. 我希望脚本在所有终端中都能正常工作,也就是说,如果我打开另一个终端,它仍然会在该终端中捕获所选命令的输出。

QUESTION: 题:

Is it even possible to do c++ program or bash script that would do such thing? 甚至有可能做这样的事情的c ++程序或bash脚本吗?

You can put shell function definitions into your bash environment configuration scripts that will have the effect you describe. 您可以将shell函数定义放入您的bash环境配置脚本中,以达到您描述的效果。 For example, 例如,

~/.bash_profile: 〜/ .bash_profile:

# ...

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

export -f pwd

Note the use of the command command to avoid recursion in shell function pwd . 请注意,使用command命令可避免在shell函数pwd递归。 Note also the export -f to export the function to child processes. 另请注意export -f将功能导出到子进程。 You would need a snippet like that for every command you want to override. 对于要覆盖的每个命令,您都需要一个类似的代码段。

Depending on your system and configuration, it might be more appropriate to put them in ~/.bashrc instead. 根据您的系统和配置,将它们放在~/.bashrc可能更合适。 Or if you want it to apply to every user, then you can put those in one of the system-wide bash configuration scripts. 或者,如果您希望它适用于每个用户,则可以将其放在系统级bash配置脚本之一中。 Note, however, that users will be able to override it. 但是请注意,用户将能够覆盖它。

First, missing from your question are two important parameters. 首先,您的问题中缺少两个重要参数。 The first is which shells need to be affected by this. 首先是哪些外壳需要受到此影响。 Is this something that is supposed to be system wide? 这应该是系统范围的吗? Just one user? 只有一个用户? Just a few specific shells of a specific user? 只是特定用户的几个特定Shell?

The second missing parameter is what permissions are needed. 第二个缺少的参数是需要哪些权限。 Is this something that root is supposed to do? 这是根应该做的事情吗? A non-privileged user? 非特权用户?

Each such command you wish to intercept is a system call. 您希望拦截的每个此类命令都是一个系统调用。 Usually it's execve , but sometimes it's something more specific ( pwd , for example, is, by definition, an internal shell command). 通常它是execve ,但有时它更具体(例如,根据定义, pwd是内部shell命令)。 Assuming you do not wish to write a kernel module (the only real way to do what you want), you will have to be a little more creative. 假设您不希望编写内核模块(做您想要的事情的唯一真实方法),那么您将不得不变得更有创造力。

One option is to replace all the relevant files on the filesystem with alternative versions that do what you want. 一种选择是用满足您需要的替代版本替换文件系统上的所有相关文件。 This is, of course, not possible if you are not root. 当然,如果您不是root用户,这是不可能的。

Another option that is more possible using non-privileged user is to use the ptrace interface to take control over the shell processes you wish to control. 使用非特权用户更可能的另一种选择是使用ptrace接口来控制您希望控制的Shell进程。 Be forewarned, however, that this is extremely complicated, slow in performance, and will only work on the same user as the one running the C++ program. 但是请注意,这非常复杂,性能低下,并且只能与运行C ++程序的用户在同一用户上使用。 In addition, recent kernels have further protection against simply attaching to a random process as a debugger, which means you will need to either disable it (which requires root), or run the affected shells through your program. 此外,最近的内核还提供了进一步的保护,以防止简单地作为调试器附加到随机进程,这意味着您将需要禁用它(需要root),或者通过程序运行受影响的shell。

One program that already does something similar is <shameless_plug> fakeroot-ng </shameless_plug>. 已经执行类似操作的一个程序是<shameless_plug> fakeroot-ng </ shameless_plug>。 It sets up a debugger, and attaches to a shell in order to give it a different view of what the system is doing than the real system. 它设置调试器,并将其附加到外壳程序上,以便为它提供与实际系统不同的视图。 You can try and hack the code to do what you want. 您可以尝试破解代码以执行所需的操作。 This will probably be easier with the multithreaded_debugger branch, but that one is still not quite stable. 使用multithreaded_debugger分支可能会更容易,但是仍然不够稳定。

You have asked the wrong question. 您问错了问题。

If what you're trying to do is to hide a set of processes and files, /etc/ld.so.preload is your friend. 如果您要隐藏一组进程和文件,则/etc/ld.so.preload是您的朋友。

What you need to do is to write a shared object file that re-implements readdir and readdir_r (two functions should, more or less, do it) in a way that makes sure that if someone tries to get the content of the directory where your "hidden" files are, you omit your files from the reply. 您需要做的是编写一个共享对象文件,该文件以某种方式重新实现readdirreaddir_r (两个函数应该或多或少地实现),以确保如果有人尝试获取该目录的内容, “隐藏”文件是,您在答复中忽略了文件。 At the same time, if someone tries to get the content of the /proc/ directory, you omit the directories corresponding to the processes you are trying to hide. 同时,如果有人尝试获取/ proc /目录的内容,则将忽略与您要隐藏的进程相对应的目录。

You can easily see whether this is the directory you wish to change the responses to by caching its inode/dev pair, and checking it. 您可以通过缓存其inode / dev对并检查它来轻松查看这是否是您希望将响应更改为的目录。 This will be resilient to renaming, symlinking etc. 这将对重命名,符号链接等具有弹性。

Search the net for how to write an LD_PRELOAD module for instructions on how to daisy chain the functions themselves. 在网上搜索如何编写LD_PRELOAD模块,以获取有关如何菊花链连接功能本身的说明。 This is considerably less work than modifying each and every binary out there. 这比修改每个二进制文件少得多。 If you know what you are doing, this can be wrapped up in ~200 lines of code. 如果您知道自己在做什么,则可以将其包装成约200行代码。

And now comes the kicker. 现在来了。 You do not need to put in the LD_PRELOAD environment variable to each and every process. 您无需将LD_PRELOAD环境变量放入每个进程。 Simply list your shared object (after testing it with LD_PRELOAD) in /etc/ld.so.preload , and viola! 只需在/etc/ld.so.preload和viola中列出您的共享库(用LD_PRELOAD测试后)即可! All the processes in your system will have your libary injected to it. 系统中的所有进程都将注入您的库。

Don't ignore the testing suggestion. 不要忽略测试建议。 Listing the wrong file in /etc/ld.so.preload might render your system completely unusable. 在/etc/ld.so.preload中列出错误的文件可能会使您的系统完全无法使用。

For added bonus, once you're done, install chkrootkit and run it, and watch as it complains that your system has been compromised. 要获得额外的好处,请在完成后安装chkrootkit并运行它,并观察它抱怨您的系统已受到威胁。 This is one of the (many) techniques used by rootkits in order to hide themselves. 这是rootkit用来隐藏自身的(许多)技术之一。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM