kernel: make injected init service name random

This commit is contained in:
weishu
2023-01-02 22:19:01 +07:00
parent 2e8645b50e
commit 5229b8158e

View File

@@ -1,5 +1,6 @@
#include "linux/workqueue.h" #include <linux/gfp.h>
#include <linux/workqueue.h>
#include <asm/current.h> #include <asm/current.h>
#include <linux/cred.h> #include <linux/cred.h>
#include <linux/dcache.h> #include <linux/dcache.h>
@@ -146,10 +147,11 @@ static int execve_handler_pre(struct kprobe *p, struct pt_regs *regs)
return 0; return 0;
} }
#define RC_SERVICE_NAME_LENGTH 8
static const char KERNEL_SU_RC[] = static const char KERNEL_SU_RC[] =
"\n" "\n"
"service ksud /data/adb/ksud post-fs-data\n" "service %s /data/adb/ksud post-fs-data\n"
" user root\n" " user root\n"
" seclabel u:r:su:s0\n" " seclabel u:r:su:s0\n"
" oneshot\n" " oneshot\n"
@@ -157,7 +159,7 @@ static const char KERNEL_SU_RC[] =
"\n" "\n"
"on post-fs-data\n" "on post-fs-data\n"
" start ksud\n" " start %s\n"
"\n" "\n"
"\n" "\n"
; ;
@@ -165,6 +167,17 @@ static const char KERNEL_SU_RC[] =
static void unregister_vfs_read_kp(); static void unregister_vfs_read_kp();
static struct work_struct unregister_vfs_read_work; static struct work_struct unregister_vfs_read_work;
static void fill_random_name(char* rc) {
int i = 0;
char name[RC_SERVICE_NAME_LENGTH];
get_random_bytes(name, RC_SERVICE_NAME_LENGTH);
for (i = 0; i < RC_SERVICE_NAME_LENGTH; i++) {
u32 remainder = (name[i] & 0xFF) % 26; // 'a' - 'z' 26 character
name[i] = 'a' + remainder;
}
sprintf(rc, KERNEL_SU_RC, name, name);
}
static int read_handler_pre(struct kprobe *p, struct pt_regs *regs) static int read_handler_pre(struct kprobe *p, struct pt_regs *regs)
{ {
struct file *file; struct file *file;
@@ -212,7 +225,13 @@ static int read_handler_pre(struct kprobe *p, struct pt_regs *regs)
// now we can sure that the init process is reading `/system/etc/init/vold.rc` // now we can sure that the init process is reading `/system/etc/init/vold.rc`
buf = PT_REGS_PARM2(regs); buf = PT_REGS_PARM2(regs);
count = PT_REGS_PARM3(regs); count = PT_REGS_PARM3(regs);
size_t rc_count = strlen(KERNEL_SU_RC);
// generate a random service name and fill it to rc bytes
char rc[sizeof(KERNEL_SU_RC) + RC_SERVICE_NAME_LENGTH * 2];
fill_random_name(rc);
pr_info("random rc: %s\n", rc);
size_t rc_count = strlen(rc);
pr_info("vfs_read: %s, comm: %s, count: %d, rc_count: %d\n", dpath, current->comm, count, rc_count); pr_info("vfs_read: %s, comm: %s, count: %d, rc_count: %d\n", dpath, current->comm, count, rc_count);
@@ -220,7 +239,8 @@ static int read_handler_pre(struct kprobe *p, struct pt_regs *regs)
pr_err("count: %d < rc_count: %d", count, rc_count); pr_err("count: %d < rc_count: %d", count, rc_count);
return 0; return 0;
} }
size_t ret = copy_to_user(buf, KERNEL_SU_RC, rc_count);
size_t ret = copy_to_user(buf, rc, rc_count);
if (ret) { if (ret) {
pr_err("copy ksud.rc failed: %d\n", ret); pr_err("copy ksud.rc failed: %d\n", ret);
return 0; return 0;