最刺激的添加内核系统调用的方法就是hack sys_call_table 了 ^_^
它的基本思想就是
1 找到 sys_call_table 的地址;
2 保存其中某项内容,比如 sys_call_table[__NR_mkdir]
以便hack后恢复;
3 修改 sys_call_table[__NR_mkdir]
使其指向自己实现的系统调用函数
这样做之后,系统调用mkdir就被你hack了 呵呵 是不是很爽
来来来
咱们实现一下
代码
hack_sys_call.c
////////////////////////////////////////////////////
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <asm/unistd.h>
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Different from others, this module automatically locate the entry of sys_call_table !");
unsigned long *sys_call_table=NULL;
asmlinkage int (*orig_mkdir)(const char *,int);
struct _idt
{
unsigned short offset_low;
unsigned short segment_sel;
unsigned char reserved;
unsigned char flags;
unsigned short offset_high;
};
unsigned long *getscTable()
{
unsigned char idtr[6],*shell,*sort;
struct _idt *idt;
unsigned long system_call,sct;
unsigned short offset_low,offset_high;
char *p;
int i;
/* get the interrupt descriptor table */
__asm__("sidt %0" : "=m" (idtr));
/* get the address of system_call */
idt=(struct _idt*)(*(unsigned long*)&idtr[2]+8*0x80);
offset_low = idt->offset_low;
offset_high = idt->offset_high;
system_call=(offset_high<<16)|offset_low;
shell=(char *)system_call;
sort="/xff/x14/x85";
/* get the address of sys_call_table */
for(i=0;i<(100-2);i++)
if(shell[i]==sort[0]&&shell[i+1]==sort[1]&&shell[i+2]==sort[2])
break;
p=&shell[i];
p+=3;
sct=*(unsigned long*)p;
return (unsigned long*)(sct);
}
asmlinkage int hacked_mkdir(const char * pathname, int mode)
{
printk("PID %d called sys_mkdir !/n",current->pid);
return orig_mkdir(pathname,mode);
}
static int __init find_init(void)
{
sys_call_table = getscTable();
orig_mkdir=(int(*)(const char*,int))sys_call_table[__NR_mkdir];
sys_call_table[__NR_mkdir]=(unsigned long)hacked_mkdir;
return 0;
}
static void __exit find_cleanup(void)
{
sys_call_table[__NR_mkdir]=(unsigned long)orig_mkdir;
}
module_init(find_init);
module_exit(find_cleanup);
////////////////////////////////////////////////////
Makefile
////////////////////////////////////////////////////
CC=gcc
INCLUDEDIR = /usr/src/linux-2.4/include
MODCFLAGS :=-Wall -O -DMODULE -D__KERNEL__ -DLINUX -I$(INCLUDEDIR)
hack_sys_call.o: hack_sys_call.c
$(CC) $(MODCFLAGS) -c hack_sys_call.c
////////////////////////////////////////////////////
getscTable()是在内存中查找sys_call_table地址的函数。
每一个系统调用都是通过int 0x80中断进入核心,中断描
述符表把中断服务程序和中断向量对应起来。对于系统调
用来说,操作系统会调用system_call中断服务程序。
system_call函数在系统调用表中根据系统调用号找到并
调用相应的系统调用服务例程。idtr寄存器指向中断描述
符表的起始地址,用sidt[asm ("sidt %0" : "=m" (idtr));]
指令得到中断描述符表起始地址,从这条指令中得到的指针
可以获得int 0x80中断服描述符所在位置,然后计算出
system_call函数的地址。反编译一下system_call函数可以
看到在system_call函数内,是用call sys_call_table指令
来调用系统调用函数的。因此,只要找到system_call里
的call sys_call_table(,eax,4)指令的机器指令就可以获得
系统调用表的入口地址了
在2.4和2.6之前的内核中,sys_call_table是可以直接导出的
挺危险的 ^_^