8

我正在开发一个使用 ptrace(2) 监视其他进程的系统调用的软件。不幸的是,大多数现代操作系统都实现了某种快速的用户模式系统调用,在 Linux 中称为vsyscalls

有没有办法禁止对单个进程使用 vsyscalls/vDSO,或者,如果不可能,对整个操作系统禁用?

4

4 回答 4

7

尝试echo 0 > /proc/sys/kernel/vsyscall64

如果您尝试对 gettimeofday 调用进行 ptrace 并且它们没有出现,那么系统使用的时间源是什么(pmtimer、acpi、tsc、hpet 等)。我想知道您是否会通过尝试将计时器强制设置为像 pmtimer 这样较旧的东西来取笑我。许多 gtod 计时器特定优化之一可能会导致您的 ptrace 调用被避免,即使 vsyscall 设置为零也是如此。

于 2011-11-26T16:59:55.610 回答
4

有没有办法禁止对单个进程使用 vsyscalls/vDSO,或者,如果不可能,对整个操作系统禁用?

事实证明,有一种方法可以有效地禁用单个进程的链接 vDSO,而无需在系统范围内使用ptrace

您所要做的就是在它返回之前停止被跟踪的进程并从辅助向量execve中删除AT_SYSINFO_EHDR条目(它直接位于指向 in 的内存区域的环境变量之后rsp)。PTRACE_EVENT_EXEC是这样做的好地方。

AT_SYSINFO_EHDR是内核用来告诉系统链接器 vDSO 在进程地址空间中的映射位置。如果此条目不存在,ld则似乎系统未映射 vDSO。

请注意,这不会以某种方式从您的进程内存中取消映射 vDSO,它只是在链接其他共享库时忽略它。如果作者真的愿意,恶意程序仍然可以与之交互。

我知道这个答案有点晚了,但我希望这些信息能让一些可怜的人头疼

于 2018-09-19T09:16:21.290 回答
3

对于较新的系统echo 0 > /proc/sys/kernel/vsyscall64可能无法正常工作。在 Ubuntu 16.04 中,可以通过在参数下添加内核参数vdso=0来在系统范围内禁用 vDSO :./etc/default/grubGRUB_CMDLINE_LINUX_DEFAULT

重要提示:参数GRUB_CMDLINE_LINUX_DEFAULT可能会被 中的其他配置文件覆盖/etc/default/grub.d/...,因此请仔细检查何时添加您的自定义配置。

于 2017-05-16T01:09:10.450 回答
2

采用Tenders McChiken 的方法,我确实创建了一个包装器,它为任意二进制文件禁用 vDSO,而不影响系统的其余部分:https ://github.com/danteu/novdso

一般程序非常简单:

  1. 使用 ptrace 等待 execve(2) 返回
  2. 找到辅助向量的地址
  3. 用 AT_IGNORE 覆盖 AT_SYSINFO_EHDR 条目,告诉应用程序忽略以下值
于 2020-09-09T11:46:49.340 回答