我正在尝试将系统调用动态加载到内核中(无需重新启动内核并对其进行编译),以尝试(一旦在内核模式下)写入用户进程的内存。
(我知道有一种方法可以使用 ptrace 接口执行此操作,但这不是一个选项。)
我知道这样做的唯一方法是加载一个模块。为了允许用户与之通信,我被告知使用字符设备(应该在 /dev/ 中,对吗?)。我成功加载了一个。我的问题是我不知道用户进程如何在没有系统调用的情况下访问它。(有人告诉我使用 ioctl) 谁能展示一个用户进程如何调用我的模块加载的 ioctl ?
谢谢, 夏
我正在尝试将系统调用动态加载到内核中(无需重新启动内核并对其进行编译),以尝试(一旦在内核模式下)写入用户进程的内存。
(我知道有一种方法可以使用 ptrace 接口执行此操作,但这不是一个选项。)
我知道这样做的唯一方法是加载一个模块。为了允许用户与之通信,我被告知使用字符设备(应该在 /dev/ 中,对吗?)。我成功加载了一个。我的问题是我不知道用户进程如何在没有系统调用的情况下访问它。(有人告诉我使用 ioctl) 谁能展示一个用户进程如何调用我的模块加载的 ioctl ?
谢谢, 夏
对于下面的答案,我假设您正在开发一个 Linux 模块。重读您的问题后,我发现我可能误解了这个问题。
有几种与内核驱动程序通信的机制:
最常见的技术是最后一种使用read()和/或write()系统调用来引起驱动程序动作的技术。虽然这些系统调用通常传递纯数据,但没有什么可以阻止特定驱动程序通过 i/o 接口传递元数据。
另一方面,如果驱动程序已经有一个有用的纯数据规则read()并且write()不适合元数据,那么ioctl()系统调用是一种通用的瑞士军刀,用于处理与文件相关的各种事情,例如加载或卸载磁带、弹出 DVD、查找网卡的以太网地址或找出发生了多少磁盘驱动器错误。已经定义了很多ioctl操作代码,您可能可以找到一个合理的用于您的目的重用。该接口的一个很大缺点ioctl是它最适合由自定义程序使用,因此通过ioctl连接到标准程序的管道来传输数据会很尴尬或困难。
该/proc接口结合了前两种技术的优点:它可以使用标准实用程序的stdin/stdout约定,但它还通过常规驱动程序机制为设备驱动程序提供了一个独立于任何 i/o 的接口。例如,尝试cat /proc/net/tcp在您的 Linux 系统上。它显示所有TCP连接的状态。
一篇关于实现procfs功能的好文章位于create_proc_entry(). 这里很好地介绍了实现 ioctl 。元数据方法与任何其他设备驱动程序一样易于编码,尽管它可能会给有经验的实施者带来概念上的障碍。