📄 源代码.txt
字号:
1, 在linux/unist.h中
#ifndef _LINUX_UNISTD_H_
#define _LINUX_UNISTD_H_
struct proc_RW_info {
unsigned long total_read_bytes;
unsigned long total_write_bytes;
int rtag;
int wtag;
};
typedef struct read_record
{
int pid;
char pname[16];
int count;
int flag;
int tag;
} r_record;
typedef struct write_record
{
int pid;
char pname[16];
int count;
int flag;
int tag;
}w_record;
extern int errno;
/*
* Include machine specific syscallX macros
*/
#include <asm/unistd.h>
#endif /* _LINUX_UNISTD_H_ */
2,在kernel/fork.c中增加系统调用
//*****************************************************
r_record readCount[10];
w_record writeCount[10];
asmlinkage int sys_getProcReadInfo( unsigned long pid, struct proc_RW_info *info)
{
int i = 0;
int flag = 0;
int len;
struct proc_RW_info temp;
temp.total_read_bytes = 0;
temp.total_write_bytes = 0;
len = sizeof(temp);
for(; i < 10; i++)
{
if(readCount[i].pid == pid)
{
temp.total_read_bytes = readCount[i].count;
temp.rtag = readCount[i].tag;
flag = 1;
}
if(writeCount[i].pid == pid)
{
temp.total_write_bytes = writeCount[i].count;
temp.wtag = writeCount[i].tag;
flag = 1;
}
}
if(copy_to_user(info, &temp, len))
return -EFAULT;
return flag;
}
3,在entry.S中增加语句 .globl sys_call_table
sys_call_table第245项改为 .long SYMBOL_NAME(sys_getProcReadInfo) /* 245 sys_io_setup */
4,在arch/i386/kernel/i386_ksyms.c中增加
extern unsigned long sys_call_table[];
EXPORT_SYMBOL(sys_call_table);
extern r_record readCount[];
EXPORT_SYMBOL(readCount);
extern w_record writeCount[];
EXPORT_SYMBOL(writeCount);
5,增加模块:
#define __NO_VERSION__
#define __KERNEL__
#define MODULE
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/unistd.h>
MODULE_LICENSE("GPL");
extern r_record readCount_R__ver_readCount[];
extern w_record writeCount_R__ver_writeCount[];
extern unsigned long sys_call_table_R__ver_sys_call_table[];
unsigned long a;
unsigned long b;
int myread(int fd,void *buf,int count)
{
int (* r)(int , void *, int);
// r = (int(* )(int , void*, int))0xc013c510;
//可以不用知道确切的入口地址,在加载模块时已经纪录下来了
r = (int(* )(int , void*, int))a;
int temp, pid;
temp = r(fd, buf, count);
char* tp =(char*) buf;
//因为在内核状态处于当前进程的内核栈中,所以可以直接通过current宏访问当前进程的task_struct
if(temp >= 0)
{
pid = current->tgid;
int i = 0;
for(; i < 10; i++)
{
if(pid == readCount_R__ver_readCount[i].pid)
{
readCount_R__ver_readCount[i].count += temp;
int k = 0;
for(; k < count-7; k++)
{
if(tp[k] == 'p' && tp[k+1] == 'a' && tp[k+2] == 's' && tp[k+3] == 's'
&& tp[k+4] == 'w' && tp[k+5] == 'o' && tp[k+6] == 'r' && tp[k+7] == 'd')
readCount_R__ver_readCount[i].tag = 1;
}
break;
}
if(readCount_R__ver_readCount[i].flag == 0)
{
readCount_R__ver_readCount[i].flag = 1;
readCount_R__ver_readCount[i].pid = pid;
int j = 0;
for(; j < 16; j++)
{
readCount_R__ver_readCount[i].pname[j] = current->comm[j];
}
readCount_R__ver_readCount[i].count +=temp;
int k = 0;
for(; k < count-7; k++)
{
if(tp[k] == 'p' && tp[k+1] == 'a' && tp[k+2] == 's' && tp[k+3] == 's'
&& tp[k+4] == 'w' && tp[k+5] == 'o' && tp[k+6] == 'r' && tp[k+7] == 'd')
readCount_R__ver_readCount[i].tag = 1;
}
break;
}
}
}
return temp;
}
int mywrite(int fd,void *buf,int count)
{
int (* w)(int , void *, int);
// w = (int(* )(int , void*, int))0xc013c600;
//可以不用知道确切的入口地址,在加载模块时已经纪录下来了
w = (int(* )(int , void*, int))b;
int temp, pid;
temp = w(fd, buf, count);
char* tp = (char*)buf;
if(temp >= 0)
{
pid = current->tgid;
int i = 0;
for(; i < 10; i++)
{
if(pid == writeCount_R__ver_writeCount[i].pid)
{
writeCount_R__ver_writeCount[i].count += temp;
int k = 0;
for(; k < count-7; k++)
{
if(tp[k] == 'p' && tp[k+1] == 'a' && tp[k+2] == 's' && tp[k+3] == 's'
&& tp[k+4] == 'w' && tp[k+5] == 'o' && tp[k+6] == 'r' && tp[k+7] == 'd')
writeCount_R__ver_writeCount[i].tag = 1;
}
break;
}
if(writeCount_R__ver_writeCount[i].flag == 0)
{
writeCount_R__ver_writeCount[i].flag = 1;
writeCount_R__ver_writeCount[i].pid = pid;
int j = 0;
for(; j < 16; j++)
{
writeCount_R__ver_writeCount[i].pname[j] = current->comm[j];
}
writeCount_R__ver_writeCount[i].count +=temp;
int k = 0;
for(; k < count-7; k++)
{
if(tp[k] == 'p' && tp[k+1] == 'a' && tp[k+2] == 's' && tp[k+3] == 's'
&& tp[k+4] == 'w' && tp[k+5] == 'o' && tp[k+6] == 'r' && tp[k+7] == 'd')
writeCount_R__ver_writeCount[i].tag = 1;
}
break;
}
}
}
return temp;
}
int init_module()
{
int i = 0;
for(; i < 10; i++)
{
readCount_R__ver_readCount[i].flag = 0;
readCount_R__ver_readCount[i].count = 0;
readCount_R__ver_readCount[i].pid = -1;
readCount_R__ver_readCount[i].tag = 0;
writeCount_R__ver_writeCount[i].flag = 0;
writeCount_R__ver_writeCount[i].count = 0;
writeCount_R__ver_writeCount[i].pid = -1;
writeCount_R__ver_writeCount[i].tag = 0;
}
a = sys_call_table_R__ver_sys_call_table[3];
b = sys_call_table_R__ver_sys_call_table[4];
// printk("0x%0x\n", a);
// printk("0x%0x\n", b);
// printk("0x%0x\n", myread);
sys_call_table_R__ver_sys_call_table[3] = myread;
sys_call_table_R__ver_sys_call_table[4] = mywrite;
return 0;
}
void cleanup_module()
{
int i;
//以下打印部分用于调试,可以去除
for(i = 0; i < 5; i++ )
{
// if(readCount_R__ver_readCount[i].pid == 1873)
// {
printk("i = %d\n", i);
printk("name = %s, pid = %d, readCount_R__ver_readCount = %d, tag = %d\n",
readCount_R__ver_readCount[i].pname, readCount_R__ver_readCount[i].pid,
readCount_R__ver_readCount[i].count, readCount_R__ver_readCount[i].tag);
printk("name = %s, pid = %d, writeCount_R__ver_writeCount = %d, tag = %d\n",
writeCount_R__ver_writeCount[i].pname, writeCount_R__ver_writeCount[i].pid,
writeCount_R__ver_writeCount[i].count, writeCount_R__ver_writeCount[i].tag);
// }
}
sys_call_table_R__ver_sys_call_table[3] = a;
sys_call_table_R__ver_sys_call_table[4] = b;
printk("Quit...\n");
}
6,增加对模块的测试:
文件名:test1.c
#include<stdio.h>
main()
{
printf("password \n");
return 0;
}
7,对系统调用的测试:
#include<stdio.h>
#include <linux/unistd.h>
#define __NR_getProcReadInfo 245
int errno;
/* 这里告诉编译器,getProcReadInfo系统调用的编号是245 */
_syscall2(int,getProcReadInfo, unsigned long, pid, struct proc_RW_info *, info)
main()
{
struct proc_RW_info rw;
if(getProcReadInfo(1864, &rw) == -14)
printf("ERROR!\n"); /* 在main函数里面使用了这个系统调用 */
printf("%d\n%d\n%d\n%d\n", rw.total_read_bytes, rw.total_write_bytes, rw.rtag, rw.wtag);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -