如何让dtrace以非root权限运行跟踪命令?

Gyo*_*yom 56 macos dtrace root strace

OS X缺少linux strace,但它dtrace本来应该是更好的.

但是,我错过了对单个命令进行简单跟踪的功能.例如,在linux上我可以写入strace -f gcc hello.ccaputre所有系统调用,它给出了编译器编译程序所需的所有文件名列表(优秀的memoize脚本是基于这个技巧)

我想在mac上移植memoize,所以我需要一些strace.我真正需要的是gcc读取和写入文件的列表,所以我需要的更多是一个truss.我当然可以说dtruss -f gcc hello.c并获得一些相同的功能,但随后编译器运行root权限,这显然是不可取的(除了大量的安全风险,一个问题是该a.out文件现在由root拥有:-)

然后我尝试了dtruss -f sudo -u myusername gcc hello.c,但这感觉有点不对,并且无论如何都不起作用(a.out这次我得不到文件,不知道为什么)

所有长篇故事都试图激发我的原始问题:如何dtrace使用普通用户权限运行我的命令,就像strace在linux中一样?

编辑:似乎我不是唯一一个想知道如何做到这一点:问题#1204256与我的几乎相同(并且具有相同的次优sudo答案:-)

ken*_*orb 46

最简单的方法是使用sudo:

sudo dtruss -f sudo -u $USER whoami
Run Code Online (Sandbox Code Playgroud)

其他解决方案是首先运行调试器并监视新的特定进程.例如

sudo dtruss -fn whoami
Run Code Online (Sandbox Code Playgroud)

然后在另一个终端中运行:

whoami
Run Code Online (Sandbox Code Playgroud)

就那么简单.

您可以在手册中找到更棘手的参数: man dtruss


或者,您可以将dtruss附加到正在运行的用户进程,例如在Mac上:

sudo dtruss -fp PID
Run Code Online (Sandbox Code Playgroud)

或类似的Linux/Unix上使用strace:

sudo strace -fp PID
Run Code Online (Sandbox Code Playgroud)

另一个hacky技巧可能是执行命令,然后在附加到进程后立即执行.这里有些例子:

sudo true; (./Pages &); sudo dtruss -fp `pgrep -n -x Pages`
sudo true; (sleep 1 &); sudo dtruss -fp `pgrep -n -x sleep`
sudo true; (tail -f /var/log/system.log &); sudo dtruss -fp `pgrep -n -x tail`
Run Code Online (Sandbox Code Playgroud)

注意:

  • 第一个sudo只是在第一次运行时缓存密码,

  • 这个技巧不适用于快速命令行,ls, date因为它需要一些时间,直到调试器将附加到进程,

  • 你必须在两个地方输入你的命令,

  • 你可以忽略&将进程运行到后台,如果它已经这样做了,

  • 完成调试后,您必须手动终止后台进程(例如killall -v tail)

  • 你是一个摇滚明星,指出了dtruss的`-n`选项.这是正确答案的100%. (5认同)

wfa*_*ulk 8

-n参数dtruss将导致dtruss等待和检查相匹配的参数传递给进程-n.该-f选项仍将用于跟踪从匹配的进程分叉的进程-n.

所有这些意味着,如果你想要一个进程(为了争论,让我们说它是whoami)作为你的非特权用户运行,请按照下列步骤操作:

  1. 打开root shell
  2. dtruss -fn whoami
    • 这将等待一个名为"whoami"的进程存在
  3. 打开一个非特权的shell
  4. whoami
    • 这将执行并正常退出
  5. 在dtruss窗口中观察系统调用跟踪
    • dtruss不会自行退出 - 它将继续等待匹配的进程 - 所以当你完成时就要突破它

这个答案重复了@ kenorb的回应的后半部分,但它应该是一流的答案.


met*_*att 5

我不知道你是否可以像strace一样无创.

"sudo [to root] dtruss sudo [back to nonroot] cmd"的一个变体似乎在我的一些快速测试中效果更好:

sudo dtruss -f su -l `whoami` cd `pwd` && cmd....
Run Code Online (Sandbox Code Playgroud)

外部sudo当然是因为dtruss以root身份运行.

内部su回到我身边,使用-l它可以正确地重新创建环境,此时我们需要回到我们开始的地方.

我认为"su -l user"比"sudo -u user"更好,如果你想让环境成为用户通常获得的环境.那将是他们的登录环境; 我不知道是否有一种很好的方法让环境通过两个用户更改继承.

在你的问题中,你有一个关于"sudo dtruss sudo"解决方法的另一个抱怨,除了丑陋之外,是"我一直没有得到a.out文件,不知道为什么".我也不知道为什么,但在我的小测试脚本中,"sudo dtruss sudo"变体也无法写入测试输出文件,上面的"sudo dtruss su"变体确实创建了输出文件.


net*_*mer 5

不是你问题的答案,而是要知道的事情.OpenSolaris(部分)使用"权限"解决了这个问题 - 请参阅此页面.即使在OpenSolaris中,也不可能允许用户在没有任何额外权限的情况下使用自己的进程.原因是dtrace的工作方式 - 它内核中启用探测.因此,允许非特权用户探测内核意味着用户可以执行许多不需要的操作,例如通过在键盘驱动程序中启用探测来嗅探其他用户的密码!