|
发表于 2005-4-25 10:00:59
|
显示全部楼层
#define MODULE
#define __KERNEL__
#define NULL 0
#include <linux/module.h>
#include <linux/tty.h>
#include <asm/unistd.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/fs.h>
void my_stub();
static unsigned long old_stub;
static unsigned long stub_eax,stub_ebx,stub_ecx;
struct descriptor_idt
{
unsigned short offset_low,seg_selector;
unsigned char reserved,flag;
unsigned short offset_high;
};
struct {
unsigned short limit;
unsigned long base;
}__attribute__ ((packed)) idtr;
void stub_kad(void)
{
__asm__ (
".globl my_stub \n"
".align 4,0x90 \n"
"my_stub: \n"
"pushl %%es\n"
"pushl %%ds\n"
"pushl %%eax\n"
"pushl %%ebp\n"
"pushl %%edi\n"
"pushl %%esi\n"
"pushl %%edx\n"
"pushl %%ecx\n"
"pushl %%ebx\n"
"movl %%eax,%0\n"
"movl %%ebx,%1\n"
"movl %%ecx,%2\n"
"call my_handler \n"
"popl %%ebx\n"
"popl %%ecx\n"
"popl %%edx\n"
"popl %%esi\n"
"popl %%edi\n"
"popl %%ebp\n"
"popl %%eax\n"
"popl %%ds\n"
"popl %%es\n"
"jmp *old_stub"
::"m"(stub_eax),"m"(stub_ebx),"m"(stub_ecx)
);
}
void my_handler()
{//假设这里只打印eax,ebx,ecx,当然你也可以做其他事情!
//最好,不要什么系统调用都打印!你可以这样
// if(stub_eax == 512) //只截获512号系统调用,该系统调用不存在,用我给的程序测试!
//我的系统是rh9,2.4内核!你可以检查/var/log/message
//看看是不是有输出了
// printk(KERN_INFO"0x%x, 0x%x, 0x%x\n",stub_eax,stub_ebx,stub_ecx);
//下面的什么系统调用都被截获,同样可以检查/var/log/message看看是不是系统调用已经源源不断
//的被输出了
printk(KERN_INFO"eax=0x%x, ebx=0x%x, ecx=0x%x\n",stub_eax,stub_ebx,stub_ecx);
}
int init_module(void)
{
printk("start get_addr_idt");
__asm__ volatile ("sidt %0": "=m" (idtr));
printk("the idt address is %x\n",idtr.base);
struct descriptor_idt *idte=(struct descriptor_idt *)(idtr.base+8*0x80);
old_stub=(idte->offset_high<<16|idte->offset_low);
printk("<1>oldstub=%x\n",old_stub);
unsigned long new_addr=(unsigned long)my_stub;
idte->offset_high = (unsigned short) (new_addr >> 16);
idte->offset_low = (unsigned short) (new_addr & 0x0000FFFF);
printk("<1>newstub=%x\n",(idte->offset_high<<16|idte->offset_low));
return 0;
}
void cleanup_module()
{
printk("destroy...b..\n");
__asm__ volatile ("sidt %0": "=m" (idtr));
struct descriptor_idt *idte=(struct descriptor_idt *)(idtr.base+8*0x80);
idte->offset_high = (unsigned short) (old_stub >> 16);
idte->offset_low = (unsigned short) (old_stub & 0x0000FFFF);
printk("<1>restore the stub=%x\n",(idte->offset_high<<16|idte->offset_low));
}
MODULE_LICENSE("GPL");
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
以上模块的编译方法:
假设你的linux source在/usr/src/linux路径下
gcc -c -I/usr/src/linux/include ok-test22.c
编译后得到ok-test22.o
insmod ok-test22.o
不就OK了 |
|