利用SystemTap,判断内核函数的参数后,才更改返回值?

接下来将展示下chatgpt给出的答案(笔者也没有运行,不保证正确性)。

SystemTap 概述

SystemTap 是一个动态追踪工具,可以用来监控内核和用户空间程序的行为。你可以通过编写脚本来插桩内核函数,并分析函数参数、返回值等信息。

在这个教程中,我们将演示如何创建一个 SystemTap 脚本,挂钩内核函数、检查参数,并在满足特定条件时修改函数的返回值。

创建SystemTap 脚本

我们以sys_open系统调用为例。sys_open用于打开文件,它接受两个主要参数:路径和打开标志。我们将判断路径是否是/etc/passwd,如果是,则修改返回值(模拟无法打开该文件)。

创建一个新的 SystemTap 脚本文件,比如check_open.stp,并编辑该文件,在文件中输入以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
probe syscall.open {
// 获取传入的路径参数
filename = user_string($filename)

// 打印文件路径
printf("Trying to open: %s\n", filename)

// 判断路径是否为 /etc/passwd
if (filename == "/etc/passwd") {
// 如果是 /etc/passwd,则返回 -EACCES,表示访问被拒绝
printf("Blocking access to /etc/passwd\n")
return -EACCES
}
}
  • probe syscall.open:我们使用 syscall.open 来挂钩 sys_open 系统调用。这将允许我们监视所有尝试打开文件的操作。
  • user_string($filename):该函数提取文件路径参数。我们使用 user_string() 来获取用户空间传入的字符串。
  • if (filename == "/etc/passwd"):这里检查传入的文件路径是否为 /etc/passwd
  • return -EACCES:如果路径是 /etc/passwd,我们通过 return 语句修改返回值,返回 -EACCES,表示访问被拒绝。

运行 SystemTap 脚本

在创建了脚本后,需要使用 stap 命令来运行脚本。

1
sudo stap check_open.stp

这将会启动脚本并开始跟踪 sys_open 调用。如果你尝试打开 /etc/passwd,脚本会修改返回值,导致文件无法打开。

验证脚本效果

你可以验证脚本的效果,看看它是否按预期工作:

尝试打开 /etc/passwd 文件,例如使用 cat 命令:

1
cat /etc/passwd

由于脚本的作用,cat 命令应该失败,并返回错误信息,如 Permission denied

总结

  1. 创建脚本:使用probe挂钩内核函数,获取相关参数。
  2. 条件判断:通过if语句判断参数值,执行相应的操作。
  3. 修改返回值:使用return修改函数的返回值。
  4. 运行脚本:使用sudo stap命令来执行脚本并进行监控。

参考资料:

  1. SystemTap Tutorial Part-II
  2. SystemTap Tutorial, Part-2
  3. Systemtap tutorial