存档在 2014年3月

通过call_usermodehelper()在内核态执行用户程序

2014年3月24日

背景

如何在Linux内核中执行某些用户态程序或系统命令?在用户态中,可以通过execve()实现;在内核态,则可以通过call_usermodehelpere()实现该功能。如果您查阅了call_usermodehelper()内核函数的源码实现,就可以发现该函数最终会执行do_execve()。而execve系统调用在经历内核的系统调用流程后,也会最终调用do_execve()。

使用举例

1.无输出的可执行文件测试

加载函数demo如下所示:

static int __init call_usermodehelper_init(void)
{
	int ret = -1;
	char path[] = "/bin/mkdir";
	char *argv[] = {path, "-p", "/home/tester/new/new_dir", NULL};

	printk("call_usermodehelper module is starting..!\n");
	ret = call_usermodehelper(path, argv, envp, UMH_WAIT_PROC);
	printk("ret=%d\n", ret);
	return 0;
}

卸载函数demo如下所示:

static void __exit call_usermodehelper_exit(void)
{
	int ret = -1;
	char path[] = "/bin/rm";
	char *argv[] = {path, "-r", "/home/tester/new", NULL};
	char *envp[] = {NULL};

	printk("call_usermodehelper module is starting..!\n");
	ret = call_usermodehelper(path, argv, envp, UMH_WAIT_PROC);
	printk("ret=%d\n", ret);
}

2.有输出的可执行文件测试

如果该可执行文件有输出,则可以利用输出重定向,不过此时的可执行文件应该是/bin/bash,而实际的可执行文件则称为bash的参数。比如如果想在内核执行ls -la命令,并且将其输出重定向到ls_output中,则在上述的argv[]={“/bin/bash”, “-c”, “ls”, “-la”, “>”, “/home/tester/ls_output”, NULL};

本文虽然说明的是在内核态如何调用用户态程序,不过可以将这种方法抽象一下,看作是内核态主动向用户态发起通信的一种方式。

Linux内核中通过文件描述符获取绝对路径

2014年3月19日

背景

在Linux内核中,已知一个进程的pid和其打开文件的文件描述符fd,如何获取该文件的绝对路径?基本思路是先获取该文件在内核中的file结构体,再通过d_path()获取到整个文件的绝对路径。

方法一

如果理解了进程和文件系统数据结构之间的关系,那么这种方法可以采用。基本的方法如下:

1.通过进程pid获取进程描述符task_struct;

2.通过task_struct获取该进程打开文件结构files_struct,从而获取文件描述符表;

3.以fd为索引在文件描述符表中获取对应文件的结构体file;

4.通过file获取对应path结构,该结构封装当前文件对应的dentry和挂载点;

5.通过内核函数d_path()获取该文件的绝对路径;

通过进程pid获取进程描述符demo:

struct task_struct *get_proc(pid_t pid)
{
	struct pid *pid_struct = NULL;
	struct task_struct *mytask = NULL;

	pid_struct = find_get_pid(pid);
	if (!pid_struct)
		return NULL;
	mytask = pid_task(pid_struct, PIDTYPE_PID);
	return mytask;
}

通过fd以及d_path()获取绝对路径demo:

int get_path(struct task_struct *mytask, int fd)
{
        struct file *myfile = NULL;
        struct files_struct *files = NULL;
        char path[100] = {'\0'};
        char *ppath = path;

        files = mytask->files;
        if (!files) {
                printk("files is null..\n");
                return -1;
        }
        myfile = files->fdt->fd[fd];
        if (!myfile) {
                printk("myfile is null..\n");
                return -1;
        }
        ppath = d_path(&(myfile->f_path), ppath, 100);

        printk("path:%s\n", ppath);
        return 0;
}

从上面的代码可以看出,从fd到file结构的获取均通过各个数据结构之间的指向关系获取。

方法二

与方法一的思路相同,但是可以直接使用内核提供的函数fget()进行fd到file的获取。这种方法使用比较简单,程序更加安全,不过就是少了对数据结构关系的思考过程。其实也可以将fget()函数的实现过程作为参考,欣赏内核中代码实现的严谨性。

 

windows 7 ultimate product key

windows 7 ultimate product key

winrar download free

winrar download free

winzip registration code

winzip registration code

winzip free download

winzip free download

winzip activation code

winzip activation code

windows 7 key generator

windows 7 key generator

winzip freeware

winzip freeware

winzip free download full version

winzip free download full version

free winrar download

free winrar download

free winrar

free winrar

windows 7 crack

windows 7 crack

windows xp product key

windows xp product key

windows 7 activation crack

windows7 activation crack

free winzip

free winzip

winrar free download

winrar free download

winrar free

winrar free

download winrar free

download winrar free

windows 7 product key

windows 7 product key