Ubuntu20.04+Linux5.8.8 添加系统调用实现进程隐藏

虚拟机版本 主机信息
VMware 15 Thinkpad carbon X1 2020 + win10

目录

  • Ubuntu20.04+Linux5.8.8 添加系统调用实现进程隐藏
    • 1 目标
    • 2. 方法与原理
      • 2.1 修改proc_pid_readdir
      • 2.2 ~~pid赋值为0~~
      • 2.3 原理
    • 3 遇到的困难
      • 3.1 虚拟机开机黑屏
    • 4 流程

1 目标

  • 实现系统调用int hide(pid_t pid, int on),在进程pid有效的前提下,如果on置1,进程被隐藏,用户无法通过ps或top观察到进程状态;如果on置0且此前为隐藏状态,则恢复正常状态。
  • 考虑权限问题,根用户才能隐藏进程。
  • 设计一个新的系统调用int hide_user_processes(uid_t uid, char *binname),参数uid为用户ID号,当binname参数为NULL时,隐藏该用户的所有进程;否则,隐藏二进制映像名为binname的用户进程。该系统调用应与hide系统调用共存。

2. 方法与原理

2.1 修改proc_pid_readdir

  • 安全的方法
  • 原理
  1. proc目录中保存着正在运行的全部进程的相关信息文件,可以调用proc_pid_readdir逐一读取。
  2. 在进程的task_struct结构体中自定义一个hide变量,proc_pid_readdir()函数中加入判断条件,如果hide=1就跳过对该进程信息的读取。
  3. 自添加的系统调用通过修改该变量,实现进程的查看隐藏与恢复显示

2.2 pid赋值为0

  • 投机取巧的危险的方法。
  • 只对Linux早期版本(如2.x)有效。但是之后的版本无效,非常不建议使用,有太多bug。
  • 原理:0号init进程不会被ps和top指令显示。
  • Bug:隐藏的进程如果不恢复,重启后无法进入正确的0号init进程,导致死机。

2.3 原理

关键是理解和linux进程相关的结构体task_struct、结构体pid和结构体cred等,用于创建进程的fork函数的源码的基本实现。
详见我精选的参考博文:

  • Linux进程描述符task_struct结构体详解
  • linux中和进程有关的API
  • Linux进程ID号

3 遇到的困难

3.1 虚拟机开机黑屏

  • 最有效的方法:使用快照备份关键节点
  • 相关博文推荐:link,基本可以解决90%的Ubuntu系统崩溃问题。

4 流程

  1. 按照官网的步骤,完成对kernel代码修改Adding a New System Call
  • 在kernel/sys.c文件里面末尾添加两个系统调用,使用SYSCALL_DEFINE2
