最近写了一个修改系统调用的LKM。我的内核是2.6.24,是fedora8的。源代码如下:
#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif
#ifdef CONFIG_MODVERSIONS
#define MODVERSIONS
#include
#endif
#include
#include
#include
#include
MODULE_LICENSE("GPL");
//由于2.6内核中没有暴露sys_call_table,因此我在/boot/System.map中自己查看了sys_call_table的地址
void** sys_call_table=(void**)0xc06357a0;
int (*orig_open)(const char* filename, int flags,int mode);
int new_open (const char* filename, int flags,int mode)
{
//仅仅是个测试而已
printk("this is a test\n");
return orig_open(filename,flags,mode);
}
int init_module(void)
{
orig_open=sys_call_table[__NR_open];
sys_call_table[__NR_open]=new_open;
printk("init_module exe\n");
return 0;
}
void cleanup_module(void)
{
sys_call_table[__NR_open]=orig_open;
printk("cleanup_module exe\n");
}
编译没有问题,但是当insmod test2.ko时会引发段错误。
系统报段错误时我用dmesg看了下错误信息如下:
<1>BUG: unable to handle kernel paging request at virtual address c06357b4
printing eip: d0aac056 *pde = 0e9dd163 *pte = 00635161
Oops: 0003 [#1] SMP
Modules linked in: test2(U) addsym(U) nls_utf8 autofs4 fuse rfcomm l2cap bluetooth sunrpc nf_conntrack_ftp nf_conntrack_ipv4 xt_state nf_conntrack xt_tcpudp ipt_REJECT iptable_filter ip_tables x_tables loop dm_multipath ipv6 snd_ens1371 gameport snd_rawmidi snd_ac97_codec ac97_bus snd_seq_dummy parport_pc snd_seq_oss snd_seq_midi_event parport snd_seq floppy snd_seq_device snd_pcm_oss snd_mixer_oss snd_pcm snd_timer ac button pcnet32 snd i2c_piix4 pcspkr soundcore mii snd_page_alloc i2c_core sr_mod sg cdrom BusLogic dm_snapshot dm_zero dm_mirror dm_mod ata_piix pata_acpi ata_generic libata sd_mod scsi_mod ext3 jbd mbcache uhci_hcd ohci_hcd ehci_hcd
Pid: 3793, comm: insmod Not tainted (2.6.24.7-92.fc8 #1)
EIP: 0060:[] EFLAGS: 00010286 CPU: 0
EIP is at init_module+0x13/0x29 [test2]
EAX: c0487967 EBX: c3c05268 ECX: 00000000 EDX: c06357b4
ESI: c3c05240 EDI: 00000001 EBP: d0aac480 ESP: ced43ebc
DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
Process insmod (pid: 3793, ti=ced43000 task=c92d0690 task.ti=ced43000)
Stack: 00000000 c044d064 00000000 00000000 c1025520 00000200 0000001b 00000000
c3d9b990 00000438 0000be03 c91ea004 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
Call Trace:
[] sys_init_module+0x14d6/0x15f9
[] printk+0x0/0x1f
[] syscall_call+0x7/0xb
=======================
Code: aa d0 a1 2c c4 aa d0 89 50 14 c7 04 24 04 c1 aa d0 e8 69 37 98 ef 58 c3 83 ec 04 8b 15 2c c4 aa d0 83 c2 14 8b 02 a3 0c d6 aa d0 02 6c c0 aa d0 c7 04 24 18 c1 aa d0 e8 42 37 98 ef 31 c0 5a
EIP: [] init_module+0x13/0x29 [test2] SS:ESP 0068:ced43ebc
我通过在代码中多加printk的方式发现orig_open=sys_call_table[__NR_open]执行后orig_open已经被正确的赋了sys_open的值,跟System.map中sys_open值一致。
错误发生在init_module中对sys_call_table[__NR_open]的赋值这一句上:sys_call_table[__NR_open]=new_open;
而且看一下错误信息好像也是:unable to handle kernel paging request at virtual address c06357b4。sys_open的系统调用号是5.我的sys_call_table的地址是c06357a0。而c06357b4刚好是c06357a0+5*4.
因此我猜测是不能向sys_call_table[__NR_open]写入新的数值。但是我在网上和书上看的其他修改系统调用的moudle都是这样写的啊,为什么我的module加载就报这个错误呢?不是我2.6.24的内核有什么新的变化吧?
急需高手帮忙,感激不尽!!
--------------------next---------------------
阅读(766) | 评论(0) | 转发(0) |