更改 Linux 中运行进程的功能

更改 Linux 中运行进程的功能

Linux 中是否可以更改正在运行的进程的功能?是否可以更改打开文件的路径(例如重定向输出)。

如果是的话,如何做?

答案1

你无法从外部改变这种过程的环境,但如果你真的必须这样做,你可以ptrace(2)流程(实际上是一个线程,但为了简单起见,我将继续说流程),并使用足够的工具来进行更改在运行过程中。当然,依赖于生产用途会很奇怪ptrace,但如果这是唯一的选择......


gdb可以做到这一点

您可以附加到一个进程(或一些具有更多 gdb-fu 的线程)并使其改变自己的行为并与之分离。如果做得足够快(即:脚本化),该过程将不会变得更明智。取决于进程运行及其动作在初始化时,您不能总是ptrace来自同一用户,然后需要 root 访问权限或至少CAP_SYS_PTRACE 能力。对流程所做的事情实际上已经完成了通过它自己:如果进程已经被允许更改其功能(通常需要CAP_SETPCAP),那么就有可能让自己这样做。如果不允许执行某项操作,那么ptrace即使是通过root 完成也无济于事。同样,关闭日志文件并在其他地方重新打开它也很容易。

一些 UL 问答的示例,其中一些是我的:

为了解决你的问题的第一个例子......


使用 gdb 限制正在运行的进程的功能

bash该示例将在以 root 身份运行(因此具有完整功能)的 shell上完成,使用gdb(也以 root 身份运行)。这很复杂,因为库卡的功能不知道程序是否没有链接到它,所以我选择了更简单但更乏味(因为它需要操作结构)的方法,它不需要任何开发环境,也不需要额外的 gdb-fu:直接使用系统调用定义在 gdb 中总是已知的。

第一学期:

# echo test > /tmp/test
# chown nobody /tmp/test
# chmod 600 /tmp/test
# cat < /tmp/test
test
# cat /tmp/test
test
# echo $$
5237
# grep ^Cap /proc/$$/status
CapInh: 0000000000000000
CapPrm: 0000003fffffffff
CapEff: 0000003fffffffff
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
#

第二学期:

# gdb -q -p 5237
Attaching to process 5237
Reading symbols from /bin/bash...(no debugging symbols found)...done.

[...]

0x00007fb774737681 in pselect () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) set $malloc=(void *(*)(long long)) malloc
(gdb) print $malloc(4*(2+3*2))
$1 = (void *) 0xc4ecc8
(gdb) set *((unsigned int *)($1))=0x20080522
(gdb) set *((unsigned int *)($1)+1)=getpid()
(gdb) print capget($1, (unsigned int *)$1+2)
$2 = 0
(gdb) set *((unsigned int *)($1)+2) &= ~(1<<1|1<<2)
(gdb) print capset($1, (unsigned int *)$1+2)
$3 = 0
(gdb) call free($1)
$4 = 0
(gdb) quit
A debugging session is active.

    Inferior 1 [process 5237] will be detached.

Quit anyway? (y or n) y
Detaching from program: /bin/bash, process 5237
# 

所以这个分配的内存,64位解决方法风格,对于需要的*cap_user_header_tcap_user_data_t[2]结构,设置一些魔法值,检索到的当前的工艺能力和已删除 CAP_DAC_OVERRIDECAP_DAC_READ_SEARCH从capability中有效设置,从而阻止其读取/tmp/test,最终释放分配的内存。

回到第一学期:

# grep ^Cap /proc/$$/status
CapInh: 0000000000000000
CapPrm: 0000003fffffffff
CapEff: 0000003ffffffff9
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
# cat < /tmp/test
bash: /tmp/test: Permission denied
# cat /tmp/test
test
#

有什么不同?使用重定向时,bash 进程无法再访问具有受限访问权限的非根文件,并且会失败(在 fork 之后但在 exec-ing 之前cat)。当(分叉和)执行一个新进程时,root 恢复其所有功能除非它们从另一个集合中删除:可以通过不同方法更改的能力边界集(prctl(PR_CAPBSET_DROP, ...))。这就是为什么cat在没有重定向的情况下运行仍然可以正常工作(对于)。

答案2

为了更改打开文件的路径,您可以使用硬链接,但它必须保留在与原始文件相同的文件系统上。一旦应用程序打开了文件,只有文件句柄和文件的索引节点才是重要的。硬链接只是为同一索引节点提供不同的文件名/路径。

如果您只想重命名/重新组织,这可能会起作用。请务必更新所有配置文件,以便在重新启动时会选择新位置。如果您想移动到新的文件系统以释放空间或其他东西,则此方法将不起作用。

有时发送特定的单个(通常是 SIGHUP),应用程序将关闭所有文件句柄,然后重新打开它们。在这种情况下,它通常会重新加载conf,因此也可能会选择一个新的文件路径。不过,此行为高度依赖于应用程序。根据数据类型,这也可能非常危险,并导致数据丢失或损坏。

虽然我并不乐观,但我不认为你可以改变流程的能力。您必须退出并重新启动。

相关内容