我有一个分配,需要为linux虚拟机编译一个模块,要求我们专门使用ubuntu 14.04,但是当我执行make命令时,它将引发此错误(当然,当尝试在虚拟机上安装结果时在计算机上显示sys_ni_syscall未定义并且不起作用)。相同的c文件可用于其他人,并且包含linux / syscalls.h。我不知道该怎么做,我将在c和makefile中添加模块的代码。谢谢
这里是模块的代码(newsyscall.c)
/*
* New system call
*/
#include <asm/unistd.h>
#include <linux/module.h>
#include <linux/syscalls.h>
#include <linux/thread_info.h>
#include <asm/asm-offsets.h> /* NR_syscalls */
MODULE_LICENSE ("GPL");
MODULE_DESCRIPTION ("New system call");
unsigned int free_ident = -1;
extern unsigned sys_call_table[];
asmlinkage long
sys_newsyscall (int parameter)
{
printk ("Hello world, parameter %d\n", parameter);
return (29);
}
#define GPF_DISABLE write_cr0(read_cr0() & (~ 0x10000)) /* Disable RO protection */
#define GPF_ENABLE write_cr0(read_cr0() | 0x10000) /* Enable RO protection */
static int __init
newsyscall_init (void)
{
unsigned int i;
/* Look for an unused sys_call_table entry */
for (i = 0; i < NR_syscalls; i++)
if (sys_call_table[i] == (unsigned) sys_ni_syscall)
break;
/* Found? */
if (i == NR_syscalls)
{
printk ("No free entry available");
return (-1);
}
/* Use this sys_call_entry */
free_ident = i;
GPF_DISABLE; /* Disable RO protection (sys_call_table is on a RO page )*/
sys_call_table[free_ident] = (unsigned) sys_newsyscall;
GPF_ENABLE; /* Enable RO protection */
printk (KERN_INFO "New syscall installed. Identifier = %d\n", free_ident);
return (0);
}
static void __exit
newsyscall_exit (void)
{
/* Restore previous state */
if (free_ident != -1) {
GPF_DISABLE; /* Disable RO protection (sys_call_table is on a RO page )*/
sys_call_table[free_ident] = (unsigned) sys_ni_syscall;
GPF_ENABLE; /* Enable RO protection */
free_ident = -1;
printk (KERN_INFO "New syscall removed\n");
}
else
printk (KERN_INFO "Unexpected error\n");
}
module_init (newsyscall_init);
module_exit (newsyscall_exit);
这里是makefile:
ifneq ($(KERNELRELEASE),)
obj-m := newsyscall.o
else
include ../Makefile
KERNELDIR := ../../$(KERNEL_VERSION)
PWD := $(shell pwd)
all: test5 modules
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
test5: test5.c
gcc -static -D__KERNEL__ -I../../$(KERNEL_VERSION)/include test5.c -o test5
clean:
rm -rf *.[oas] .*.flags *.ko .*.cmd .*.d .*.tmp *.mod.c .tmp_versions Module.symvers test5 *.order
endif
Well ... sys_ni_syscall
是not导出的符号;您可以从内核源代码内部(如果要修补内核本身)访问它,但不能从模块中访问它。
我知道的唯一不需要更改内核本身的解决方案就是通过get the address manually更改为/proc/kallsyms
。
尽管这是一个易碎且非常棘手的“解决方案” ...