如何从shell触发内核模块?

cecemelly

我在VirtualBox中使用Ubuntu。我正在为我的外壳定义一个新命令,以输出子进程的某些特征(例如兄弟树等)。为了输出这些特征,我创建了一个内核模块并使用task_struct。我还在外壳之外测试了内核模块,并且该模块有效。现在我的问题是如何在我的Shell中触发此内核模块(使用C代码),以便加载我的内核模块?

我搜索后发现,我需要使用系统调用,例如modprobe或insmod,但不了解如何使用它们。我尝试了下面的代码,但是没有用:

setuid(0);

系统(“ / sbin / insmod /.../mymodule.ko”);

谢谢您的帮助。

山姆·普罗岑科

加载模块使用 system()

您正试图通过执行成为您的应用程序的setuid(0),但是您没有这样做的权限(如果您以普通用户身份运行程序)。相反,您应该检查程序是否从root运行(使用getuid())。另外,最好测试一下模块文件是否存在。这是此类代码的示例(已经过测试并进行了所有必要的检查):

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

#define ROOT_UID    0
#define INSMOD_PATH "/sbin/insmod"
#define MOD_PATH    "/.../mymodule.ko"

int main(void)
{
    uid_t uid;
    int res;

    /* Check if program being run by root */
    uid = getuid();
    if (uid != ROOT_UID) {
        fprintf(stderr, "Error: Please run this program as root\n");
        return EXIT_FAILURE;
    }

    /* Check if module file exists */
    if (access(MOD_PATH, F_OK) == -1) {
        fprintf(stderr, "Error: File \"%s\" doesn't exist\n", MOD_PATH);
        return EXIT_FAILURE;
    }

    /* Load module */
    res = system(INSMOD_PATH " " MOD_PATH);
    if (res != 0) {
        fprintf(stderr, "Error loading module: %d\n", res);
        return EXIT_FAILURE;
    }

    printf("Module \"%s\" was successfully loaded\n", MOD_PATH);

    return EXIT_SUCCESS;
}

将此代码另存为main.c文件。确保用模块文件的实际路径替换MOD_PATH定义。

使用下一条命令进行编译:

$ gcc -Wall -O2 main.c -o load_module

现在执行下一个:

$ su
# ./load_module
  1. 第一个命令将您的用户切换为root用户(将要求您输入root密码)。如果您不知道root密码,请尝试使用sudo -scommand代替su
  2. 第二个命令运行您的程序。

在命令提示符下,请注意最后一个字符:

  • #表示您目前拥有root权限
  • $ 表示您仅具有常规用户权限。

加载模块使用 finit_module()

system()在C中使用函数通常被认为是一种不好的做法(因为执行需要花费大量时间,并且基本上只是尝试替换更简单的Bash脚本)。

如果您想在不使用C的情况下在C中加载内核模块system(),则可以查看该insmod工具的源代码参见libkmod/libkmod-module.c文件,kmod_module_insert_module()功能。您可以在此处查看这些资源

注意finit_module()函数调用。可以在手册页上找到有关此系统调用的很好的解释

$ man finit_module

这是一个示例,您可以使用finit_module()系统调用:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include <sys/stat.h>
#include <fcntl.h>

#define ROOT_UID    0
#define MOD_PATH    "/.../mymodule.ko"

static inline int finit_module(int fd, const char *uargs, int flags)
{
    return syscall(__NR_finit_module, fd, uargs, flags);
}

int main(void)
{
    uid_t uid;
    long res;
    int fd;

    /* Check if program being run by root */
    uid = getuid();
    if (uid != ROOT_UID) {
        fprintf(stderr, "Error: Please run this program as root\n");
        return EXIT_FAILURE;
    }

    /* Check if module file exists */
    if (access(MOD_PATH, F_OK) == -1) {
        fprintf(stderr, "Error: File \"%s\" doesn't exist\n", MOD_PATH);
        return EXIT_FAILURE;
    }

    /* Load module */
    fd = open(MOD_PATH, O_RDONLY | O_CLOEXEC);
    if (fd < 0) {
        perror("Unable to open module file");
        return EXIT_FAILURE;
    }
    res = finit_module(fd, "", 0);
    if (res != 0) {
        perror("Error when loading module");
        close(fd);
        return EXIT_FAILURE;
    }
    close(fd);

    printf("Module \"%s\" was successfully loaded\n", MOD_PATH);

    return EXIT_SUCCESS;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何从shell触发内核模块?

来自分类Dev

如何编译内核模块

来自分类Dev

如何安装“ cdfs”内核模块?

来自分类Dev

如何临时禁用内核模块?

来自分类Dev

如何写入/ proc内核模块

来自分类Dev

如何从内核模块写入TTY?

来自分类Dev

如何禁用内核模块中的缓存

来自分类Dev

如何调试插入的内核模块?

来自分类Dev

如何永久加载内核模块?

来自分类Dev

如何丢失树内内核模块?

来自分类Dev

如何临时禁用内核模块?

来自分类Dev

如何永久加载内核模块?

来自分类Dev

如何管理同名的多个内核模块?

来自分类Dev

如何永久禁用内核模块?

来自分类Dev

如何丢失树内内核模块?

来自分类Dev

如何验证内核模块签名?

来自分类Dev

如何删除VirtualBox vboxdrv内核模块?

来自分类Dev

如何构建特定的内核模块?

来自分类Dev

如何监视“ iptables”内核模块的性能?

来自分类Dev

如何卸载正在使用的内核模块?

来自分类Dev

如何安装“cdfs”内核模块?

来自分类Dev

内核模块如何自动加载

来自分类Dev

测试内核模块

来自分类Dev

内核模块问题

来自分类Dev

内核模块警告

来自分类Dev

签名内核模块

来自分类Dev

如何在AWS内核上获取配额内核模块?

来自分类Dev

如何为加载的内核构建 iptables 内核模块?

来自分类Dev

如何配置以构建与已加载内核模块相同的内核模块