SYSCALL_DEFINE2(hide, pid_t, pid,int,on)
{printk("hide process invoked with params: pid=%d on=%d\n",pid,on);printk("current uid = %d\n", get_current_cred()->uid.val);//if( get_current_cred()->uid.val != 0) //判断是否为root用户if(!uid_eq(current_euid(),GLOBAL_ROOT_UID)){printk("you aren't the root user! try to use sudo!\n");return -1;}struct task_struct *p;struct task_struct * me = NULL;p = &init_task;do{printk("check proc with pid = %d and old_pid = %d\n", p->pid,p->old_pid);if( pid == p->old_pid )      //pid_t == int   old_pid is global pid{me = p;break;} }while( ( p = next_task(p) ) && ( p != &init_task ) );  //next_task get the next PCB pointer, //it's a loop list, so the stop signal is p != &init_task!if(me == NULL ) //判断pid是否有效{printk("the target pid doesn't exist!\n");return -2;}if( on == 1 ){  printk("hide proccess with pid=%d\n",me->pid);me->hide = 1;  //置隐藏标志为1}else{if( me->hide == 1 ){printk("reveal proccess with pid=%d\n",me->pid);me->hide = 0;}}printk("nice system call! goodbye!\n");return 0;
}SYSCALL_DEFINE2(hide_user_process,uid_t,uid,char*,binname){struct task_struct *p;struct user_namespace *ns = current_user_ns();struct pid *thread_pid;char buf[TASK_COMM_LEN];char buf2[TASK_COMM_LEN];int hide,i;kuid_t kuid;kuid = make_kuid(ns, uid);printk("hide_user_proc invoked");printk(" uid=%d ",uid);if(binname!=NULL){copy_from_user(buf2,binname,TASK_COMM_LEN);printk(" binname=%s",buf2);}else printk(" binname=NULL");for_each_process(p){if(uid_eq(task_uid(p),kuid)){hide=1;get_task_comm(buf, p);if(binname!=NULL){for(i=0;buf2[i];i++){if(!buf[i]||buf[i]!=buf2[i]){hide=0;break;}}if(buf[i])hide=0;}printk("scan on '%s' hide it? =%d",buf,hide);if(hide){p -> hide = 1;thread_pid = get_pid(p->thread_pid);proc_flush_pid(thread_pid);}}}return 0;
}
  • 在include/linux/syscalls.h中的对应位置添加函数声明,注意返回值都是long,因为是64位系统
asmlinkage long sys_hide( pid_t pid, int on );                        //my system call
asmlinkage long sys_hide_user_process( uid_t uid, char* binname );    //my system call
  • 在include/uapi/asm-generic/unistd.h中的对应位置添加函数声明,同时注意修改 __NR_syscalls 440为__NR_syscalls 442
#define __NR_xyzzy 440
__SYSCALL(__NR_hide, sys_hide)
#define __NR_xyzzy 441
__SYSCALL(__NR_hide_user_process, sys_hide_user_process)
  • 修改arch/x86/entry/syscalls/syscall_64.tbl,该表是x86_64的系统调用表,对应位置添加如下信息
440 64      hide       sys_hide
441 64      hide_user_process  sys_hide_user_process
  • 在fs/proc/base.c中修改函数 proc_pid_readdir,在3343行之后添加如下一行
if (iter.task->hide==1) continue;
  • 修改结构体task_struct,在include/linux/sched.h中636行之后添加如下
int hide;
  • 修改进程派生的fork函数,在kernel/fork.c的2443行之后添加
p->hide = 0;
  1. 编译修改后的内核
# 从官网下载5.8.8的linux内核的压缩包,解压并在终端打开
# 依次修改对应位置的源码之后,执行如下指令sudo make mrproper sudo make clean #进入界面后,直接exit,再yes,一般这个步骤的调整会影响微内核的大小,进而影响开机时间
sudo make menuconfig# 我给ubuntu虚拟机的配置是,1个处理器,6个内核
#本机的CPU为一个CORE i7-10710U CPU, 6核12线程
sudo make -j12  # 同时允许最多12线程并行,约1h20minsudo make modules_install        //安装内核模块sudo make install      //安装内核reboot
  1. 重启后,使用测试程序测试系统调用的准确性

待续

