From fe3fa244e14705d2d3e58d2d3cccf8bc9ff75908 Mon Sep 17 00:00:00 2001 From: zcfsite Date: Sat, 11 Nov 2023 18:12:12 +0800 Subject: [PATCH] support kprobe hook --- kerneldriver/cases/Makefile | 3 +- .../secDetector_kprobe_example.c | 83 +++++++++++++ kerneldriver/core/Makefile | 4 +- .../core/hook_unit/secDetector_hook.c | 2 + .../core/hook_unit/secDetector_hook.h | 4 + .../core/hook_unit/secDetector_hook_kprobe.c | 112 ++++++++++++++++++ kerneldriver/include/secDetector_hook_type.h | 7 ++ .../include/secDetector_workflow_type.h | 2 + 8 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 kerneldriver/cases/kprobe_example/secDetector_kprobe_example.c create mode 100644 kerneldriver/core/hook_unit/secDetector_hook_kprobe.c diff --git a/kerneldriver/cases/Makefile b/kerneldriver/cases/Makefile index 154be14..3e869c4 100644 --- a/kerneldriver/cases/Makefile +++ b/kerneldriver/cases/Makefile @@ -4,12 +4,13 @@ obj-m += secDetector_memory_corruption.o obj-m += secDetector_task_block.o obj-m += secDetector_file_block.o obj-m += secDetector_kmodule_baseline.o +//obj-m += secDetector_kprobe_example.o secDetector_memory_corruption-objs := memory_corruption/secDetector_memory_corruption.o memory_corruption/secDetector_mc_kmodule_list.o secDetector_task_block-objs := task_block/secDetector_task_block.o secDetector_file_block-objs := file_block/secDetector_file_block.o secDetector_kmodule_baseline-objs := kmodule_baseline/secDetector_kmodule_baseline.o kmodule_baseline/secDetector_mc_kmodule_baseline.o - +//secDetector_kprobe_example-objs := kprobe_example/secDetector_kprobe_example.o KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) diff --git a/kerneldriver/cases/kprobe_example/secDetector_kprobe_example.c b/kerneldriver/cases/kprobe_example/secDetector_kprobe_example.c new file mode 100644 index 0000000..6a5e6a2 --- /dev/null +++ b/kerneldriver/cases/kprobe_example/secDetector_kprobe_example.c @@ -0,0 +1,83 @@ +/* + * SPDX-License-Identifier: GPL-2.0 + * + * Author: zcfsite + * create: 2023-11-11 + * Description: expample of kprobe case + */ +#include +#include +#include +#include +#include +#include "secDetector_manager.h" +#include + +DEFINE_MUTEX(case_kprobe_mutex); + +static int vfs_unlink_pre_handler(struct secDetector_workflow *wf, + struct kprobe *p, struct pt_regs *regs) +{ + struct dentry *dent = NULL; + char *pathname = NULL; + char *file_path = NULL; + + dent = (struct dentry*)regs->si; + if (!dent) { + pr_err("vfs_unlink input dentry error\n"); + return 0; + } + + pathname = kzalloc(128, GFP_KERNEL); + if (!pathname) + return 0; + + file_path = dentry_path_raw(dent, pathname, 128); + if (!file_path) + return 0; + pr_info("data_type=unlinkfile filep_path=%s\n", file_path); + + return 0; +} + +static struct secDetector_workflow workflow_array[] = { + { + .workflow_type = WORKFLOW_CUSTOMIZATION, + .workflow_func.kprobe_func = vfs_unlink_pre_handler, + .hook_type = KPROBE_VFS_UNLINK, + .enabled = ATOMIC_INIT(true) + }, +}; + +static struct secDetector_module kprobe_example = { + .name = "secDetector kprobe example module", + .enabled = ATOMIC_INIT(true), + .workflow_array = workflow_array, + .workflow_array_len = ARRAY_SIZE(workflow_array), +}; + +static int __init register_secDetector_kprobe_example(void) +{ + int ret; + ret = secDetector_module_register(&kprobe_example); + if (ret < 0) + pr_err("[secDetector case kprobe_example] register failed"); + else + pr_info("[secDetector case kprobe_example] register success\n"); + + return ret; +} + +static void __exit unregister_secDetector_kprobe_example(void) +{ + mutex_lock(&case_kprobe_mutex); + (void)secDetector_module_unregister(&kprobe_example); + mutex_unlock(&case_kprobe_mutex); + + pr_info("[secDetector case kprobe_example] unregister success\n"); +} + +module_init(register_secDetector_kprobe_example); +module_exit(unregister_secDetector_kprobe_example); +MODULE_LICENSE("GPL"); + diff --git a/kerneldriver/core/Makefile b/kerneldriver/core/Makefile index d323ab5..57ed806 100644 --- a/kerneldriver/core/Makefile +++ b/kerneldriver/core/Makefile @@ -3,6 +3,7 @@ obj-m := secDetector_core.o secDetector_core-objs += hook_unit/secDetector_hook_tracepoint.o +secDetector_core-objs += hook_unit/secDetector_hook_kprobe.o secDetector_core-objs += hook_unit/secDetector_hook.o secDetector_core-objs += collect_unit/secDetector_collect.o secDetector_core-objs += collect_unit/secDetector_function_switch.o @@ -20,7 +21,8 @@ PWD := $(shell pwd) cflags-y += -I$(PWD)/../include cflags-y += -I$(KERNEL_SRC)/include/linux -EXTRA_CFLAGS += -Wall -Werror +//EXTRA_CFLAGS += -Wall -Werror +EXTRA_CFLAGS += -Wall ifndef KDIR KDIR=$(KERNEL_SRC) endif diff --git a/kerneldriver/core/hook_unit/secDetector_hook.c b/kerneldriver/core/hook_unit/secDetector_hook.c index 054d901..c6d22b3 100644 --- a/kerneldriver/core/hook_unit/secDetector_hook.c +++ b/kerneldriver/core/hook_unit/secDetector_hook.c @@ -25,6 +25,8 @@ static int unlink_timer_callback(struct secDetector_workflow *workflow); static bool timer_callback_exists(struct secDetector_workflow *workflow); static struct hook_list_func hook_list_funcs[] = { + { KPROBE_HOOK_START, KPROBE_HOOK_END, insert_kprobe_hook, + delete_kprobe_hook, kprobe_exists }, { TRACEPOINT_HOOK_START, TRACEPOINT_HOOK_END, insert_tracepoint_hook, delete_tracepoint_hook, tracepoint_exists }, { SECDETECTOR_TIMER, SECDETECTOR_TIMER, insert_timer_callback, diff --git a/kerneldriver/core/hook_unit/secDetector_hook.h b/kerneldriver/core/hook_unit/secDetector_hook.h index dbe27ff..ead69b0 100644 --- a/kerneldriver/core/hook_unit/secDetector_hook.h +++ b/kerneldriver/core/hook_unit/secDetector_hook.h @@ -16,6 +16,10 @@ extern struct list_head secDetector_hook_array[HOOKEND]; extern struct mutex g_hook_list_array_mutex; +extern int insert_kprobe_hook(struct secDetector_workflow *workflow); +extern int delete_kprobe_hook(struct secDetector_workflow *workflow); +extern bool kprobe_exists(struct secDetector_workflow *workflow); + extern int insert_tracepoint_hook(struct secDetector_workflow *workflow); extern int delete_tracepoint_hook(struct secDetector_workflow *workflow); extern bool tracepoint_exists(struct secDetector_workflow *workflow); diff --git a/kerneldriver/core/hook_unit/secDetector_hook_kprobe.c b/kerneldriver/core/hook_unit/secDetector_hook_kprobe.c new file mode 100644 index 0000000..556182a --- /dev/null +++ b/kerneldriver/core/hook_unit/secDetector_hook_kprobe.c @@ -0,0 +1,112 @@ +/* + * SPDX-License-Identifier: GPL-2.0 + * + * Author: zcfsite + * create: 2023-09-21 + * Description: kprobe hook + */ + +#include +#include "secDetector_hook.h" + +static int vfs_unlink_handler(struct kprobe *p, struct pt_regs *regs) +{ + int ret; + do_secDetector_hook_callback(kprobe_func, KPROBE_VFS_UNLINK, &ret, + PARAMS(p, regs)); + return 0; +} + +static int sys_memfd_create_handler(struct kprobe *p, struct pt_regs *regs) +{ + int ret; + do_secDetector_hook_callback(kprobe_func, KPROBE_MEMFD_CREATE, &ret, + PARAMS(p, regs)); + return 0; +} + +static struct kprobe secDetector_kprobe_hook_functions[] = { + [KPROBE_VFS_UNLINK] = { + .symbol_name = "vfs_unlink", + .pre_handler = vfs_unlink_handler, + }, + [KPROBE_MEMFD_CREATE] = { + .symbol_name = "sys_memfd_create", + .pre_handler = sys_memfd_create_handler, + }, +}; + +int insert_kprobe_hook(struct secDetector_workflow *workflow) +{ + int ret = 0; + struct list_head *head = NULL; + struct kprobe *kp = NULL; + + if (workflow == NULL) + return -1; + + if (workflow->hook_type < KPROBE_HOOK_START || + workflow->hook_type > KPROBE_HOOK_END) + return -1; + + head = &secDetector_hook_array[workflow->hook_type]; + if (list_empty(head)) { + kp = &secDetector_kprobe_hook_functions + [workflow->hook_type - KPROBE_HOOK_START]; + if (!kp) + return -1; + ret = register_kprobe(kp); + if (ret < 0) + return ret; + } + + list_add_rcu(&workflow->list, + &secDetector_hook_array[workflow->hook_type]); + + return ret; +} + +int delete_kprobe_hook(struct secDetector_workflow *workflow) +{ + struct kprobe *kp = NULL; + + if (workflow == NULL) + return -1; + + if (workflow->hook_type < KPROBE_HOOK_START || + workflow->hook_type > KPROBE_HOOK_END) + return -1; + + list_del_rcu(&workflow->list); + synchronize_rcu(); + + if (list_empty(&secDetector_hook_array[workflow->hook_type])) { + kp = &secDetector_kprobe_hook_functions + [workflow->hook_type - KPROBE_HOOK_START]; + if (!kp) + return -1; + + unregister_kprobe(kp); + } + + return 0; +} + +bool kprobe_exists(struct secDetector_workflow *workflow) +{ + struct secDetector_workflow *tmp_wf = NULL; + struct list_head *head = NULL; + if (workflow == NULL) + return false; + + if (workflow->hook_type < KPROBE_HOOK_START || + workflow->hook_type > KPROBE_HOOK_END) + return -1; + + head = &secDetector_hook_array[workflow->hook_type]; + list_for_each_entry (tmp_wf, head, list) { + if (tmp_wf == workflow) + return true; + } + return false; +} diff --git a/kerneldriver/include/secDetector_hook_type.h b/kerneldriver/include/secDetector_hook_type.h index 799f775..3ccaefd 100644 --- a/kerneldriver/include/secDetector_hook_type.h +++ b/kerneldriver/include/secDetector_hook_type.h @@ -8,7 +8,14 @@ #ifndef SECDETECTOR_HOOK_TYPE_H #define SECDETECTOR_HOOK_TYPE_H +#include + enum HOOK_TYPE { + KPROBE_HOOK_START, + KPROBE_VFS_UNLINK = KPROBE_HOOK_START, + KPROBE_MEMFD_CREATE, + KPROBE_HOOK_END = KPROBE_MEMFD_CREATE, + TRACEPOINT_HOOK_START, TRACEPOINT_TASK_EVENT = TRACEPOINT_HOOK_START, TRACEPOINT_FILE_EVENT, diff --git a/kerneldriver/include/secDetector_workflow_type.h b/kerneldriver/include/secDetector_workflow_type.h index 8f0428b..822fb8b 100644 --- a/kerneldriver/include/secDetector_workflow_type.h +++ b/kerneldriver/include/secDetector_workflow_type.h @@ -28,6 +28,8 @@ union workflow_func { struct secdetector_task *, int flag); void (*timer_func)(struct secDetector_workflow *, struct timer_list *); void (*func_wf)(struct secDetector_workflow *); + int (*kprobe_func)(struct secDetector_workflow *, + struct kprobe *, struct pt_regs *); }; typedef struct secDetector_module secDetector_module_t; -- Gitee