hook - 加载 Linux 内核模块时,如何使用 `kallsyms_lookup_name` 函数修复`unknown character` 错误?
问题描述
我正在尝试在我的 uni 作业程序中完成一个挂钩示例附件。该任务需要sys_rt_sigaction
在 Linux 内核中启动可加载模块时挂钩系统调用(我使用 Ubuntu 18.04 LTS,内核版本为 5.0.0-23-generic)。因此,我正在苦苦挣扎的情况源于could not insert module <module name>: Unknown symbol in module
我开始时的错误sudo insmod <my module name>.ko
。经过一番谷歌搜索,我清楚地看到这个问题是由于缺少sys_call_table
导出以顺利运行插入而出现的。在这篇文章之后,我想kallsyms_lookup_name
在开始程序之前处理那个调用调用init
。
有.c
-file 提供模块可访问的操作定义(文件名为buffer.c
):
#define __KERNEL__
#define MODULE
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/syscalls.h>
#include <linux/kallsyms.h>
#include <linux/unistd.h>
void * sys_call_table = (void *) kallsyms_lookup_name("sys_call_table");// some wrongness here, but what exactly?
MODULE_LICENSE("GPL");
int (*real_rt_sigaction)(const char * path); // true syscall prototype
static int __init buffer_init_module(void);
static void __exit buffer_exit_module(void);
static int device_open(struct inode *, struct file *); // driver file opening
static int device_release(struct inode *, struct file *); // return of system resource control
static ssize_t device_read(struct file *, char *, size_t, loff_t *); // reading from driver file
static ssize_t device_write(struct file *, const char *, size_t, loff_t *); // writing into driver file
#define DEVICE_NAME "buffer"
#define BUF_LEN 80
// to be called instead
int alter_rt_sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact, size_t sigsetsize) {
printk(KERN_INFO "Syscall function hooked - you've lost control of your experience");
return 0;
}
static int Major;
static int Device_Open = 0;
static int total_open = 1;
static char Buf[BUF_LEN + 1] = "Buffer is empty, add some input\n";
static char *Msg_ptr;
static int Buf_Char = 50;
static int Bytes_Read = 0;
static struct file_operations fops = {
.read = device_read,
.write = device_write,
.open = device_open,
.release = device_release
};
static int __init buffer_init_module(void)
{
printk(KERN_INFO
"Device initializing in progress...");
Major = register_chrdev(0, DEVICE_NAME, &fops);
if(Major < 0) {
printk("Major number hasn't been assigned - Driver registration failed\n");
return Major;
}
printk(KERN_INFO "Registration success - device major number: %d\n", Major);
real_rt_sigaction=sys_call_table[__NR_rt_sigaction];
sys_call_table[__NR_rt_sigaction]=alter_rt_sigaction; // hooking implementation
return 0;
}
static void __exit buffer_exit_module(void)
{
unregister_chrdev(Major, DEVICE_NAME);
printk(KERN_INFO "Outside the module - exit successfully completed\n");
sys_call_table[__NR_rt_sigaction]=real_rt_sigaction; // original call reset
}
static int device_open(struct inode *inode, struct file *file)
{
if(Device_Open)
return -EBUSY;
Device_Open++;
printk(KERN_INFO "Device file has been accessed %d time(s)\n", total_open++);
Msg_ptr = Buf;
try_module_get(THIS_MODULE);
Bytes_Read = 0;
return 0;
}
static int device_release(struct inode * node, struct file * filep)
{
Device_Open--;
module_put(THIS_MODULE);
printk(KERN_INFO "Device file gets close\n");
return 0;
}
static ssize_t device_read(struct file * filep, char * buffer, size_t len, loff_t * offset)
{
int got_read = Bytes_Read;
if(Bytes_Read >= Buf_Char)
return 0;
while(len && (Bytes_Read < Buf_Char)) {
put_user(Msg_ptr[Bytes_Read], buffer+Bytes_Read);
len--;
Bytes_Read++;
}
return Bytes_Read-got_read;
}
static ssize_t device_write(struct file * filep, const char * buffer, size_t len, loff_t * offset)
{
Buf_Char = 0;
if(Buf_Char >= BUF_LEN) {
return 0;
}
while(len && (Buf_Char < BUF_LEN))
{
get_user(Msg_ptr[Buf_Char], buffer+Buf_Char);
len--;
Buf_Char++;
}
return Buf_Char;
}
module_init(buffer_init_module);
module_exit(buffer_exit_module);
此外,还有代码Makefile
:
obj-m += buffer.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
initializer element is not constant
每当我试图sudo make
在我的项目文件夹中构建模块时,这里的痛苦时刻是一条错误消息。当我遵循初学者的教程并需要一些基本的洞察力时,很可能会看到任何有关解决方案的帮助,甚至是一些如何更有效地处理相同问题的想法。
解决方案
推荐阅读
- excel - 唯一/条件计数公式
- .net-core - 我可以使用 bot 框架作为 MS Teams 中的用户发送/更新消息吗?
- javascript - 我该如何解决这个问题'不允许重复的道具反应/jsx-no-duplicate-props'
- flutter - 如何根据面值对飞镖中的整数列表进行排序?
- python - 用于查找具有非封闭形式解的方程的数值解的 python 包
- typescript - 寻找一种类型安全的方法来压平 pojo
- node.js - React and Express iTunes Search API :: 错误:请求失败,状态码为 404
- javascript - 避免在 Javascript 中使用模板文字
- javascript - 赛普拉斯:如何在页面对象模型中引用其方法之外的别名
- python-3.x - kivy 和 kivymd 中 kivy/波斯语输入的 RTL 输入