### Example: Check KernelPatch and Get Version Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/super-syscall.md Demonstrates how to check if KernelPatch is installed and retrieve its version along with the kernel version. ```APIDOC ## Example: Check KernelPatch and Get Version ```c #include #include "supercall.h" int main(void) { const char *key = "mysuperkey"; if (!sc_ready(key)) { printf("KernelPatch not installed\n"); return 1; } uint32_t kp_ver = sc_kp_ver(key); uint32_t k_ver = sc_k_ver(key); printf("KernelPatch version: %d.%d.%d\n", (kp_ver >> 16) & 0xff, (kp_ver >> 8) & 0xff, kp_ver & 0xff); printf("Kernel version: %d.%d.%d\n", (k_ver >> 16) & 0xff, (k_ver >> 8) & 0xff, k_ver & 0xff); return 0; } ``` ``` -------------------------------- ### Check KernelPatch and Get Version (C) Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/super-syscall.md This example demonstrates how to check if KernelPatch is installed and retrieve both KernelPatch and kernel versions. Ensure 'supercall.h' is included and the key is valid. ```c #include #include "supercall.h" int main(void) { const char *key = "mysuperkey"; if (!sc_ready(key)) { printf("KernelPatch not installed\n"); return 1; } uint32_t kp_ver = sc_kp_ver(key); uint32_t k_ver = sc_k_ver(key); printf("KernelPatch version: %d.%d.%d\n", (kp_ver >> 16) & 0xff, (kp_ver >> 8) & 0xff, kp_ver & 0xff); printf("Kernel version: %d.%d.%d\n", (k_ver >> 16) & 0xff, (k_ver >> 8) & 0xff, k_ver & 0xff); return 0; } ``` -------------------------------- ### FP Hook Syscall (`fp_hook_syscalln`) Example Source: https://context7.com/bmax121/kernelpatch/llms.txt Demonstrates installing two independent function-pointer hooks on the `openat` syscall. Ensure `CONFIG_HAVE_SYSCALL_WRAPPERS` is handled automatically. Use `syscall_argn` for reading arguments. ```c #include #include #include #include #include #include KPM_NAME("kpm-syscall-hook-demo"); KPM_VERSION("1.0.0"); KPM_LICENSE("GPL v2"); KPM_AUTHOR("author"); KPM_DESCRIPTION("Syscall hook example"); static uint64_t open_count = 0; // Chain 0: log the filename void before_openat_log(hook_fargs4_t *args, void *udata) { const char __user *filename = (typeof(filename))syscall_argn(args, 1); char buf[256]; compat_strncpy_from_user(buf, filename, sizeof(buf)); pr_info("[chain0] openat: %s\n", buf); } // Chain 1: count opens and log return value void before_openat_count(hook_fargs4_t *args, void *udata) { uint64_t *cnt = (uint64_t *)udata; (*cnt)++; } void after_openat_count(hook_fargs4_t *args, void *udata) { pr_info("[chain1] openat #%llu ret=%ld\n", *(uint64_t *)udata, (long)args->ret); // Block a specific call: // args->skip_origin = 1; // args->ret = (uint64_t)-EPERM; } static long my_init(const char *args, const char *event, void *reserved) { hook_err_t err; // Install two independent hooks on the same syscall err = fp_hook_syscalln(__NR_openat, 4, before_openat_log, NULL, NULL); if (err) pr_err("hook chain0 err: %d\n", err); err = fp_hook_syscalln(__NR_openat, 4, before_openat_count, after_openat_count, &open_count); if (err) pr_err("hook chain1 err: %d\n", err); return 0; } static long my_exit(void *reserved) { fp_unhook_syscalln(__NR_openat, before_openat_log, NULL); fp_unhook_syscalln(__NR_openat, before_openat_count, after_openat_count); return 0; } KPM_INIT(my_init); KPM_EXIT(my_exit); ``` -------------------------------- ### Minimal KPM Example Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/module.md A basic KernelPatch Module demonstrating metadata, init, control0, and exit callbacks. Includes necessary headers and logging. ```c #include #include #include #include #include KPM_NAME("kpm-hello-demo"); KPM_VERSION("1.0.0"); KPM_LICENSE("GPL v2"); KPM_AUTHOR("bmax121"); KPM_DESCRIPTION("KernelPatch Module Example"); static long hello_init(const char *args, const char *event, void *reserved) { pr_info("hello init, event: %s, args: %s\n", event, args); pr_info("kernelpatch version: %x\n", kpver); return 0; } static long hello_control0(const char *args, char *__user out_msg, int outlen) { char echo[64] = "echo: "; strncat(echo, args, 48); compat_copy_to_user(out_msg, echo, sizeof(echo)); return 0; } static long hello_exit(void *reserved) { pr_info("hello exit\n"); return 0; } KPM_INIT(hello_init); KPM_CTL0(hello_control0); KPM_EXIT(hello_exit); ``` -------------------------------- ### Example: Grant Root to Current Process Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/super-syscall.md Illustrates how to grant root privileges to the current process using `sc_su`. ```APIDOC ## Example: Grant Root to Current Process ```c #include "supercall.h" int grant_root(const char *key) { struct su_profile profile = { .uid = getuid(), .to_uid = 0, .scontext = "u:r:su:s0", }; return (int)sc_su(key, &profile); } ``` ``` -------------------------------- ### Example: Hook openat with Two Independent Chains Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/syscall-hook.md Demonstrates setting up two independent chains of hooks for the `openat` syscall using `fp_hook_syscalln`. Includes before and after callbacks, user data, and module initialization/exit functions. ```c #include #include #include #include #include #include #include KPM_NAME("kpm-syscall-hook-demo"); KPM_VERSION("1.0.0"); KPM_LICENSE("GPL v2"); KPM_AUTHOR("author"); KPM_DESCRIPTION("Syscall hook example"); uint64_t open_counts = 0; void before_openat_0(hook_fargs4_t *args, void *udata) { const char __user *filename = (typeof(filename))syscall_argn(args, 1); char buf[256]; compat_strncpy_from_user(buf, filename, sizeof(buf)); pr_info("chain0 before openat: %s\n", buf); } void before_openat_1(hook_fargs4_t *args, void *udata) { uint64_t *pcount = (uint64_t *)udata; (*pcount)++; pr_info("chain1 before openat count: %llu\n", *pcount); } void after_openat_1(hook_fargs4_t *args, void *udata) { pr_info("chain1 after openat ret: %ld\n", (long)args->ret); } static long my_init(const char *args, const char *event, void *reserved) { hook_err_t err; err = fp_hook_syscalln(__NR_openat, 4, before_openat_0, NULL, NULL); if (err) { pr_err("hook chain0 failed: %d\n", err); return 0; } err = fp_hook_syscalln(__NR_openat, 4, before_openat_1, after_openat_1, &open_counts); if (err) { pr_err("hook chain1 failed: %d\n", err); } return 0; } static long my_exit(void *reserved) { fp_unhook_syscalln(__NR_openat, before_openat_0, NULL); fp_unhook_syscalln(__NR_openat, before_openat_1, after_openat_1); return 0; } KPM_INIT(my_init); KPM_EXIT(my_exit); ``` -------------------------------- ### Example: Hook openat with Two Independent Chains Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/syscall-hook.md Demonstrates how to hook the `openat` syscall with two independent chains using the function pointer strategy. ```APIDOC ## Example: Hook openat with Two Independent Chains ```c #include #include #include #include #include #include #include KPM_NAME("kpm-syscall-hook-demo"); KPM_VERSION("1.0.0"); KPM_LICENSE("GPL v2"); KPM_AUTHOR("author"); KPM_DESCRIPTION("Syscall hook example"); uint64_t open_counts = 0; void before_openat_0(hook_fargs4_t *args, void *udata) { const char __user *filename = (typeof(filename))syscall_argn(args, 1); char buf[256]; compat_strncpy_from_user(buf, filename, sizeof(buf)); pr_info("chain0 before openat: %s\n", buf); } void before_openat_1(hook_fargs4_t *args, void *udata) { uint64_t *pcount = (uint64_t *)udata; (*pcount)++; pr_info("chain1 before openat count: %llu\n", *pcount); } void after_openat_1(hook_fargs4_t *args, void *udata) { pr_info("chain1 after openat ret: %ld\n", (long)args->ret); } static long my_init(const char *args, const char *event, void *reserved) { hook_err_t err; err = fp_hook_syscalln(__NR_openat, 4, before_openat_0, NULL, NULL); if (err) { pr_err("hook chain0 failed: %d\n", err); return 0; } err = fp_hook_syscalln(__NR_openat, 4, before_openat_1, after_openat_1, &open_counts); if (err) { pr_err("hook chain1 failed: %d\n", err); } return 0; } static long my_exit(void *reserved) { fp_unhook_syscalln(__NR_openat, before_openat_0, NULL); fp_unhook_syscalln(__NR_openat, before_openat_1, after_openat_1); return 0; } KPM_INIT(my_init); KPM_EXIT(my_exit); ``` ``` -------------------------------- ### Callback Signature Example Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/inline-hook.md The callback signature depends on the number of arguments (`argno`). This example shows the signature for `argno = 2`. ```c // For argno = 2 typedef void (*hook_chain2_callback)(hook_fargs2_t *fargs, void *udata); ``` -------------------------------- ### hook_wrap Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/inline-hook.md Installs a before and/or after callback for a target function, supporting multiple independent hooks on the same function via a chain. ```APIDOC ## hook_wrap ### Description Installs a `before` callback (called before the original function) and/or an `after` callback (called after the original function). Multiple callers can independently hook the same function using a chain. ### Signature ```c hook_err_t hook_wrap(void *func, int32_t argno, void *before, void *after, void *udata); ``` ### Parameters #### Path Parameters - **func** (void *) - Address of the target kernel function - **argno** (int32_t) - Number of arguments the target function takes (0–12) - **before** (void *) - Callback invoked before the original function (can be `NULL`) - **after** (void *) - Callback invoked after the original function (can be `NULL`) - **udata** (void *) - User data pointer passed to the callbacks ### Callback Signature ```c // For argno = 2 typedef void (*hook_chain2_callback)(hook_fargs2_t *fargs, void *udata); ``` ### Request Example ```c // Example usage with a function taking 2 arguments void *target_func = (void *)0x12345678; void before_callback(hook_fargs2_t *args, void *udata) { // Access arguments: args->arg0, args->arg1 // Modify arguments: args->arg0 = new_value; // Skip original function: args->skip_origin = 1; // Save data for after callback: args->local.data0 = args->arg0; } void after_callback(hook_fargs2_t *args, void *udata) { // Access original return value: args->ret // Modify return value: args->ret = new_return_value; // Access data from before callback: uint64_t saved_arg0 = args->local.data0; } hook_wrap(target_func, 2, before_callback, after_callback, NULL); ``` ### Response #### Success Response (0) - **hook_err_t** - Indicates success (0) or an error code. ``` -------------------------------- ### Hooking a 2-Argument Function Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/inline-hook.md Example of hooking a function with two arguments. It demonstrates setting up 'before' and 'after' callbacks to log argument values and the return value. Ensure the target function is findable via kallsyms_lookup_name and always unhook in the exit callback. ```c #include #include #include KPM_NAME("my-hook-module"); KPM_VERSION("1.0.0"); KPM_LICENSE("GPL v2"); KPM_AUTHOR("author"); KPM_DESCRIPTION("Inline hook example"); void before_add(hook_fargs2_t *args, void *udata) { pr_info("before add: arg0=%d, arg1=%d\n", (int)args->arg0, (int)args->arg1); // Optionally modify arguments: // args->arg0 = 42; // Optionally skip the original function: // args->skip_origin = 1; // args->ret = 0; } void after_add(hook_fargs2_t *args, void *udata) { pr_info("after add: ret=%d\n", (int)args->ret); // Optionally override return value: // args->ret = 100; } static long my_init(const char *args, const char *event, void *reserved) { void *target_func = (void *)kallsyms_lookup_name("target_function_name"); hook_err_t err = hook_wrap2(target_func, before_add, after_add, NULL); if (err != HOOK_NO_ERR) { pr_err("hook failed: %d\n", err); } return 0; } static long my_exit(void *reserved) { void *target_func = (void *)kallsyms_lookup_name("target_function_name"); hook_unwrap(target_func, before_add, after_add); return 0; } KPM_INIT(my_init); KPM_EXIT(my_exit); ``` -------------------------------- ### Auto-select Syscall Hook (`hook_syscalln`) Example Source: https://context7.com/bmax121/kernelpatch/llms.txt Automatically selects the best hooking strategy (inline or function-pointer) for the running kernel. Use this when explicit strategy control is not needed. Ensure arguments are read using `syscall_argn`. ```c #include #include #include void before_unlinkat(hook_fargs3_t *args, void *udata) { const char __user *path = (typeof(path))syscall_argn(args, 1); char buf[PATH_MAX]; compat_strncpy_from_user(buf, path, sizeof(buf)); pr_info("unlinkat: %s\n", buf); } static long my_init(const char *args, const char *event, void *reserved) { return hook_syscalln(__NR_unlinkat, 3, before_unlinkat, NULL, NULL); } static long my_exit(void *reserved) { unhook_syscalln(__NR_unlinkat, before_unlinkat, NULL); return 0; } ``` -------------------------------- ### Super Command: Superkey Management Source: https://github.com/bmax121/kernelpatch/blob/main/doc/zh-CN/super-command.md Manages the superkey. Requires superkey authentication. Allows getting, setting, and configuring hash verification for the superkey. ```bash truncate key <子命令> [...] ``` ```bash truncate key get ``` ```bash truncate key set mynewsecretkey ``` ```bash truncate key hash enable ``` -------------------------------- ### Hook Local Data Usage Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/inline-hook.md The `fargs->local` slots can be used to pass context between `before` and `after` callbacks. This example saves `arg0` in the `before` callback for use in the `after` callback. ```c void before_fn(hook_fargs2_t *args, void *udata) { args->local.data0 = args->arg0; // Save arg0 for use in after } void after_fn(hook_fargs2_t *args, void *udata) { uint64_t saved = args->local.data0; } ``` -------------------------------- ### Hook Wrap Signature Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/inline-hook.md The `hook_wrap` function installs a before and/or after callback for a target kernel function. Typed convenience wrappers `hook_wrap0` through `hook_wrap12` are available. ```c hook_err_t hook_wrap(void *func, int32_t argno, void *before, void *after, void *udata); ``` -------------------------------- ### `hook_wrap` / `hook_unwrap` Source: https://context7.com/bmax121/kernelpatch/llms.txt Installs `before` and/or `after` callbacks around a kernel function identified by its virtual address. Callbacks are chained if multiple KPMs hook the same function. Supports up to 16 chain items per function. ```APIDOC ## `hook_wrap` / `hook_unwrap` — Chain-based function inline hook (recommended) ### Description Installs a `before` and/or `after` callback around any kernel function, identified by its virtual address. Multiple KPMs can independently hook the same function; their callbacks are chained in insertion order. Supports up to 16 chain items per function (`HOOK_CHAIN_NUM`). Use the typed convenience wrappers `hook_wrap0`–`hook_wrap12` for compile-time argument-count type checking. ### Usage Example ```c #include #include #include KPM_NAME("kpm-inlinehook-demo"); KPM_VERSION("1.0.0"); KPM_LICENSE("GPL v2"); KPM_AUTHOR("author"); KPM_DESCRIPTION("Inline hook example"); // Called BEFORE the target function executes // fargs->arg0, arg1 hold the first two arguments; modify them to change what the function sees // Set fargs->skip_origin = 1 to prevent the original function from running void before_add(hook_fargs2_t *fargs, void *udata) { pr_info("before add: arg0=%d arg1=%d\n", (int)fargs->arg0, (int)fargs->arg1); fargs->local.data0 = fargs->arg0; // stash arg0 for the after callback // fargs->arg0 = 42; // optionally override arg // fargs->skip_origin = 1; // optionally skip original; set fargs->ret too } // Called AFTER the target function; fargs->ret holds (and can override) the return value void after_add(hook_fargs2_t *fargs, void *udata) { pr_info("after add: original_arg0=%d ret=%d\n", (int)fargs->local.data0, (int)fargs->ret); // fargs->ret = 100; // override return value } static long my_init(const char *args, const char *event, void *reserved) { void *target = (void *)kallsyms_lookup_name("target_function_name"); if (!target) { pr_err("symbol not found\n"); return -1; } hook_err_t err = hook_wrap2(target, before_add, after_add, NULL); if (err != HOOK_NO_ERR) pr_err("hook_wrap2 failed: %d\n", err); return 0; } static long my_exit(void *reserved) { void *target = (void *)kallsyms_lookup_name("target_function_name"); hook_unwrap(target, before_add, after_add); // always unhook in exit return 0; } KPM_INIT(my_init); KPM_EXIT(my_exit); ``` ``` -------------------------------- ### Chain-based Inline Hook with Callbacks Source: https://context7.com/bmax121/kernelpatch/llms.txt Use `hook_wrap` to install `before` and/or `after` callbacks around a kernel function. Callbacks are chained if multiple KPMs hook the same function. Supports up to 16 chain items. Use typed wrappers like `hook_wrap2` for compile-time argument checking. ```c #include #include #include KPM_NAME("kpm-inlinehook-demo"); KPM_VERSION("1.0.0"); KPM_LICENSE("GPL v2"); KPM_AUTHOR("author"); KPM_DESCRIPTION("Inline hook example"); // Called BEFORE the target function executes // fargs->arg0, arg1 hold the first two arguments; modify them to change what the function sees // Set fargs->skip_origin = 1 to prevent the original function from running void before_add(hook_fargs2_t *fargs, void *udata) { pr_info("before add: arg0=%d arg1=%d\n", (int)fargs->arg0, (int)fargs->arg1); fargs->local.data0 = fargs->arg0; // stash arg0 for the after callback // fargs->arg0 = 42; // optionally override arg // fargs->skip_origin = 1; // optionally skip original; set fargs->ret too } // Called AFTER the target function; fargs->ret holds (and can override) the return value void after_add(hook_fargs2_t *fargs, void *udata) { pr_info("after add: original_arg0=%d ret=%d\n", (int)fargs->local.data0, (int)fargs->ret); // fargs->ret = 100; // override return value } static long my_init(const char *args, const char *event, void *reserved) { void *target = (void *)kallsyms_lookup_name("target_function_name"); if (!target) { pr_err("symbol not found\n"); return -1; } hook_err_t err = hook_wrap2(target, before_add, after_add, NULL); if (err != HOOK_NO_ERR) pr_err("hook_wrap2 failed: %d\n", err); return 0; } static long my_exit(void *reserved) { void *target = (void *)kallsyms_lookup_name("target_function_name"); hook_unwrap(target, before_add, after_add); // always unhook in exit return 0; } KPM_INIT(my_init); KPM_EXIT(my_exit); ``` -------------------------------- ### Get KPM Module Info Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/module.md Retrieve information about a specific Kernel Patching Module (KPM) using sc_kpm_info. Provide the key, module name, and a buffer for the info. ```c // Get module info char info[1024]; sc_kpm_info(key, "kpm-hello-demo", info, sizeof(info)); ``` -------------------------------- ### Control Kernel Patch Modules (KPMs) Source: https://context7.com/bmax121/kernelpatch/llms.txt Use the 'truncate' command to load, control, get info about, and unload Kernel Patch Modules (KPMs). Arguments like module name and init arguments are required. ```bash truncate module load /data/local/tmp/my.kpm "init_arg=1" ``` ```bash truncate module ctl0 my-kpm-name "ping" ``` ```bash truncate module info my-kpm-name ``` ```bash truncate module unload my-kpm-name ``` -------------------------------- ### SuperCall API: Detect KernelPatch Presence and Version Source: https://context7.com/bmax121/kernelpatch/llms.txt Checks if KernelPatch is installed and retrieves its version and build time using the SuperCall API. Requires a valid superkey for authentication. All operations are multiplexed through Linux syscall 45 (`__NR_supercall`). ```c #include #include #include "supercall.h" int main(void) { const char *key = "mysuperkey"; // Check whether KernelPatch is active if (!sc_ready(key)) { fprintf(stderr, "KernelPatch not installed\n"); return 1; } uint32_t kp_ver = sc_kp_ver(key); uint32_t k_ver = sc_k_ver(key); printf("KernelPatch: %d.%d.%d\n", (kp_ver >> 16) & 0xff, (kp_ver >> 8) & 0xff, kp_ver & 0xff); printf("Linux kernel: %d.%d.%d\n", (k_ver >> 16) & 0xff, (k_ver >> 8) & 0xff, k_ver & 0xff); char buildtime[64]; sc_kp_buildtime(key, buildtime, sizeof(buildtime)); printf("KP build time: %s\n", buildtime); return 0; } // Expected output: // KernelPatch: 0.13.1 // Linux kernel: 5.15.0 // KP build time: ``` -------------------------------- ### Super Command: Help Source: https://github.com/bmax121/kernelpatch/blob/main/doc/zh-CN/super-command.md Prints the complete usage instructions for the Super command. ```bash truncate help ``` -------------------------------- ### hook_unwrap Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/inline-hook.md Removes a previously installed hook created with `hook_wrap`. ```APIDOC ## hook_unwrap ### Description Removes a previously installed hook created with `hook_wrap`. ### Signature ```c void hook_unwrap(void *func, void *before, void *after); ``` ### Parameters #### Path Parameters - **func** (void *) - Address of the target kernel function - **before** (void *) - Pointer to the `before` callback function that was registered - **after** (void *) - Pointer to the `after` callback function that was registered ### Request Example ```c // Assuming target_func, before_callback, and after_callback were used in hook_wrap hook_unwrap(target_func, before_callback, after_callback); ``` ``` -------------------------------- ### KPM Control Operations Source: https://context7.com/bmax121/kernelpatch/llms.txt Commands to load, control, get information about, and unload Kernel Patch Modules (KPMs). ```APIDOC ## Load, control, and unload a KPM ### Description These commands manage Kernel Patch Modules (KPMs) within the kernel. ### Commands - `truncate module load [init_arg]` - `truncate module ctl0 ` - `truncate module info ` - `truncate module unload ` ``` -------------------------------- ### Build kpatch with CMake Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/build.md Build the kpatch component using CMake. Navigate to the user directory, create a build directory, and then run cmake and make. ```shell cd user mkdir build cd build cmake .. make ``` -------------------------------- ### Unhook Function Signature Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/inline-hook.md The `hook_unwrap` function removes a previously installed hook. It requires the same `func`, `before`, and `after` pointers used during `hook_wrap`. ```c void hook_unwrap(void *func, void *before, void *after); ``` -------------------------------- ### Build kptools with CMake Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/build.md Compile the kptools component using CMake. Navigate to the tools directory, create a build directory, and then run cmake and make. ```shell cd tools mkdir build cd build cmake .. make ``` -------------------------------- ### Create Static Library Source: https://github.com/bmax121/kernelpatch/blob/main/user_deprecated/CMakeLists.txt Creates a static library named 'kp' using the defined source files. ```cmake add_library(kp STATIC ${SRCS}) ``` -------------------------------- ### Register KPM Exit Callback Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/module.md Registers the exit function for a KPM, called when the module is unloaded. Ensure all installed hooks are unhooked here. ```c // Signature typedef long (*mod_exitcall_t)(void *reserved); KPM_EXIT(my_exit_function); ``` -------------------------------- ### Kernel Storage API Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/module.md Functions for interacting with kernel storage entries, allowing read, write, get, list, and remove operations. ```APIDOC ## Kernel Storage (``) ### Description Provides functions to manage persistent storage entries within the kernel. ### Functions - `write_kstorage(gid, did, data, offset, len, is_user)`: Write a storage entry. - `read_kstorage(gid, did, data, offset, len, is_user)`: Read a storage entry. - `get_kstorage(gid, did)`: Get a storage entry pointer (within RCU read lock). - `on_each_kstorage_elem(gid, cb, udata)`: Iterate entries in a group. - `list_kstorage_ids(gid, ids, idslen, is_user)`: List entry IDs in a group. - `remove_kstorage(gid, did)`: Remove a storage entry. ``` -------------------------------- ### Create Executable Source: https://github.com/bmax121/kernelpatch/blob/main/user_deprecated/CMakeLists.txt Creates an executable named 'kpatch' using the defined source files and 'main.c'. ```cmake add_executable(kpatch ${SRCS} main.c) ``` -------------------------------- ### Manage KernelPatch Keys Source: https://context7.com/bmax121/kernelpatch/llms.txt Manage security keys for KernelPatch using the 'truncate' command. Supports getting, setting, and enabling hashing for keys. ```bash truncate key get ``` ```bash truncate key set mynewsecretkey ``` ```bash truncate key hash enable ``` -------------------------------- ### Super Command: Boot Log Source: https://github.com/bmax121/kernelpatch/blob/main/doc/zh-CN/super-command.md Prints the boot log of KernelPatch. ```bash truncate bootlog ``` -------------------------------- ### Build a KernelPatch Module (KPM) Source: https://context7.com/bmax121/kernelpatch/llms.txt Build a KernelPatch Module (KPM) using a bare-metal cross-compiler. The output is a .kpm file. ```shell export TARGET_COMPILE=aarch64-none-elf- cd kpms/demo-hello make # output: demo-hello.kpm ``` -------------------------------- ### Build KernelPatch Module Demo Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/build.md Build a demo KernelPatch module. Set the TARGET_COMPILE environment variable and navigate to the module directory before running make. ```shell export TARGET_COMPILE=aarch64-none-elf- cd kpms/demo-hello make ``` -------------------------------- ### Build kptools (Host-Side Patcher) with Makefile Source: https://context7.com/bmax121/kernelpatch/llms.txt Build the host-side kernel image patcher 'kptools' using the Makefile. Set ANDROID=1 for Android support. ```shell # Makefile export ANDROID=1 cd tools && make ``` -------------------------------- ### Build kpimg with Makefile Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/build.md Build the kpimg component using the Makefile. Requires a bare-metal cross compiler. Set the TARGET_COMPILE and ANDROID environment variables as needed. ```shell export TARGET_COMPILE=aarch64-none-elf- cd kernel export ANDROID=1 # Android version, including support for the 'su' command make ``` -------------------------------- ### Build kptools (Host-Side Patcher) with CMake Source: https://context7.com/bmax121/kernelpatch/llms.txt Build the host-side kernel image patcher 'kptools' using CMake. This involves creating a build directory and running cmake and make. ```shell # CMake cd tools && mkdir build && cd build cmake .. && make # output: tools/kptools ``` -------------------------------- ### Getting Original Function Pointer in Callback Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/inline-hook.md Demonstrates how to retrieve the original function pointer within a callback using `fp_get_origin_func`. This is useful when the original function needs to be called from the hook. ```c void *orig = fp_get_origin_func(args); ``` -------------------------------- ### Build kpuser (Android Userspace Library) Source: https://context7.com/bmax121/kernelpatch/llms.txt Build the Android userspace library 'kpuser' using CMake and the Android NDK. Specify the NDK path, build type, platform, and ABI. ```shell export ANDROID_NDK=/path/to/ndk export ANDROID=1 cd user && mkdir -p build/android && cd build/android cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \ -DCMAKE_BUILD_TYPE=Release \ -DANDROID_PLATFORM=android-33 \ -DANDROID_ABI=arm64-v8a ../.. cmake --build . ``` -------------------------------- ### Define Source Files for Library and Executable Source: https://github.com/bmax121/kernelpatch/blob/main/user_deprecated/CMakeLists.txt Lists the source files for the main library and executable. ```cmake set(SRCS kpatch.c kpm.c su.c ) ``` -------------------------------- ### Build kpatch with Makefile Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/build.md Build the kpatch component using the Makefile. This component runs in user space. For Android, ensure the ANDROID environment variable is set. ```shell cd user make ``` -------------------------------- ### Super Command Basic Usage Source: https://github.com/bmax121/kernelpatch/blob/main/doc/zh-CN/super-command.md The basic syntax for the Super command. Use 'superkey' or 'su' as the first argument for authentication. If no command is specified, an interactive shell is launched. ```bash truncate [-u UID] [-Z SCONTEXT] [COMMAND [...]] ``` -------------------------------- ### Build kpimg (In-Kernel Payload) Source: https://context7.com/bmax121/kernelpatch/llms.txt Build the in-kernel payload 'kpimg' using a bare-metal cross-compiler. Set ANDROID=1 to include Android 'su' support. ```shell export TARGET_COMPILE=aarch64-none-elf- export ANDROID=1 # include Android 'su' support cd kernel make # output: kernel/kpimg ``` -------------------------------- ### Debug Operations Source: https://context7.com/bmax121/kernelpatch/llms.txt Command for retrieving boot logs. ```APIDOC ## Debug ### Description Retrieves the boot log for debugging purposes. ### Command - `truncate bootlog` ``` -------------------------------- ### Build kptools with Makefile Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/build.md Compile the kptools component using the Makefile. This component can run anywhere. Set the ANDROID environment variable if building for Android. ```shell export ANDROID=1 cd tools make ``` -------------------------------- ### Super Command: Build Time Source: https://github.com/bmax121/kernelpatch/blob/main/doc/zh-CN/super-command.md Prints the compilation timestamp of KernelPatch. ```bash truncate buildtime ``` -------------------------------- ### Basic Hook and Unhook Functions Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/inline-hook.md Provides the basic `hook` and `unhook` functions for simple replacement scenarios where only one module hooks a function. The `backup` parameter receives the original function pointer for potential invocation. ```c hook_err_t hook(void *func, void *replace, void **backup); void unhook(void *func); ``` -------------------------------- ### Super Command: SU Permission Management Source: https://github.com/bmax121/kernelpatch/blob/main/doc/zh-CN/super-command.md Manages SU permissions for UIDs. Subcommands include granting/revoking permissions, listing UIDs, and managing SU binary path and SELinux context. ```bash truncate sumgr <子命令> [...] ``` ```bash # 授予 UID 2000 root 权限,切换到 uid 0,使用默认 scontext truncate sumgr grant 2000 ``` ```bash # 授予 UID 2000,切换到 uid 0,使用自定义 scontext truncate sumgr grant 2000 0 u:r:su:s0 ``` ```bash # 撤销 truncate sumgr revoke 2000 ``` ```bash # 查看 UID 2000 的 profile truncate sumgr profile 2000 ``` ```bash # 修改 su 二进制路径 truncate sumgr path /data/local/tmp/mysu ``` ```bash # 设置全允许 SELinux 上下文 truncate sumgr sctx u:r:su:s0 ``` -------------------------------- ### Register KPM Initialization Callback Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/module.md Registers the initialization function for a KPM. This function is called when the module is loaded. Return 0 on success, non-zero on failure. ```c // Signature typedef long (*mod_initcall_t)(const char *args, const char *event, void *reserved); KPM_INIT(my_init_function); ``` -------------------------------- ### Super Command: Version Source: https://github.com/bmax121/kernelpatch/blob/main/doc/zh-CN/super-command.md Displays the kernel version and KernelPatch version in hexadecimal format. The output is comma-separated: ,. ```bash truncate version ``` -------------------------------- ### Include Directories Source: https://github.com/bmax121/kernelpatch/blob/main/user_deprecated/CMakeLists.txt Adds the binary directory to the include path. ```cmake include_directories(${CMAKE_CURRENT_BINARY_DIR}) ``` -------------------------------- ### Hook Chain Execution Flow Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/inline-hook.md Illustrates the execution order of `before` and `after` callbacks when multiple hooks are registered on the same function. `before` callbacks run in insertion order, and `after` callbacks run in reverse order. ```text before[0] → before[1] → ... → before[N-1] → original function (skipped if any before sets skip_origin = 1) → after[N-1] → ... → after[1] → after[0] ``` -------------------------------- ### Load a KPM Module Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/module.md Load a Kernel Patching Module (KPM) using the sc_kpm_load function. Provide a key, the module path, and initialization arguments. ```c #include "supercall.h" // Load a module sc_kpm_load(key, "/data/local/tmp/my.kpm", "init_args", NULL); ``` -------------------------------- ### Grant Root to Current Process (C) Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/super-syscall.md This function grants root privileges to the current process by utilizing the `sc_su` syscall. It requires a valid key and sets up a `su_profile` structure with the current UID and target UID set to 0. ```c #include "supercall.h" int grant_root(const char *key) { struct su_profile profile = { .uid = getuid(), .to_uid = 0, .scontext = "u:r:su:s0", }; return (int)sc_su(key, &profile); } ``` -------------------------------- ### Generic Compat Syscall Hook API (Auto-Select) Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/syscall-hook.md Generic API for 32-bit compatibility syscalls that automatically selects the best hooking method. ```c hook_err_t hook_compat_syscalln(int nr, int narg, void *before, void *after, void *udata); void unhook_compat_syscalln(int nr, void *before, void *after); ``` -------------------------------- ### sc_hello / sc_ready Source: https://context7.com/bmax121/kernelpatch/llms.txt Detect KernelPatch presence. SuperCall multiplexes all KernelPatch operations through Linux syscall 45 (`__NR_supercall`). Include `user/supercall.h` for all `sc_*` wrappers. Every call requires a **superkey** string for authentication. ```APIDOC ## SuperCall API (Userspace → Kernel) ### `sc_hello` / `sc_ready` — Detect KernelPatch presence SuperCall multiplexes all KernelPatch operations through Linux syscall 45 (`__NR_supercall`). Include `user/supercall.h` for all `sc_*` wrappers. Every call requires a **superkey** string for authentication. ### Usage ```c #include #include #include "supercall.h" int main(void) { const char *key = "mysuperkey"; // Check whether KernelPatch is active if (!sc_ready(key)) { fprintf(stderr, "KernelPatch not installed\n"); return 1; } uint32_t kp_ver = sc_kp_ver(key); uint32_t k_ver = sc_k_ver(key); printf("KernelPatch: %d.%d.%d\n", (kp_ver >> 16) & 0xff, (kp_ver >> 8) & 0xff, kp_ver & 0xff); printf("Linux kernel: %d.%d.%d\n", (k_ver >> 16) & 0xff, (k_ver >> 8) & 0xff, k_ver & 0xff); char buildtime[64]; sc_kp_buildtime(key, buildtime, sizeof(buildtime)); printf("KP build time: %s\n", buildtime); return 0; } // Expected output: // KernelPatch: 0.13.1 // Linux kernel: 5.15.0 // KP build time: ``` ``` -------------------------------- ### Super Command: Execute Program Source: https://github.com/bmax121/kernelpatch/blob/main/doc/zh-CN/super-command.md Directly executes a program specified by its full path, along with any arguments. ```bash truncate exec /data/local/tmp/my_program arg1 arg2 ``` -------------------------------- ### Register KPM Control Callback (ctl1) Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/module.md Registers an alternative control callback for internal kernel-to-module communication. ```c // Signature typedef long (*mod_ctl1call_t)(void *a1, void *a2, void *a3); KPM_CTL1(my_control1_function); ``` -------------------------------- ### Super Command: KPM Module Management Source: https://github.com/bmax121/kernelpatch/blob/main/doc/zh-CN/super-command.md Manages KernelPatch Modules (KPM). Requires superkey authentication. Supports loading, unloading, controlling, and listing modules. ```bash truncate module <子命令> [...] ``` ```bash truncate module load /data/local/tmp/my.kpm "init args" ``` ```bash truncate module ctl0 my-module "ping" ``` ```bash truncate module info my-module ``` ```bash truncate module unload my-module ``` ```bash truncate module list ``` -------------------------------- ### Register KPM Control Callback (ctl0) Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/module.md Registers the primary control callback for a KPM, invoked via sc_kpm_control(). Use compat_copy_to_user to write responses. ```c // Signature typedef long (*mod_ctl0call_t)(const char *ctl_args, char *__user out_msg, int outlen); KPM_CTL0(my_control0_function); ``` -------------------------------- ### Super Command: Event Reporting Source: https://github.com/bmax121/kernelpatch/blob/main/doc/zh-CN/super-command.md Reports user events to KernelPatch. Can include event data. ```bash truncate event [DATA] ``` -------------------------------- ### KPM Metadata and Lifecycle Macros Source: https://context7.com/bmax121/kernelpatch/llms.txt Declare KPM identity metadata and register init, control, and exit callbacks using macros from . The module name serves as its runtime identifier. ```c #include #include #include #include #include KPM_NAME("kpm-hello-demo"); // unique identifier, max 32 bytes KPM_VERSION("1.0.0"); KPM_LICENSE("GPL v2"); KPM_AUTHOR("bmax121"); KPM_DESCRIPTION("KernelPatch Module Example"); // max 512 bytes static long hello_init(const char *args, const char *event, void *reserved) { // args — string passed via sc_kpm_load() // event — "load" on manual load, or a kernel event string at boot pr_info("hello init, event: %s, args: %s\n", event, args); pr_info("kernelpatch version: %x\n", kpver); return 0; // non-zero = init failure } static long hello_control0(const char *ctl_args, char *__user out_msg, int outlen) { // Triggered by sc_kpm_control() from userspace char echo[64] = "echo: "; strncat(echo, ctl_args, 48); compat_copy_to_user(out_msg, echo, sizeof(echo)); return 0; } static long hello_exit(void *reserved) { pr_info("hello exit\n"); return 0; } KPM_INIT(hello_init); KPM_CTL0(hello_control0); KPM_EXIT(hello_exit); ``` -------------------------------- ### Syscall Argument Access Helpers Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/syscall-hook.md Provides utility functions to safely read and write syscall arguments, abstracting kernel differences. ```APIDOC ## Syscall Argument Access Helpers Because some kernels wrap syscalls with a `pt_regs` parameter, always use the provided helpers to access arguments instead of reading `fargs->argN` directly: ```c #include // Read argument n (0-based) uint64_t val = syscall_argn(args, n); // Write argument n set_syscall_argn(args, n, new_val); ``` ``` -------------------------------- ### Create Android Shared Library and Link Log Source: https://github.com/bmax121/kernelpatch/blob/main/user_deprecated/CMakeLists.txt Conditionally creates a shared library 'apjni' for Android, linking against the 'log' library. ```cmake if(ANDROID) add_library( apjni SHARED android/apjni.cpp ) find_library(lib-log log) target_link_libraries(apjni ${lib-log}) endif() ``` -------------------------------- ### Generic Syscall Hook API (Auto-Select Strategy) Source: https://github.com/bmax121/kernelpatch/blob/main/doc/en/syscall-hook.md Automatically selects the best hooking method (inline or function pointer) for the current kernel. ```APIDOC ## Generic Hook (Auto-Select Strategy) ```c hook_err_t hook_syscalln(int nr, int narg, void *before, void *after, void *udata); void unhook_syscalln(int nr, void *before, void *after); hook_err_t hook_compat_syscalln(int nr, int narg, void *before, void *after, void *udata); void unhook_compat_syscalln(int nr, void *before, void *after); ``` These automatically select the best hooking method for the current kernel. ```