我们是否可以说流程(无论是否有子流程)完全反映在它们的(描述性)文件中?

我们是否可以说流程(无论是否有子流程)完全反映在它们的(描述性)文件中?

我们是否可以说,一个进程中的整个“系列”文件(分别由文件描述符表示)直接反映了该进程及其可能的子进程,以便分别查看文件描述符所描述的文件,可以告诉我们该进程及其可能的子进程的确切性质?

换句话说,如果你看看每个文件(按 0-X 等相应顺序用文件描述符表示),它会告诉您进程或/和子进程的性质吗?

如果整个过程确实仅由这些文件组成的话,我相信答案是肯定的。

答案1

简短回答:否

长答案:进程使用的文件描述符不够静态,无法对进程进行可靠的分析。文件可以打开和关闭,相应的数据结构将由内核回收。

答案2

反例:编写两个程序,让它们都休眠 100 秒,然后分别将 1 和 2 写入 stderr。从同一个 shell 启动这两个程序,并将它们置于后台。您将无法通过查看文件描述符来区分它们,因为这两个程序的文件描述符是相同的。

变体:让它们打开同一个文件,所以如果它不受标准描述符的限制,它甚至不起作用。

答案3

我想我没有完全理解你在问什么...请添加一些解释。

但据我了解,

可以类比如下:

如果我观察 A 并看到他们与谁交谈,我能确定 A 的意图吗?

在这种情况下,答案很模糊。您可能能够看到 A 正在与执法部门的某个重要人物交谈,也许还与一些与有组织犯罪有关的人交谈。但要确切地说出 A 的动机将极其困难(不可能?)。他们是卧底警察,还是受法官控制的罪犯?

仅凭这些知识你无法可靠地读出任何内容。

如果您设法确定更多信息,例如正在执行的 I/O,那么您将能够更清楚地了解情况。


换句话说,如果您查看每个文件(按 0-X 等相应顺序由文件描述符表示),它会告诉您进程和/或子进程的性质吗?

我觉得你对“文件描述符' 是。文件描述符由一个简单的数字 ( int) 标识 - 返回值open()... 但在内核中,文件描述符具有与其相关联的信息。请参阅struct file


如果整个过程确实仅由这些文件组成的话,我相信答案是肯定的。

这也包含了一些误解的证据。流程不是“仅由这些文件组成“,而是访问这些文件现在。我们可以通过运行以下命令来显示这一点:

$ ls -l /proc/self/fd
total 0
lrwx------ 1 attie attie 64 May 20 15:20 0 -> /dev/pts/3
lrwx------ 1 attie attie 64 May 20 15:20 1 -> /dev/pts/3
lrwx------ 1 attie attie 64 May 20 15:20 2 -> /dev/pts/3
lr-x------ 1 attie attie 64 May 20 15:20 3 -> /proc/13103/fd

正如@grawity 在评论中指出的那样,open()将返回下一个可用文件描述符,从零开始填补任何空白。您在上面看到的是当前打开的文件的快照,并且会随着时间的推移而变化。


您无法看到ls上述列表中的二进制文件或其任何直接依赖项:

$ ldd $(which ls)
        linux-vdso.so.1 =>  (0x00007fff569ef000)
        libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007feeb33df000)
        libacl.so.1 => /lib/x86_64-linux-gnu/libacl.so.1 (0x00007feeb31d7000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007feeb2e0e000)
        libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007feeb2bd0000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007feeb29cc000)
        /lib64/ld-linux-x86-64.so.2 (0x00007feeb361a000)
        libattr.so.1 => /lib/x86_64-linux-gnu/libattr.so.1 (0x00007feeb27c6000)

当您尝试“执行ls“链接器实际上就是读取库文件来整理和‘链接’完整进程映像。当ls开始执行时,这些数据已经在内存中,文件不再‘打开’。

一些应用程序可能会使用“插件”,或“动态”加载提供功能的附加文件(见dlopen()),但这只是一种极端情况,与典型行为相去甚远——我的机器上当前运行的所有进程都没有打开共享对象 ( *.so) 文件。


总而言之,我仍然同意我最初的回答,

没有明确的方法来通过查看某个进程打开了哪些文件来确定该进程的行为。

就确定子进程的性质而言,这是不可能的 - 您能查看init并确定系统的完整运行时配置吗?

答案4

简短的回答:是的,但是效果非常有限。

事实上,监视进程的行为是防病毒软件的主要功能之一,因为打开的文件还包括 DLL(Windows)或共享库(Linux)。判断进程行为的防病毒软件会在进程打开过多或过于敏感的文件或尝试访问敏感文件夹时发出警报。在这种情况下,Windows/Linux 可能会请求用户许可。

可以检测到某个进程正在打开 DLL/共享库,但要找出它调用了哪些 API,需要分析它所做的系统调用,防病毒软件可以通过检查进程的可执行文件本身来找到这些调用。

不要忘记可执行文件本身是打开的文件之一,因此对它的分析可以准确地找出它使用了哪些 DLL/共享库,从而可以很好地理解它的作用。

操作系统将监视进程的行为,并将其归类为 CPU 密集型、IO 密集型或混合型调度类,这将影响其执行优先级和允许的系统资源份额。

子进程通常会继承其父进程的所有打开的文件描述符,因此在操作系统和防病毒软件的眼中,它将以相同的分类开始其生命,但稍后可能会通过其操作移动到另一个分类。

相关内容