该项工作主要分为两部,其一获得特定进程的名字,找到指定进程的task_struct
其二根据task_struct获得文件对象表struct file,其代码如下:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/stat.h>
#include <linux/fs.h>
#include<linux/sched.h>
#include<linux/dcache.h>
#include<linux/fdtable.h>
#include<linux/string.h>
#include <linux/fcntl.h>//for O_RDONLY
#include <linux/uaccess.h>//for get_fs
#include <linux/limits.h>//for PATH_MAX
#include <linux/mm.h>
#include <linux/slab.h>
MODULE_LICENSE("GPL");
extern char *d_path(const struct path *, char *, int);
extern char *dentry_path_raw(struct dentry *, char *, int);
static int hello_init(void)
{
printk(KERN_ALERT "My Kernel Begin\n");
if(NULL==current)
{
printk(KERN_ALERT "get current failed \n");
return 0;
}
printk(KERN_ALERT "get current successfully \n");
struct task_struct *task;
struct list_head *list;
for(list=(&(current->tasks))->next; list!=¤t->tasks; list=list->next)
{
task=list_entry(list, struct task_struct, tasks);
if(strstr(task->comm,"gedit")!=NULL)//获得指定进程的task_struct
{
task_lock(task);
printk(KERN_ALERT "this is process %s\n",task->comm);
char * tpath= NULL;
tpath=(char*)kmalloc(2048,GFP_KERNEL);
char *tmp=(char*)kmalloc(2048,GFP_KERNEL);
if(tpath==NULL||tmp==NULL)
return 0;
int i=0;
struct files_struct*files=task->files;
if(NULL!=files)
{
struct fdtable* fdt=files->fdt;
while(fdt!=NULL)
{
i=0;
for(;i<NR_OPEN_DEFAULT;i++)//默认打开表是NR_OPEN_DEFAULT
{
char* path=NULL;
struct file* file=fdt->fd[i];
if(file!=NULL&&file->f_path.dentry!=NULL)
{
char*result=NULL;
if(file->f_path.dentry->d_name.name!=NULL)
result==strstr(file->f_path.dentry->d_name.name,".c");//查找制定类型的文件
if(result!=NULL)
{
printk(KERN_ALERT "maybe this is our file\n");
printk(KERN_ALERT "FILE NAME IS :%s\n",file->f_path.dentry->d_name.name);
memset(tmp,0,2048);
if((file->f_path.dentry!=NULL)&&(file->f_path.mnt!=NULL))
path = d_path(&(file->f_path),tmp,2048);
if(path!=NULL)
{
memset(tpath,0,2048);
strcpy(tpath,path);
printk(KERN_ALERT "the file name is %s\n",tpath);
memset(path,0,2048);
}
}
else
{
printk(KERN_ALERT "NOT MY WANT\n");
}
}
}
fdt=fdt->next;
}
}
task_unlock(task);
kfree(tpath);
kfree(tmp);
}
}
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Goodbye,Cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
其makefile如下
obj-m := hello.o
all:
make -C /lib/modules/`uname -r`/build SUBDIRS=$(PWD) modules #`uname -r` 指的是linux的版本号 $(PWD)当前目录
clean:
make -C /lib/modules/`uname -r`/build SUBDIRS=$(PWD) clean
#就是说首先改变目录到-C选项指定的目录(即内核源代码目录),SUBDIRS=选项让该makefile在构造modules目标返回之前到模块源代码目录。然后,modules目标指向obj-m变量设定的模块。
# subsystem:
cd subdir && $(MAKE)
其等价于:
subsystem:
$(MAKE) -C subdir
$(MAKE) -C subdir
定义$(MAKE)宏变量的意思是,也许我们的make需要一些参数,所以定义成一个变量比较利于维护。这两个例子的意思都是先进入“subdir”目录,然后执行make命令。
我们把这个Makefile叫做“总控Makefile”,总控Makefile的变量可以传递到下级的Makefile中(如果你显示的声明),但是不会覆盖下层的Makefile中所定义的变量,除非指定了“-e”
使用make编译连接之后,sudo insmod ./hello.ko即可
使用
tail -100 /var/log/syslog
查看输出信息