【问题标题】:Get other process' argv in OS X using C使用 C 在 OS X 中获取其他进程的 argv
【发布时间】:2016-11-09 11:59:39
【问题描述】:

我想获取其他进程的 argv,例如 ps。

我使用的是在 Intel 或 PowerPC 上运行的 Mac OS X 10.4.11。

首先,我阅读了ps和man kvm的代码,然后我写了一些C代码。

#include <kvm.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/sysctl.h>
#include <paths.h>

int
main(void) {
    char errbuf[1024];
    kvm_t *kd = kvm_openfiles(_PATH_DEVNULL, NULL, _PATH_DEVNULL, O_RDONLY, errbuf);
    int num_procs;
    if (!kd) { fprintf(stderr, "kvm_openfiles failed : %s\n", errbuf); return 0; }
    struct kinfo_proc *proc_table = kvm_getprocs(kd, KERN_PROC_ALL, 0, &num_procs);

    for (int i = 0; i < num_procs; i++) {
        struct kinfo_proc *pproc = &proc_table[i];
        char **proc_argv = kvm_getargv(kd, pproc, 0);
        printf("%p\n", proc_argv);
    }

    kvm_close(kd);
    return 0;
}

在 PowerPC 上运行时,kvm_getargv() 始终返回 NULL。跑的时候 在 Intel 上,kvm_openfiles() 失败,错误为 /dev/mem: No such file or directory。

当然,我知道许可。

其次,我尝试了 sysctl。

#include <sys/sysctl.h>
#include <stdio.h>
#include <stdlib.h>
#define pid_of(pproc) pproc->kp_proc.p_pid

int
main(void) {

   int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
   int buffer_size;
   sysctl(mib, 4, NULL, &buffer_size, NULL, 0);

   struct kinfo_proc *result = malloc(buffer_size);
   sysctl(mib, 4, result, &buffer_size, NULL, 0);

   int num_procs = buffer_size / sizeof(struct kinfo_proc);
   for (int i = 0; i < num_procs; i++) {
       struct kinfo_proc *pproc = result + i;
       int mib[3] = { CTL_KERN, KERN_PROCARGS, pid_of(pproc) }; // KERN_PROC_ARGS is not defined
       char *proc_argv;
       int argv_len;
       sysctl(mib, 3, NULL, &argv_len, NULL, 0);
       proc_argv = malloc(sizeof(char) * argv_len);
       sysctl(mib, 3, proc_argv, &argv_len, NULL, 0);
       fwrite(proc_argv, sizeof(char), argv_len, stdout);
       printf("\n");
       free(proc_argv);
   }

   return 0;
}

通过 fwrite,我得到了 argv[0] 但 argv[1..] 不是(环境变量 打印出来。)

没有其他办法了吗?

【问题讨论】:

  • 你想做什么?您可以作为调试器附加到进程,但这是破坏安全性的唯一正当理由。
  • 我想将工作流程视为数据。我明白了,安全很重要。但是,为什么ps可以访问argv?我也可以解析 ps 的输出,但我想要整个 argv。

标签: c macos argv


【解决方案1】:

在 10.6 中,KERN_PROCARGS2 可用:https://gist.github.com/770696

这种方式用于ps,MacFUSE上的procfs等

【讨论】:

    【解决方案2】:

    实际上,我正在编写的 Python 库也需要同样的东西,在搜索过程中,我发现了另一个用 C 代码实现此功能的 Python 库 (PSI)。它是列出进程的 python 模块代码的一部分,还包括列出每个进程的参数。您可以查看源代码作为一个工作示例:

    darwin_process.c - 向下滚动到 set_exe() 以获取相关代码

    注意:该网站真的很慢,所以在加载时您必须有点耐心。

    【讨论】:

    • 谢谢,杰。我再次尝试浏览和复制您的代码,我得到了 argv!
    • 那个链接坏了;该文件不再存在。我花了一段时间浏览项目的源代码,归结为他们使用的是“sysctl”。该代码的当前位置在 src/arch/darwin_process.c 中。希望对遇到这个问题的其他人有所帮助。
    • 带有代码的相关链接似乎返回502 – Bad Gateway错误,@jay。如果可能,请修复它,因为后面许多问题的答案都指向这篇文章。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2014-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多