【Operating System】 基于Android为进程添加级别及调试

最近在学习 操作系统

看到每个进程都有 pid 等很多属性。 那我们可以做到修改或者添加进程的某个属性, 进而影响操作系统的运行吗?

本文 以 Android 系统为例,尝试为进程添加级别属性。

第一步 是要找到进程属性的定义的地方。在/include/linux/sched.h内的 task_struct 结构体内定义了许多属性。那首先,笔者在此处添加了p_level属性。

第二步是 在相同文件夹下,可以观测到有一个syscall.h 文件。这个头文件内定义了系统调用的函数列表。我们定义的P_level显然需要基本的 set 和 get 功能。此时我们需要将这两个函数添加进入syscall的头文件内。

第三步 对于系统调用而言。一般会有一个tbl的表格,表明了所有的系统调用的代号。我们自己生成的调用函数,也要保存在内才行。对于64位的系统,一般在 /arch/x86/entry/syscalls/syscall_64.tbl 内会定义。此处要用Tab啊。不然会识别不出来。

如果有需要的话,比如设定默认的属性时。还需要修改kernel内的fork.c文件。此我们就将它默认值设为0了

此时我们基本完成了系统设置的内容。我们在 syscall 表内添加了我们自定义的call,然后在syscall的头文件内定义了函数名。在进程的属性结构体内添加了自定义的属性。那下面,我们要做的就是实现我们定义的函数了。

创建一个Level.c 文件如下,然后在Makefile内添加 core-y  += Level/ .

记得要在Level文件夹下写Makefile,使之变成可执行文件。

然后 sudo make 就可以啦~

# include <linux/kernel.h>
# include <linux/sched.h>
# include <linux/pid.h>

asmlinkage int sys_set_P_level(int pid, int level){
    struct task_struct *task;
    //若小于0, 则返回err
	if (level < 0) return -1; 
    /* 普通用户时 */
	if (current_euid().val !=0){
        //当前进程?
        if (pid == current->pid){
            //当前进程要比设置的level高
            int temp = current->P_level>=level ? level : -1; 
            if(temp != -1) current->P_level = level;
            return temp;
        }
        else{
            for_each_process(task){
                //寻找进程,而且要修改的级别小于当前进程时方可修改
          	    if(task->pid == pid && current->P_level > task->P_level){
                        int temp = current->P_level>=level ? level : -1;
                        if(temp != -1) task->P_level = level;
                        return temp;
                }
            }
            return -1;
        }          
    }
    /* 当用户是root user时,自带最高级别属性*/
    else{
        for_each_process(task){ //寻找对应进程
            if(task->pid == pid )  {
                task->P_level = level; 
                return task->P_level;
            }
        }
        //未找到则返回err
        return -1;
    }
} 

asmlinkage int sys_get_P_level (int pid){
    /* 对于get函数 就很简单 
        遍历进程池 
        若找到则return P_level, otherwise return -1;
    */
}

这个项目的报告 也附在下面了:


- 对于这个项目,我创建了一个包含我的用户空间的文件 调用系统调用函数来获取和设置进程的访问级别。
- 在内核空间。我创建了一个文件夹,名为Level和内部创建一个Level.c和make文件。
- make文件包含“obj-y:= Level.o”确保Level.c文件被编译和包含在内核源代码。
- Level.c文件包含调用系统调用的函数。
- 要添加两个新的系统调用,我编辑了定义系统调用的syscalls.h文件签名和定义的系统调用编号和名称syscall_64.tbl文件
的系统调用。
- 我还要编辑内核Makefile以包含Level文件夹,这告诉了编译器,新的系统调用是存在于Level目录。
- 通过创建调用两个系统调用的用户空间函数来执行测试。 我首先开始使用一个简单的系统调用,它接受用户空间变量并在控制台中打印,以验证功能是否成功。 然后我继续访问进程表并读取进程表中的不同参数。 还创建了用户空间函数来专门调用系统调用。 随着流程的继续,整个开发就像快速原型。 创建简单的功能并继续构建它们,直到它满足项目要求。。

 

posted @ 2018-06-27 23:09  chris1030  阅读(316)  评论(0编辑  收藏  举报