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;