patch-test-and-proc
实验环境
Ubuntu 14.04.5 LTS
Linux - 4.15.6
为单个文件进程补丁操作
在桌面
Desktop建立文件夹patch,作为实验用,然后进入patch文件夹。建立测试文件test0、test1。我们的目标:给
test0打补丁test1.patch,使test0与test1内容一致:
注:使用
diff创建补丁test1.patch;源文件test0;目标文件test1;因为单个文件,所以不需要-r选项。选项顺序没有关系,即可以是-uN,也可以是-Nu。
给源文件
test0打补丁与恢复:
注:
-pN与patch文件中列出的文件名有关,N表示拿掉几个斜线(目录层级);-E选项说明如果发现了空文件,那么就删除它;-R选项说明在补丁文件中的“新”文件和“旧”文件现在要调换过来了(实际上就是给新版本打补丁,让它变成老版本)。
为多个文件进行补丁操作
在上文中的
/Desktop/patch文件夹下创建测试文件夹prj0:

注:在
patch文件夹下,创建文件夹prj0,并把test0拷入,再在文件夹prj0下创建文件prj0name;创建文件夹prj1,并把test1拷入,再在文件夹prj1下创建文件prj1name。然后返回patch目录下。创建补丁
diff的功能就是用来比较两个文件的不同,然后记录下来,也就是所谓的diff补丁。语法格式:diff【选项】 源文件(夹) 目的文件(夹)就是要给源文件(夹)打个补丁,使之变成目的文件(夹),术语也就是“升级”。下面介绍三个最为常用选项:
-r是一个递归选项,设置了这个选项,diff会将两个不同版本源代码目录中的所有对应文件全部都进行一次比较,包括子目录文件。-N选项确保补丁文件将正确地处理已经创建或删除文件的情况。-u选项以统一格式创建补丁文件,这种格式比缺省格式更紧凑些。

