为实现网络监控,故需要监控系统调用函数__NR_connect
系统环境 64 位 CentOS
代码如下:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/list.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <asm/unistd.h>
#include <linux/dirent.h>
#include <linux/stat.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#include <net/sock.h>
#include <net/netlink.h>
#define CALLOFF 100
#define SP_INTERCEPT_SOCKET_NETLINK 28
//define idtr and idt struct
char psname[10] = "hello";
char *processname = psname;
static char *mod_name = "hook";
module_param(mod_name, charp, 0);
struct{
unsigned short limit;
unsigned int base;
}__attribute__((packed))idtr;
struct{
unsigned short off_low;
unsigned short sel;
unsigned char none;
unsigned char flags;
unsigned short off_high;
}__attribute__((packed))*idt;
struct _idt
{
unsigned short offset_low,segment_sel;
unsigned char reserved,flags;
unsigned short offset_high;
};
/*unsigned long *getscTable()
{
unsigned char idtr[6] = {0}, *shell = NULL, *sort = NULL;
struct _idt *idtLong = NULL;
unsigned long system_call = 0, sct = 0;
unsigned short offset_low = 0, offset_high = 0;
char *p = NULL;
int i = 0;
__asm__("sidt %0" : "=m" (idtr));
idtLong=(struct _idt*)(*(unsigned long*)&idtr[2]+8*0x80);
offset_low = idtLong->offset_low;
offset_high = idtLong->offset_high;
system_call = (offset_high<<16)|offset_low;
shell=(char *)system_call;
sort="\xff\x14\x85";
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);
}*/
//define function, Point to the system being hijacked
struct linux_dirent
{
unsigned long d_ino;
unsigned long d_off;
unsigned short d_reclen;
char d_name[1];
};
//asmlinkage long (*orig_getdents)(unsigned int fd, struct linux_dirent __user *dirp, unsigned int count);
/*
struct sockaddr
{
unsigned short sa_family;
char sa_data[14];
};
struct in_addr
{
unsigned long s_addr;
};
*/
//struct sockaddr_in
//{
// short int sin_family; /* Internet地址族*/
// unsigned short int sin_port; /* 端口号*/
// struct in_addr sin_addr; /* Internet地址*/
// unsigned char sin_zero[8]; /* 填充0(为了保持和struct sockaddr一样大小)*/
//};
asmlinkage long (*orig_getdents)(int fd, struct sockaddr __user *dirp, int addrlen);
//int orig_cr0 = 0;
unsigned long *sys_call_table = NULL;
//add by liangz 2016-06-13
void spinfo_destroy_netlink();
static struct mutex ply_cs_mutex;
static struct sock *nl_sk = NULL;
//policy list
typedef struct _NetworkCtrl_
{
// 是否启用
bool bEnable;
//ip:port
char website[2048];
}NetworkCtrl, *PNetworkCtrl;
PNetworkCtrl sp_ply_info = NULL;
//get function system_call addr
/*void* get_system_call(void)
{
printk(KERN_ALERT "start get_system_call...\n");
void * addr = NULL;
asm("sidt %0":"=m"(idtr));
idt = (void*) ((unsigned long*)idtr.base);
addr = (void*) (((unsigned int)idt[0x80].off_low) | (((unsigned int)idt[0x80].off_high)<<16 ));
return addr;
}*/
//find sys_call_table
char* findoffset(char *start)
{
printk(KERN_ALERT "start findoffset...\n");
char *p = NULL;
int i = 0;
/*for(p=start; p < start + CALLOFF; p++)
{
if(*(p+0) == '\xff' && *(p+1) =