Ubuntu20.04+Linux5.8.8 添加系统调用实现进程隐藏相关推荐

  1. 【Linux、进程隐藏】在Linux环境下添加系统调用实现进程隐藏

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 [进程隐藏]在Linux环境下添加系统调用实现进程隐藏 前言 一.环境设置: 二.实现方法步骤: 1.思路图 2.利用strace命令 ...

  2. 西电软工操作系统实验:编译Ubuntu18.04新内核并添加系统调用(含代码以及详细分析)

    西电软工操作系统实验一:编译Linux内核 目录 (一)前言 (二)实验内容 (三)实验环境 (四)实验过程 4.1安装虚拟机 4.2虚拟机换源 4.3 添加系统调用内核 4.4 下载编译所需的软件依 ...

  3. Linux实验 | Ubuntu20.04编译内核并添加一个系统调用

    实验环境 Ubuntu 20.04 LTS VMware Workstation Pro 16 Linux Kernel 5.10.2 存储空间至少留55GB,我第一次做就因为空间不够编译失败,最后编 ...

  4. Ubuntu20.04中fastdfs,nginx的安装和配置(apt-get安装nginx添加fastdfs-nginx-module模块)

    Ubuntu20.04中fastdfs,nginx的安装和配置 环境准备: 编译环境: Ubuntu20.04 使用的系统软件: fastdfs-6.07 fastdfs-nginx-module-1 ...

  5. Ubuntu20.04交叉编译Vlc3.0.16,并添加录像接口

    准备工作 1.准备好ubuntu20.04的编译环境,虚拟机.云服务器都可 2.去官方网站查询一下指定编译步骤This page will help you to compile VLC media ...

  6. Ubuntu20.04添加用户到root组方法

    Ubuntu20.04安装后,默认没有root用户,只有一个oem的用户.新建了一个用户,执行sudo时总是出问题,查了很多资料,一般都讲得十分复杂,6~7个甚至上10个步骤,一下子看蒙了.因此解决问 ...

  7. 操作系统实验:添加系统调用修改主机名(hostname)

    实验环境配置 Ubuntu18.04.5,Linux内核:5.9.6,VMware Workstation Pro,内存:4G,CPU:4x1=4核,外存:128G. ubuntu安装.内核源码下载及 ...

  8. linux内核添加系统调用(详细)

    linux内核添加系统调用(详细) 说在前面: 这是我第五次编译内核,分别踩了很多坑.中途问过wz佬,佬让我用qemu.我还是最后换ubuntu虚拟机跑了.现在已经有点emo了. 这篇博客是我第五次的 ...

  9. 【Linux系列】添加系统调用

    [Linux系列]添加系统调用最新教程 编译环境 修改任务 基础任务 进阶任务 修改准备 修改源码 添加系统调用号 修改系统调用头文件 修改系统调用函数定义 编译安装内核 编写主程序 进阶任务 总结 ...

最新文章

  1. php程序内存优化之数组操作优化
  2. Python list 数据类型:列表
  3. C指针原理(16)-C指针基础
  4. WPF依赖属性(续)(1)
  5. 互联网企业互相屏蔽对方的链接,这种事情以后不行了!
  6. EasyBert,基于Pytorch的Bert应用
  7. 【超参数寻优】交叉验证(Cross Validation)超参数寻优的python实现:多参数寻优
  8. 字符编码ASCII,Unicode和UTF-8
  9. [转]MySQL和SQLServer的比较
  10. eclipse 配置多个tomcat
  11. html 下载 txt 文件
  12. Datalogic得利捷推出物流应用领域全新标杆产品——AV900
  13. win7 桌面计算机不显示器,Win7电脑显示器黑屏不显示的解决方案
  14. vue中使用粒子特效
  15. java applepay_ApplePay对接java后台详细代码
  16. 超参数自动优化方法PBT(Population Based Training)
  17. excel如何自动填充123456……
  18. Python习题练习 + 简单语法总结
  19. Hololens开发学习笔记-4
  20. Cooapods为iOS项目配置SnapKit等第三方框架

热门文章

  1. Rubber Ducky简介
  2. noi题目P4206 [NOI2005] 聪聪与可可
  3. 乐视 无法播放服务器文件夹,乐视电视最新常见问题及解决方法分享!
  4. 2016福州大学软件工程助教总结_排骨
  5. 新手如何学好C语言?
  6. vue数组去重 数组对象去重
  7. cordova wifi插件(cordova plugin add cordova-plugin-hotspot)
  8. Informatica 中文字符
  9. python数据分析比较好的书籍_python数据分析比较好的书籍推荐|陇川制作项目盈利能力分析...
  10. 离散数学 --- 谓词逻辑 --- 谓词符号化与谓词合式公式