注:把所有
prj1目录下的文件,打补丁到prj0目录下。
注:复制 prj1.patch 到 prj0 文件夹下;
进入 prj0 目录下,打补丁,
-p1表示prj0/test0。
下面变通一下,不复制
.patch文件,执行:
总结:
单个文件
diff -uN from_file to_file > to_file.patch
patch -p0 < to_file.patch
patch -RE -p0 < to_file.patch
多个文件
diff -uNr from_docu to_docu > to_docu.patch
patch -p1 < to_docu.patch
patch -R -p1 < to_docu.patch
创建显示系统进程信息的 proc 模块
将
tasklist.c与修改后的tasklist.c(我们下边命名为:tasklist1.c) 生成补丁首先看一下系统中
proc目录下是否有tasklist这个文件
创建
tasklist.c、tasklist1.c和Makefile文件:
tasklist.c代码://------------------------------------------------------------------- // tasklist.c: 本内核文件创建一个proc伪文件,'/proc/tasklist' // 通过如下命令可以显示系统中所有进程的部分信息 // 注意:Makefile文件必须正确放置在当前目录下。 // 编译命令: make // 内核模块添加:$sudo insmod tasklist.ko // 添加内核模块后读取并信息tasklist内核信息: $ cat /proc/tasklist // 内核模块删除:$sudo rmmod tasklist // NOTE: Written and tested with Linux kernel version 4.15.6 // strace函数可用于追踪系统调用,命令格式如下所示: // $ strace cat /proc/tasklist //------------------------------------------------------------------- #include <linux/module.h> // for init_module() #include <linux/proc_fs.h> // for create_proc_info_entry() #include <linux/sched/task.h> // for init_task #include <linux/seq_file.h> // for sequence files #include <linux/slab.h> // for kzalloc, kfree #include <linux/sched/signal.h> //for next_task char modname[] = "tasklist"; struct task_struct *task; int taskcounts=0; // 'global' so value will be retained static void * my_seq_start(struct seq_file *m, loff_t *pos) { ///printk(KERN_INFO"Invoke start\n"); //可以输出调试信息 if ( *pos == 0 ) // 表示遍历开始 { task = &init_task; //遍历开始的记录地址 return &task; //返回一个非零值表示开始遍历 } else //遍历过程中 { if (task == &init_task ) //重新回到初始地址,退出 return NULL; return (void*)pos ;//否则返回一个非零值 } } static int my_seq_show(struct seq_file *m, void *v) {//获取进程的相关信息 //printk(KERN_INFO"Invoke show\n"); //输出进程序号 seq_printf( m, "#%-3d\t ", taskcounts++ ); //输出进程pid? //输出进程state? //输出进程名称(comm)? seq_puts( m, "\n" ); return 0; } static void * my_seq_next(struct seq_file *m, void *v, loff_t *pos) { //printk(KERN_INFO"Invoke next\n"); (*pos)++; //task指向下一个进程? return NULL; } static void my_seq_stop(struct seq_file *m, void *v) { //printk(KERN_INFO"Invoke stop\n"); // do nothing } static struct seq_operations my_seq_fops = {//序列文件记录操作函数集合 .start = my_seq_start, .next = my_seq_next, .stop = my_seq_stop, .show = my_seq_show }; static int my_open(struct inode *inode, struct file *file) { return seq_open(file, &my_seq_fops); //打开序列文件并关联my_seq_fops } static const struct file_operations my_proc = { //proc文件操作函数集合 .owner = THIS_MODULE, .open = my_open, .read = seq_read, .llseek = seq_lseek, .release = seq_release }; int __init my_init( void ) { struct proc_dir_entry* my_proc_entry; printk( "<1>\nInstalling \'%s\' module\n", modname ); my_proc_entry = proc_create(modname, 0x644, NULL, &my_proc);//生成proc文件 if (NULL == my_proc_entry) { return -ENOMEM; } return 0; //SUCCESS } void __exit my_exit( void ) { remove_proc_entry( modname, NULL );//删除proc文件 printk( "<1>Removing \'%s\' module\n", modname ); } module_init(my_init); module_exit(my_exit); MODULE_LICENSE("GPL");tasklist1.c代码://------------------------------------------------------------------- // tasklist.c: 本内核文件创建一个proc伪文件,'/proc/tasklist' // 通过如下命令可以显示系统中所有进程的部分信息 // 注意:Makefile文件必须正确放置在当前目录下。 // 编译命令: make // 内核模块添加:$sudo insmod tasklist.ko // 添加内核模块后读取并信息tasklist内核信息: $ cat /proc/tasklist // 内核模块删除:$sudo rmmod tasklist // NOTE: Written and tested with Linux kernel version 4.15.6 // strace函数可用于追踪系统调用,命令格式如下所示: // $ strace cat /proc/tasklist //------------------------------------------------------------------- #include <linux/module.h> // for init_module() #include <linux/proc_fs.h> // for create_proc_info_entry() #include <linux/sched/task.h> // for init_task #include <linux/seq_file.h> // for sequence files #include <linux/slab.h> // for kzalloc, kfree #include <linux/sched/signal.h> //for next_task char modname[] = "tasklist"; struct task_struct *task; int taskcounts=0; // 'global' so value will be retained static void * my_seq_start(struct seq_file *m, loff_t *pos) { ///printk(KERN_INFO"Invoke start\n"); //可以输出调试信息 if ( *pos == 0 ) // 表示遍历开始 { task = &init_task; //遍历开始的记录地址 return &task; //返回一个非零值表示开始遍历 } else //遍历过程中 { if (task == &init_task ) //重新回到初始地址,退出 return NULL; return (void*)pos ;//否则返回一个非零值 } } static int my_seq_show(struct seq_file *m, void *v) {//获取进程的相关信息 //printk(KERN_INFO"Invoke show\n"); //输出进程序号 seq_printf( m, "#%-3d\t ", taskcounts++ ); //输出进程pid? seq_printf( m, "%5d\t", task->pid ); //输出进程state? seq_printf( m, "%lu\t", task->state ); //输出进程名称(comm)? seq_printf( m, "%-15s ", task->comm ); seq_puts( m, "\n" ); return 0; } static void * my_seq_next(struct seq_file *m, void *v, loff_t *pos) { //printk(KERN_INFO"Invoke next\n"); (*pos)++; //task指向下一个进程? task = next_task(task); return NULL; } static void my_seq_stop(struct seq_file *m, void *v) { //printk(KERN_INFO"Invoke stop\n"); // do nothing } static struct seq_operations my_seq_fops = {//序列文件记录操作函数集合 .start = my_seq_start, .next = my_seq_next, .stop = my_seq_stop, .show = my_seq_show }; static int my_open(struct inode *inode, struct file *file) { return seq_open(file, &my_seq_fops); //打开序列文件并关联my_seq_fops } static const struct file_operations my_proc = { //proc文件操作函数集合 .owner = THIS_MODULE, .open = my_open, .read = seq_read, .llseek = seq_lseek, .release = seq_release }; int __init my_init( void ) { struct proc_dir_entry* my_proc_entry; printk( "<1>\nInstalling \'%s\' module\n", modname ); my_proc_entry = proc_create(modname, 0x644, NULL, &my_proc);//生成proc文件 if (NULL == my_proc_entry) { return -ENOMEM; } return 0; //SUCCESS } void __exit my_exit( void ) { remove_proc_entry( modname, NULL );//删除proc文件 printk( "<1>Removing \'%s\' module\n", modname ); } module_init(my_init); module_exit(my_exit); MODULE_LICENSE("GPL");Makefile代码:ifneq ($(KERNELRELEASE),) obj-m := tasklist.o else KDIR := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) default: $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules rm -r -f .tmp_versions *.mod.c .*.cmd *.o *.symvers endif给
tasklist.c打补丁tasklist1.patch:
在
~/Desktop/module_test文件夹下,编译:
模块
tasklist.ko已经添加入内核,现在可以查看tasklist文件的内核信息了:
通过模块传参,传入进程名隐藏相应进程。
卸载模块
tasklist.ko:
在
~/Desktop/module_test目录下,新建如下tasklist2.c目标文件://------------------------------------------------------------------- // tasklist.c: 本内核文件创建一个proc伪文件,'/proc/tasklist' // 通过如下命令可以显示系统中所有进程的部分信息 // 注意:Makefile文件必须正确放置在当前目录下。 // 编译命令: make // 内核模块添加:$sudo insmod tasklist.ko // 添加内核模块后读取并信息tasklist内核信息: $ cat /proc/tasklist // 内核模块删除:$sudo rmmod tasklist // NOTE: Written and tested with Linux kernel version 4.15.6 // strace函数可用于追踪系统调用,命令格式如下所示: // $ strace cat /proc/tasklist //------------------------------------------------------------------- #include <linux/module.h> // for init_module() #include <linux/proc_fs.h> // for create_proc_info_entry() #include <linux/sched/task.h> // for init_task #include <linux/seq_file.h> // for sequence files #include <linux/slab.h> // for kzalloc, kfree #include <linux/sched/signal.h> //for next_task #include <linux/string.h> char modname[] = "tasklist"; struct task_struct *task; int taskcounts=0; // 'global' so value will be retained static char* var; module_param(var,charp,0644); static void * my_seq_start(struct seq_file *m, loff_t *pos) { ///printk(KERN_INFO"Invoke start\n"); //可以输出调试信息 if ( *pos == 0 ) // 表示遍历开始 { task = &init_task; //遍历开始的记录地址 return &task; //返回一个非零值表示开始遍历 } else //遍历过程中 { if (task == &init_task ) //重新回到初始地址,退出 return NULL; return (void*)pos ;//否则返回一个非零值 } } static int my_seq_show(struct seq_file *m, void *v) {//获取进程的相关信息 //printk(KERN_INFO"Invoke show\n"); //输出进程序号 seq_printf( m, "#%-3d\t ", taskcounts++ ); //输出进程pid? seq_printf( m, "%5d\t", task->pid ); //输出进程state? seq_printf( m, "%lu\t", task->state ); //输出进程名称(comm)? seq_printf( m, "%-15s ", task->comm ); seq_puts( m, "\n" ); return 0; } static void * my_seq_next(struct seq_file *m, void *v, loff_t *pos) { //printk(KERN_INFO"Invoke next\n"); (*pos)++; //task指向下一个进程? task = next_task(task); if(!strcmp(task->comm,var)) { task = next_task(task); } return NULL; } static void my_seq_stop(struct seq_file *m, void *v) { //printk(KERN_INFO"Invoke stop\n"); // do nothing } static struct seq_operations my_seq_fops = {//序列文件记录操作函数集合 .start = my_seq_start, .next = my_seq_next, .stop = my_seq_stop, .show = my_seq_show }; static int my_open(struct inode *inode, struct file *file) { return seq_open(file, &my_seq_fops); //打开序列文件并关联my_seq_fops } static const struct file_operations my_proc = { //proc文件操作函数集合 .owner = THIS_MODULE, .open = my_open, .read = seq_read, .llseek = seq_lseek, .release = seq_release }; int __init my_init( void ) { struct proc_dir_entry* my_proc_entry; printk( "<1>\nInstalling \'%s\' module\n", modname ); printk( KERN_INFO"var=%s\n", var ); my_proc_entry = proc_create(modname, 0x644, NULL, &my_proc);//生成proc文件 if (NULL == my_proc_entry) { return -ENOMEM; } return 0; //SUCCESS } void __exit my_exit( void ) { remove_proc_entry( modname, NULL );//删除proc文件 printk( "<1>Removing \'%s\' module\n", modname ); } module_init(my_init); module_exit(my_exit); MODULE_LICENSE("GPL");
给
tasklist.c打补丁tasklist2.patch在
~/Desktop/module_test文件夹下:$ make $ sudo insmod tasklist.ko var = "init" $ cat /proc/tasklist
注:
init进程就被隐藏了。注意:
insmod命令后一定要给var传递参数,否则可能会出现下面问题
解决办法是重启系统,重新加在模块(执行
insmod命令)并记得给var传递参数。卸载
tasklist.ko模块,重新insmod进内核,var赋个空字符串。init进程就显示了:
上述办法是在执行
insmod命令时,给变量var(进程名)赋值。归根结底是tasklist.c文件中变量var未初始化造成的,另一种办法是初始化tasklist.c文件中的变量var。比如:static char* var; // 将此行替换为下面这行 static char* var = " "; // 给 var 初始化为空串然后:
$ make $ sudo insmod tasklist.ko // 此处可不给var传参,因为代码中已经初始化了 $ cat /proc/tasklist // 显示全部进程 $ sudo rmmod tasklist.ko // 卸载tasklist.ko模块 $ sudo insmod tasklist.ko var = "输入你想隐藏的进程名" $ cat /proc/tasklist // 发现指定的进程已被隐藏,显示隐藏的进程请看前一步
Reference
Linux下使用diff和patch制作及打补丁(已经实践可行!)
patch-test-and-proc的更多相关文章
- 利用 SysRq 键排除和诊断系统故障
说白了,SysRq手动触发而不用命令, /proc/sysrq-trigger 这个是通过命令接口 实验:LINUX窗口下 ,CTRL+ALT+F1,切换到TTY1,在文本模式下,按下 ALT+Sys ...
- oracle 数据库安装环境,需要大汇总
Oracle Database (RDBMS) on Unix AIX,HP-UX,Linux,Mac OS X,Solaris,Tru64 Unix Operating Systems Ins ...
- 每日一小时linux(1)--sysRq
参考https://www.ibm.com/developerworks/cn/linux/l-cn-sysrq/index.html SysRq 是什么 你是否遇到服务器不能通过 SSH 登录,也不 ...
- 为什么ps中CPU占用率会有超出%100的现象?
前面的关于ps中的%CPU的含义一文已经介绍了CPU占用率的含义,那么为什么有时会在ps的输出中看到CPU占用率超出%100的现象呢?我们知道在/proc目录下每个进程都会有一个以它的PID以名字的目 ...
- Windows X64 Patch Guard
先简单介绍下PatchGuard ,摘自百度百科 PatchGuard就是Windows Vista的内核保护系统,防止任何非授权软件试图“修改”Windows内核,也就是说,Vista内核的新型金钟 ...
- Android内核sys_setresuid() Patch提权(CVE-2012-6422)
让我们的Android ROOT,多一点套路. 一.简单套路 CVE-2012-6422的漏洞利用代码,展示了另一种提权方法.(见附录) 这也是一个mmap驱动接口校验导致映射任意内核地址的洞.将内核 ...
- proc 文件系统学习
proc.txt翻译 ------------------------------------------------------------------------------Version 1.3 ...
- grep,cut,wc,sort,diff,uniq,patch命令
文本处理工具: Linux上文本处理三剑客: grep,egrep,fgrep: 文本过滤工具(模式: pattern)工具; grep:基本正则表达式,-E,-F egrep:扩展正则表达式,-G, ...
- kernel build & preempt-rt patch & xenomai
提前准备好 linux 内核源代码,假设是 x86 系统.能够去下载原生内核(Vanilla kernel): wget https://www.kernel.org/pub/linux/kernel ...
- kubectl 之 patch 命令
patch命令 kubectl patch — Update field(s) of a resource using strategic merge patch Synopsis kubectl p ...
随机推荐
- python --- 19 判断对象所属,区分函数和对象, 反射
一.判断对象所属 isinstance, type , issubclass 1.issubclass(x,y) 判断x是否是y 的子类 2.type(x) 精准返回x 的数据类型 3.isi ...
- topcoder srm 400 div1
problem1 link 枚举指数,然后判断是不是素数即可. problem2 link 令$f[len][a][b][r]$(r=0或者1)表示子串$init[a,a+len-1]$匹配$goal ...
- Oracle错误——ORA-01691: Lob 段SFZXP.SYS_LOB0000030381C00004$$无法通过8192(在表空间USERS中)扩展
问题 Oracle报错:ORA-01691: Lob 段SFZXP.SYS_LOB0000030381C00004$$无法通过8192(在表空间USERS中)扩展 问题原因 Oracle数据表空间不足 ...
- LuoguP3674 小清新人渣的本愿 && BZOJ4810: [Ynoi2017]由乃的玉米田
题目地址 小清新人渣的本愿 [Ynoi2017]由乃的玉米田 所以这两题也就输出不一样而已 题解 这种lxl的题还是没修改操作的题基本就是莫队 分开考虑每个询问 1.减法 \(a-b=x⇒a=b+x\ ...
- Winform异步解决窗体耗时操作(Action专门用于无返回值,Func专门用于有返回值)
http://blog.csdn.net/config_man/article/details/25578767 #region 调用timer控件实时查询开关机时间 private void tim ...
- P1829 [国家集训队]Crash的数字表格 / JZPTAB
推式子太快乐啦!虽然我好蠢而且dummy和maomao好巨(划掉) 思路 莫比乌斯反演的题目 首先这题有\(O(\sqrt n)\)的做法但是我没写咕咕咕 然后就是爆推一波式子 \[ \sum_{i= ...
- windows service in vs
用 vs2013 创建 windows service 程序 vs2015开发Windows服务 VS 2010一步步开发windows服务(windows service)
- 洛谷P1679神奇的四次方数--DP
原题请戳>>https://www.luogu.org/problem/show?pid=1679<< 题目描述 在你的帮助下,v神终于帮同学找到了最合适的大学,接下来就要通知 ...
- log4j2打印Mybatis执行的SQL语句及SQL语句的执行时间
http://blog.csdn.net/zjq852533445/article/details/78320012
- 19. --mus-- 音乐,娱乐(词20)