Reptile Reading
目录结构
Reptile-master├── configs│ └── defconfig├── Kconfig├── kernel│ ├── backdoor.c # done│ ├── dir.c # done│ ├── encrypt│ │ └── encrypt.c # done rotate 13 算法加密│ ├── file.c # done│ ├── include│ │ ├── backdoor.h # done│ │ ├── config.h│ │ ├── dir.h # done│ │ ├── encrypt.h # done│ │ ├── file.h # done│ │ ├── module.h # done│ │ ├── network.h # done│ │ ├── proc.h # done│ │ ├── string_helpers.h # done│ │ └── util.h # done│ ├── Kbuild│ ├── khook│ │ ├── engine.c│ │ ├── engine.h│ │ ├── engine.lds│ │ ├── internal.h│ │ └── x86│ │ ├── hook.c│ │ ├── Makefile│ │ ├── README.md│ │ ├── stub32.inc│ │ ├── stub.inc│ │ └── stub.S│ ├── kmatryoshka│ │ ├── Kbuild│ │ └── kmatryoshka.c│ ├── loader│ │ └── loader.c # done│ ├── main.c #│ ├── module.c # done│ ├── network.c # done│ ├── proc.c # done│ ├── string_helpers.c│ └── util.c # done├── Makefile├── scripts│ ├── bashrc│ ├── destringify.pl│ ├── installer.sh│ ├── kconfig│ │ ├── check.sh│ │ ├── conf.c│ │ ├── confdata.c│ │ ├── config.sh│ │ ├── expr.c│ │ ├── expr.h│ │ ├── foo.h│ │ ├── gconf.c│ │ ├── gconf.glade│ │ ├── GNUmakefile│ │ ├── images.c│ │ ├── kxgettext.c│ │ ├── list.h│ │ ├── lkc.h│ │ ├── lkc_proto.h│ │ ├── lxdialog│ │ │ ├── BIG.FAT.WARNING│ │ │ ├── checklist.c│ │ │ ├── check-lxdialog.sh│ │ │ ├── dialog.h│ │ │ ├── inputbox.c│ │ │ ├── menubox.c│ │ │ ├── textbox.c│ │ │ ├── util.c│ │ │ └── yesno.c│ │ ├── Makefile│ │ ├── Makefile.br│ │ ├── mconf.c│ │ ├── menu.c│ │ ├── merge_config.sh│ │ ├── nconf.c│ │ ├── nconf.gui.c│ │ ├── nconf.h│ │ ├── patches│ │ │ ├── 01-kconfig-kernel-to-buildroot.patch│ │ │ ├── 06-br-build-system-integration.patch│ │ │ ├── 100-kconfig-generic-env.patch│ │ │ ├── 101-kconfig-build.patch│ │ │ ├── 10-br-build-system.patch│ │ │ ├── 11-use-mktemp-for-lxdialog.patch│ │ │ ├── 12-fix-glade-file-path.patch│ │ │ ├── 14-support-out-of-tree-config.patch│ │ │ ├── 15-fix-qconf-moc-rule.patch│ │ │ ├── 16-fix-space-to-de-select-options.patch│ │ │ └── series│ │ ├── POTFILES.in│ │ ├── qconf.cc│ │ ├── qconf.h│ │ ├── README.buildroot│ │ ├── streamline_config.pl│ │ ├── symbol.c│ │ ├── util.c│ │ ├── zconf.gperf│ │ ├── zconf.hash.c_shipped│ │ ├── zconf.l│ │ ├── zconf.lex.c_shipped│ │ ├── zconf.tab.c_shipped│ │ └── zconf.y│ ├── lib│ │ └── Unescape.pm│ ├── random.sh│ ├── rule│ └── start└── userland├── client│ ├── client.c│ ├── listener.c│ └── packet.c├── cmd.c├── crypto│ ├── aes.c│ └── sha1.c├── include│ ├── aes.h│ ├── config.h│ ├── custom_rol32.h│ ├── pel.h│ ├── sha1.h│ └── util.h├── Makefile├── shell.c└── transport└── pel.c
kernel
kernel/├── backdoor.c # done├── dir.c # done├── encrypt│ └── encrypt.c # rol32加密├── file.c # this module can't work properly├── include│ ├── backdoor.h # done│ ├── config.h # done│ ├── dir.h # done│ ├── encrypt.h # done│ ├── file.h # done│ ├── module.h # done│ ├── network.h # done│ ├── proc.h # done│ ├── string_helpers.h│ └── util.h├── Kbuild├── khook # 第三方钩子模板 khook│ ├── engine.c│ ├── engine.h│ ├── engine.lds│ ├── internal.h│ └── x86│ ├── hook.c│ ├── Makefile│ ├── README.md│ ├── stub32.inc│ ├── stub.inc│ └── stub.S├── kmatryoshka # 第三方库 kmatryoshka LKM loader│ ├── Kbuild│ └── kmatryoshka.c├── loader│ └── loader.c├── main.c├── module.c # done├── network.c # done├── proc.c # done├── string_helpers.c└── util.c
- 感觉这种堆叠也挺好的,开发快速,前提是看过和用过的东西要多
主逻辑分析
关键函数分析
技术分析
- make config(kconfig)
总结
参考资料
(1/3)Khook代码分析
kconfig
- https://blog.csdn.net/jianwen_hi/article/details/53398141
- https://blog.csdn.net/whatday/article/details/102095114
- https://blog.csdn.net/y24283648/article/details/108608966
- https://blog.csdn.net/liangdapo/article/details/43699655
内核函数
[call_usermodehelper(char *path, char **argv, char **envp, enum umh_wait wait);](https://www.cnblogs.com/embedded-linux/p/7439984.html)
linux kernel提供了call_usermodehelper,用于内核中直接新建和运行用户空间程序,并且该程序具有root权限。void *skb_header_pointer(const struct sk_buff *skb, int offset, int len, void *buffer)- skb_header_pointer这个函数的主要功能很简单,就是从skb字段中获取指定长度到内容到缓存中。
- memzero_explicit
- argv_split
- ftell、fseek、rewind
- memmove
- proc部分
- rcu_read_lock、rcu_read_unlock
- find_get_pid、put_pid
- get_pid_task、put_task_struct: 释放进程内核栈和thread_info结构所占的页,释放task_struct占用的slab高速缓存
- for_each_process
- kstrtoint
- strncpy_from_user
- kallsyms_on_each_symbol
- module部分
- mutex_trylock
- mutex_unlock
- module_mutex这个锁在哪
- cpu_relax
- THIS_MODULE
- util部分
- ksym_lookup_name 符号中查找函数
- access_process_vm
- get_task_mm、mmput
- down_read、up_read
- kmatryoshka
- __builtin_alloca
- current_thread_info()->addr_limit.seg
- kallsyms_on_each_symbol
- roundup
- PAGE_SIZE
内核结构体、宏
- work_struct
有点类似于struct list,都是基础辅助结构体,我们只要拿到这个结构体,放入自己的结构体中(加入自己想要做的事情),使用特定函数头的函数,就可以使用对应的几个宏去完成自定义的任务的内核调度
内核里一直运行类似worker thread,它会对工作队列中的work进行处理,大致的工作流程原理可以参考下图所示:

在这里的work则是work_struct变量,并且绑定一个执行函数——typedef void (*work_func_t)(struct work_struct *work);。在worker thread中会对非空的工作队列进行工作队列的出队操作,并运行work绑定的函数。
| 函数 | 功能 |
|---|---|
| INIT_WORK(_work, _func) | 初始化一个work |
| INIT_WORK_ONSTACK(_work, _func) | 在栈上初始化一个work |
| flush_work(struct work_struct *work); | 销毁一个work |
| schedule_work(struct work_struct *work) | 调度一个work开始运行 |
- task_struct
- GFP_KERNEL、GFP_ATOMIC
- sk_buff
- iphdr
- icmphdr
- tcphdr
- udphdr
- struct pid
- find_get _pid
- get_pid_task
- put_task_struct
- put_pid
- gfp_t
- mm_struct
- typeof 此关键字返回变量的类型,可用于变量声明
__attribute__((section(".data.khook")))表示分配到.data.khook节ldflags-y += -T$(src)/khook/engine.lds
SECTIONS{.data : {KHOOK_tbl = . ; # . 表示当前定位器符号的位置,所以KHOOK_tbl指的.data.khook开头*(.data.khook)KHOOK_tbl_end = . ; # KHOOK_tbl_end指的.data.khook结尾}}
- 这一坨没完全分析清楚,只说明是stub填充物(这个STUB会被初始化为stub.inc或stub32.inc。也就是stub的模板)
typedef struct {// 摆上了16字节(计数)、32字节(原函数地址)、64字节(hook地址)#pragma pack(push, 1)union {unsigned char _0x00_[ 0x10 ];atomic_t use_count;};union {unsigned char _0x10_[ 0x20 ];unsigned char orig[0];};union {unsigned char _0x30_[ 0x40 ];unsigned char hook[0];};#pragma pack(pop)// 这是什么类型??unsigned nbytes;} __attribute__((aligned(32))) khook_stub_t;
