kpm: 改进可读性 (#392)

* kpm: improving readability
Honestly, this format is really messy

Signed-off-by: Cloud_Yun <1770669041@qq.com>

* kpm: fix missing int label
my bad (((

Signed-off-by: Cloud_Yun <1770669041@qq.com>

---------

Signed-off-by: Cloud_Yun <1770669041@qq.com>
This commit is contained in:
Cloud_Yun
2025-09-14 18:43:54 +09:00
committed by ShirkNeko
parent cead5b03f4
commit 7d475e642f
7 changed files with 279 additions and 283 deletions

View File

@@ -3,4 +3,4 @@ obj-y += compact.o
obj-y += super_access.o obj-y += super_access.o
ccflags-y += -Wno-implicit-function-declaration -Wno-strict-prototypes -Wno-int-conversion -Wno-gcc-compat ccflags-y += -Wno-implicit-function-declaration -Wno-strict-prototypes -Wno-int-conversion -Wno-gcc-compat
ccflags-y += -Wno-declaration-after-statement -Wno-unused-function ccflags-y += -Wno-declaration-after-statement -Wno-unused-function

View File

@@ -13,7 +13,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/rcupdate.h> #include <linux/rcupdate.h>
#include <asm/elf.h> /* 包含 ARM64 重定位类型定义 */ #include <asm/elf.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/string.h> #include <linux/string.h>
@@ -29,55 +29,48 @@
#include "../allowlist.h" #include "../allowlist.h"
#include "../manager.h" #include "../manager.h"
unsigned long sukisu_compact_find_symbol(const char* name); static int sukisu_is_su_allow_uid(uid_t uid)
{
// ======================================================================
// 兼容函数 for KPM
static
int sukisu_is_su_allow_uid(uid_t uid) {
return ksu_is_allow_uid(uid) ? 1 : 0; return ksu_is_allow_uid(uid) ? 1 : 0;
} }
static static int sukisu_get_ap_mod_exclude(uid_t uid)
int sukisu_get_ap_mod_exclude(uid_t uid) { {
// Not supported return 0; /* Not supported */
return 0;
} }
static static int sukisu_is_uid_should_umount(uid_t uid)
int sukisu_is_uid_should_umount(uid_t uid) { {
return ksu_uid_should_umount(uid) ? 1 : 0; return ksu_uid_should_umount(uid) ? 1 : 0;
} }
static static int sukisu_is_current_uid_manager(void)
int sukisu_is_current_uid_manager() { {
return is_manager(); return is_manager();
} }
static static uid_t sukisu_get_manager_uid(void)
uid_t sukisu_get_manager_uid() { {
return ksu_manager_uid; return ksu_manager_uid;
} }
static static void sukisu_set_manager_uid(uid_t uid, int force)
void sukisu_set_manager_uid(uid_t uid, int force) { {
if(force || ksu_manager_uid == -1) { if (force || ksu_manager_uid == -1)
ksu_manager_uid = uid; ksu_manager_uid = uid;
}
} }
// ======================================================================
struct CompactAddressSymbol { struct CompactAddressSymbol {
const char* symbol_name; const char *symbol_name;
void* addr; void *addr;
}; };
static struct CompactAddressSymbol address_symbol [] = { unsigned long sukisu_compact_find_symbol(const char *name);
static struct CompactAddressSymbol address_symbol[] = {
{ "kallsyms_lookup_name", &kallsyms_lookup_name }, { "kallsyms_lookup_name", &kallsyms_lookup_name },
{ "compact_find_symbol", &sukisu_compact_find_symbol }, { "compact_find_symbol", &sukisu_compact_find_symbol },
{ "is_run_in_sukisu_ultra", (void*)1 }, { "is_run_in_sukisu_ultra", (void *)1 },
{ "is_su_allow_uid", &sukisu_is_su_allow_uid }, { "is_su_allow_uid", &sukisu_is_su_allow_uid },
{ "get_ap_mod_exclude", &sukisu_get_ap_mod_exclude }, { "get_ap_mod_exclude", &sukisu_get_ap_mod_exclude },
{ "is_uid_should_umount", &sukisu_is_uid_should_umount }, { "is_uid_should_umount", &sukisu_is_uid_should_umount },
@@ -86,25 +79,22 @@ static struct CompactAddressSymbol address_symbol [] = {
{ "sukisu_set_manager_uid", &sukisu_set_manager_uid } { "sukisu_set_manager_uid", &sukisu_set_manager_uid }
}; };
unsigned long sukisu_compact_find_symbol(const char* name) { unsigned long sukisu_compact_find_symbol(const char* name)
{
int i; int i;
unsigned long addr; unsigned long addr;
// 先自己在地址表部分查出来 for (i = 0; i < (sizeof(address_symbol) / sizeof(struct CompactAddressSymbol)); i++) {
for(i = 0; i < (sizeof(address_symbol) / sizeof(struct CompactAddressSymbol)); i++) { struct CompactAddressSymbol *symbol = &address_symbol[i];
struct CompactAddressSymbol* symbol = &address_symbol[i];
if(strcmp(name, symbol->symbol_name) == 0) { if (strcmp(name, symbol->symbol_name) == 0)
return (unsigned long) symbol->addr; return (unsigned long)symbol->addr;
}
} }
// 通过内核来查
addr = kallsyms_lookup_name(name); addr = kallsyms_lookup_name(name);
if(addr) { if (addr)
return addr; return addr;
}
return 0; return 0;
} }
EXPORT_SYMBOL(sukisu_compact_find_symbol); EXPORT_SYMBOL(sukisu_compact_find_symbol);

View File

@@ -1,6 +1,6 @@
#ifndef ___SUKISU_KPM_COMPACT_H #ifndef __SUKISU_KPM_COMPACT_H
#define ___SUKISU_KPM_COMPACT_H #define __SUKISU_KPM_COMPACT_H
unsigned long sukisu_compact_find_symbol(const char* name); extern unsigned long sukisu_compact_find_symbol(const char *name);
#endif #endif

View File

@@ -8,6 +8,7 @@
* 集成了 ELF 解析、内存布局、符号处理、重定位(支持 ARM64 重定位类型) * 集成了 ELF 解析、内存布局、符号处理、重定位(支持 ARM64 重定位类型)
* 并参照KernelPatch的标准KPM格式实现加载和控制 * 并参照KernelPatch的标准KPM格式实现加载和控制
*/ */
#include <linux/export.h> #include <linux/export.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
@@ -23,7 +24,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/rcupdate.h> #include <linux/rcupdate.h>
#include <asm/elf.h> /* 包含 ARM64 重定位类型定义 */ #include <asm/elf.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/string.h> #include <linux/string.h>
@@ -39,7 +40,7 @@
#include <linux/stacktrace.h> #include <linux/stacktrace.h>
#include <linux/kallsyms.h> #include <linux/kallsyms.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,0,0) && defined(CONFIG_MODULES) #if LINUX_VERSION_CODE >= KERNEL_VERSION(5,0,0) && defined(CONFIG_MODULES)
#include <linux/moduleloader.h> // 需要启用 CONFIG_MODULES #include <linux/moduleloader.h>
#endif #endif
#include "kpm.h" #include "kpm.h"
#include "compact.h" #include "compact.h"
@@ -54,131 +55,157 @@
#endif #endif
#endif #endif
// ============================================================================================ noinline NO_OPTIMIZE void sukisu_kpm_load_module_path(const char *path,
const char *args, void *ptr, void __user *result)
noinline {
NO_OPTIMIZE
void sukisu_kpm_load_module_path(const char* path, const char* args, void* ptr, void __user* result) {
// This is a KPM module stub.
int res = -1; int res = -1;
printk("KPM: Stub function called (sukisu_kpm_load_module_path). path=%s args=%s ptr=%p\n", path, args, ptr);
__asm__ volatile("nop"); // 精确控制循环不被优化
if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed.");
}
noinline printk("KPM: Stub function called (sukisu_kpm_load_module_path).
NO_OPTIMIZE path=%s args=%s ptr=%p\n", path, args, ptr);
void sukisu_kpm_unload_module(const char* name, void* ptr, void __user* result) {
// This is a KPM module stub.
int res = -1;
printk("KPM: Stub function called (sukisu_kpm_unload_module). name=%s ptr=%p\n", name, ptr);
__asm__ volatile("nop"); // 精确控制循环不被优化
if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed.");
}
noinline __asm__ volatile("nop");
NO_OPTIMIZE
void sukisu_kpm_num(void __user* result) {
// This is a KPM module stub.
int res = 0;
printk("KPM: Stub function called (sukisu_kpm_num).\n");
__asm__ volatile("nop"); // 精确控制循环不被优化
if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed.");
}
noinline if (copy_to_user(result, &res, sizeof(res)) < 1)
NO_OPTIMIZE printk("KPM: Copy to user failed.");
void sukisu_kpm_info(const char* name, void __user* out, void __user* result) {
// This is a KPM module stub.
int res = -1;
printk("KPM: Stub function called (sukisu_kpm_info). name=%s buffer=%p\n", name, out);
__asm__ volatile("nop"); // 精确控制循环不被优化
if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed.");
} }
noinline
NO_OPTIMIZE
void sukisu_kpm_list(void __user* out, unsigned int bufferSize, void __user* result) {
// This is a KPM module stub.
int res = -1;
printk("KPM: Stub function called (sukisu_kpm_list). buffer=%p size=%d\n", out, bufferSize);
if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed.");
}
noinline
NO_OPTIMIZE
void sukisu_kpm_control(void __user* name, void __user* args, void __user* result) {
// This is a KPM module stub.
int res = -1;
printk("KPM: Stub function called (sukisu_kpm_control). name=%p args=%p\n", name, args);
__asm__ volatile("nop"); // 精确控制循环不被优化
if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed.");
}
noinline
NO_OPTIMIZE
void sukisu_kpm_version(void __user* out, unsigned int bufferSize, void __user* result) {
int res = -1;
printk("KPM: Stub function called (sukisu_kpm_version). buffer=%p size=%d\n", out, bufferSize);
if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed.");
}
EXPORT_SYMBOL(sukisu_kpm_load_module_path); EXPORT_SYMBOL(sukisu_kpm_load_module_path);
noinline NO_OPTIMIZE void sukisu_kpm_unload_module(const char *name,
void *ptr, void __user *result)
{>
int res = -1;
printk("KPM: Stub function called (sukisu_kpm_unload_module).
name=%s ptr=%p\n", name, ptr);
__asm__ volatile("nop");
if (copy_to_user(result, &res, sizeof(res)) < 1)
printk("KPM: Copy to user failed.");
}
EXPORT_SYMBOL(sukisu_kpm_unload_module); EXPORT_SYMBOL(sukisu_kpm_unload_module);
noinline NO_OPTIMIZE void sukisu_kpm_num(void __user *result)
{
int res = 0;
printk("KPM: Stub function called (sukisu_kpm_num).\n");
__asm__ volatile("nop");
if (copy_to_user(result, &res, sizeof(res)) < 1)
printk("KPM: Copy to user failed.");
}
EXPORT_SYMBOL(sukisu_kpm_num); EXPORT_SYMBOL(sukisu_kpm_num);
noinline NO_OPTIMIZE void sukisu_kpm_info(const char *name, void __user *out,
void __user *result)
{
int res = -1;
printk("KPM: Stub function called (sukisu_kpm_info).
name=%s buffer=%p\n", name, out);
__asm__ volatile("nop");
if (copy_to_user(result, &res, sizeof(res)) < 1)
printk("KPM: Copy to user failed.");
}
EXPORT_SYMBOL(sukisu_kpm_info); EXPORT_SYMBOL(sukisu_kpm_info);
noinline NO_OPTIMIZE void sukisu_kpm_list(void __user *out, unsigned int bufferSize,
void __user *result)
{
int res = -1;
printk("KPM: Stub function called (sukisu_kpm_list).
buffer=%p size=%d\n", out, bufferSize);
if (copy_to_user(result, &res, sizeof(res)) < 1)
printk("KPM: Copy to user failed.");
}
EXPORT_SYMBOL(sukisu_kpm_list); EXPORT_SYMBOL(sukisu_kpm_list);
EXPORT_SYMBOL(sukisu_kpm_version);
noinline NO_OPTIMIZE void sukisu_kpm_control(void __user *name, void __user *args,
void __user *result)
{
int res = -1;
printk("KPM: Stub function called (sukisu_kpm_control).
name=%p args=%p\n", name, args);
__asm__ volatile("nop");
if (copy_to_user(result, &res, sizeof(res)) < 1)
printk("KPM: Copy to user failed.");
}
EXPORT_SYMBOL(sukisu_kpm_control); EXPORT_SYMBOL(sukisu_kpm_control);
noinline noinline NO_OPTIMIZE void sukisu_kpm_version(void __user *out, unsigned int bufferSize,
int sukisu_handle_kpm(unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) void __user *result)
{ {
if(arg2 == SUKISU_KPM_LOAD) { int res = -1;
printk("KPM: Stub function called (sukisu_kpm_version).
buffer=%p size=%d\n", out, bufferSize);
if (copy_to_user(result, &res, sizeof(res)) < 1)
printk("KPM: Copy to user failed.");
}
EXPORT_SYMBOL(sukisu_kpm_version);
noinline int sukisu_handle_kpm(unsigned long arg2, unsigned long arg3, unsigned long arg4,
unsigned long arg5)
{
if (arg2 == SUKISU_KPM_LOAD) {
char kernel_load_path[256] = { 0 }; char kernel_load_path[256] = { 0 };
char kernel_args_buffer[256] = { 0 }; char kernel_args_buffer[256] = { 0 };
if(arg3 == 0) { if (arg3 == 0)
return -1; return -1;
}
strncpy_from_user((char*)&kernel_load_path, (const char __user *)arg3, 255); strncpy_from_user((char *)&kernel_load_path, (const char __user *)arg3, 255);
if(arg4 != 0) {
strncpy_from_user((char*)&kernel_args_buffer, (const char __user *)arg4, 255); if (arg4 != 0)
} strncpy_from_user((char *)&kernel_args_buffer, (const char __user *)arg4, 255);
sukisu_kpm_load_module_path((const char*)&kernel_load_path, (const char*) &kernel_args_buffer, NULL, (void __user*) arg5);
} else if(arg2 == SUKISU_KPM_UNLOAD) { sukisu_kpm_load_module_path((const char *)&kernel_load_path,
(const char *)&kernel_args_buffer, NULL, (void __user *)arg5);
} else if (arg2 == SUKISU_KPM_UNLOAD) {
char kernel_name_buffer[256] = { 0 }; char kernel_name_buffer[256] = { 0 };
if(arg3 == 0) { if (arg3 == 0)
return -1; return -1;
}
strncpy_from_user((char*)&kernel_name_buffer, (const char __user *)arg3, 255); strncpy_from_user((char *)&kernel_name_buffer, (const char __user *)arg3, 255);
sukisu_kpm_unload_module((const char*) &kernel_name_buffer, NULL, (void __user*) arg5);
} else if(arg2 == SUKISU_KPM_NUM) { sukisu_kpm_unload_module((const char *)&kernel_name_buffer, NULL,
sukisu_kpm_num((void __user*) arg5); (void __user *)arg5);
} else if(arg2 == SUKISU_KPM_INFO) { } else if (arg2 == SUKISU_KPM_NUM) {
sukisu_kpm_num((void __user *)arg5);
} else if (arg2 == SUKISU_KPM_INFO) {
char kernel_name_buffer[256] = { 0 }; char kernel_name_buffer[256] = { 0 };
if(arg3 == 0 || arg4 == 0) { if (arg3 == 0 || arg4 == 0)
return -1; return -1;
}
strncpy_from_user((char*)&kernel_name_buffer, (const char __user *)arg3, 255); strncpy_from_user((char *)&kernel_name_buffer, (const char __user *)arg3, 255);
sukisu_kpm_info((const char*) &kernel_name_buffer, (char __user*) arg4, (void __user*) arg5);
} else if(arg2 == SUKISU_KPM_LIST) { sukisu_kpm_info((const char *)&kernel_name_buffer, (char __user *)arg4,
sukisu_kpm_list((char __user*) arg3, (unsigned int) arg4, (void __user*) arg5); (void __user *)arg5);
} else if(arg2 == SUKISU_KPM_VERSION) { } else if (arg2 == SUKISU_KPM_LIST) {
sukisu_kpm_version((char __user*) arg3, (unsigned int) arg4, (void __user*) arg5); sukisu_kpm_list((char __user *)arg3, (unsigned int)arg4, (void __user *)arg5);
} else if(arg2 == SUKISU_KPM_CONTROL) { } else if (arg2 == SUKISU_KPM_CONTROL) {
sukisu_kpm_control((char __user*) arg3, (char __user*) arg4, (void __user*) arg5); sukisu_kpm_control((char __user *)arg3, (char __user *)arg4, (void __user *)arg5);
} else if (arg2 == SUKISU_KPM_VERSION) {
sukisu_kpm_version((char __user *)arg3, (unsigned int)arg4, (void __user *)arg5);
} }
return 0; return 0;
} }
EXPORT_SYMBOL(sukisu_handle_kpm);
int sukisu_is_kpm_control_code(unsigned long arg2) { int sukisu_is_kpm_control_code(unsigned long arg2) {
return (arg2 >= CMD_KPM_CONTROL && arg2 <= CMD_KPM_CONTROL_MAX) ? 1 : 0; return (arg2 >= CMD_KPM_CONTROL &&
arg2 <= CMD_KPM_CONTROL_MAX) ? 1 : 0;
} }
EXPORT_SYMBOL(sukisu_handle_kpm);

View File

@@ -1,44 +1,58 @@
#ifndef ___SUKISU_KPM_H #ifndef __SUKISU_KPM_H
#define ___SUKISU_KPM_H #define __SUKISU_KPM_H
int sukisu_handle_kpm(unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5); extern int sukisu_handle_kpm(unsigned long arg2, unsigned long arg3, unsigned long arg4,
int sukisu_is_kpm_control_code(unsigned long arg2); unsigned long arg5);
extern int sukisu_is_kpm_control_code(unsigned long arg2);
// KPM控制代码 /* KPM Control Code */
#define CMD_KPM_CONTROL 28 #define CMD_KPM_CONTROL 28
#define CMD_KPM_CONTROL_MAX 35 #define CMD_KPM_CONTROL_MAX 35
// 控制代码 /* Control Code */
/*
// prctl(xxx, 28, "PATH", "ARGS") * prctl(xxx, 28, "PATH", "ARGS")
// success return 0, error return -N * success return 0, error return -N
*/
#define SUKISU_KPM_LOAD 28 #define SUKISU_KPM_LOAD 28
// prctl(xxx, 29, "NAME") /*
// success return 0, error return -N * prctl(xxx, 29, "NAME")
* success return 0, error return -N
*/
#define SUKISU_KPM_UNLOAD 29 #define SUKISU_KPM_UNLOAD 29
// num = prctl(xxx, 30) /*
// error return -N * num = prctl(xxx, 30)
// success return +num or 0 * error return -N
* success return +num or 0
*/
#define SUKISU_KPM_NUM 30 #define SUKISU_KPM_NUM 30
// prctl(xxx, 31, Buffer, BufferSize) /*
// success return +out, error return -N * prctl(xxx, 31, Buffer, BufferSize)
* success return +out, error return -N
*/
#define SUKISU_KPM_LIST 31 #define SUKISU_KPM_LIST 31
// prctl(xxx, 32, "NAME", Buffer[256]) /*
// success return +out, error return -N * prctl(xxx, 32, "NAME", Buffer[256])
* success return +out, error return -N
*/
#define SUKISU_KPM_INFO 32 #define SUKISU_KPM_INFO 32
// prctl(xxx, 33, "NAME", "ARGS") /*
// success return KPM's result value * prctl(xxx, 33, "NAME", "ARGS")
// error return -N * success return KPM's result value
* error return -N
*/
#define SUKISU_KPM_CONTROL 33 #define SUKISU_KPM_CONTROL 33
// prctl(xxx, 34, buffer, bufferSize) /*
// success return KPM's result value * prctl(xxx, 34, buffer, bufferSize)
// error return -N * success return KPM's result value
* error return -N
*/
#define SUKISU_KPM_VERSION 34 #define SUKISU_KPM_VERSION 34
#endif #endif

View File

@@ -13,7 +13,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/rcupdate.h> #include <linux/rcupdate.h>
#include <asm/elf.h> /* 包含 ARM64 重定位类型定义 */ #include <asm/elf.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/string.h> #include <linux/string.h>
@@ -24,34 +24,37 @@
#include <linux/version.h> #include <linux/version.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "kpm.h"
#include "compact.h"
#include <linux/types.h> #include <linux/types.h>
#include <linux/stddef.h> #include <linux/stddef.h>
#include <linux/mount.h>
#include <linux/kprobes.h>
#include <linux/mm_types.h>
#include <linux/netlink.h>
#include <linux/sched.h>
#include <../fs/mount.h>
#include "kpm.h"
#include "compact.h"
// 结构体成员元数据
struct DynamicStructMember { struct DynamicStructMember {
const char* name; const char *name;
size_t size; size_t size;
size_t offset; size_t offset;
}; };
// 结构体元数据(包含总大小)
struct DynamicStructInfo { struct DynamicStructInfo {
const char* name; const char *name;
size_t count; size_t count;
size_t total_size; size_t total_size;
struct DynamicStructMember* members; struct DynamicStructMember *members;
}; };
// 定义结构体元数据的宏(直接使用 struct 名称)
#define DYNAMIC_STRUCT_BEGIN(struct_name) \ #define DYNAMIC_STRUCT_BEGIN(struct_name) \
static struct DynamicStructMember struct_name##_members[] = { static struct DynamicStructMember struct_name##_members[] = {
#define DEFINE_MEMBER(struct_name, member) \ #define DEFINE_MEMBER(struct_name, member) \
{ \ { \
.name = #member, \ .name = #member, \
.size = sizeof(((struct struct_name*)0)->member), \ .size = sizeof(((struct struct_name *)0)->member), \
.offset = offsetof(struct struct_name, member) \ .offset = offsetof(struct struct_name, member) \
}, },
@@ -64,17 +67,6 @@ struct DynamicStructInfo {
.members = struct_name##_members \ .members = struct_name##_members \
}; };
// ==================================================================================
#include <linux/version.h>
#define KERNEL_VERSION_6_1 KERNEL_VERSION(6, 1, 0)
#define KERNEL_VERSION_5_15 KERNEL_VERSION(5, 15, 0)
#include <../fs/mount.h>
#include <linux/mount.h>
// 定义元数据
DYNAMIC_STRUCT_BEGIN(mount) DYNAMIC_STRUCT_BEGIN(mount)
DEFINE_MEMBER(mount, mnt_parent) DEFINE_MEMBER(mount, mnt_parent)
DEFINE_MEMBER(mount, mnt) DEFINE_MEMBER(mount, mnt)
@@ -96,13 +88,11 @@ DYNAMIC_STRUCT_BEGIN(mnt_namespace)
DEFINE_MEMBER(mnt_namespace, root) DEFINE_MEMBER(mnt_namespace, root)
DEFINE_MEMBER(mnt_namespace, seq) DEFINE_MEMBER(mnt_namespace, seq)
DEFINE_MEMBER(mnt_namespace, mounts) DEFINE_MEMBER(mnt_namespace, mounts)
#if LINUX_VERSION_CODE < KERNEL_VERSION_5_15 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)
DEFINE_MEMBER(mnt_namespace, count) DEFINE_MEMBER(mnt_namespace, count)
#endif #endif
DYNAMIC_STRUCT_END(mnt_namespace) DYNAMIC_STRUCT_END(mnt_namespace)
#include <linux/kprobes.h>
#ifdef CONFIG_KPROBES #ifdef CONFIG_KPROBES
DYNAMIC_STRUCT_BEGIN(kprobe) DYNAMIC_STRUCT_BEGIN(kprobe)
DEFINE_MEMBER(kprobe, addr) DEFINE_MEMBER(kprobe, addr)
@@ -110,16 +100,13 @@ DYNAMIC_STRUCT_BEGIN(kprobe)
DEFINE_MEMBER(kprobe, offset) DEFINE_MEMBER(kprobe, offset)
DEFINE_MEMBER(kprobe, pre_handler) DEFINE_MEMBER(kprobe, pre_handler)
DEFINE_MEMBER(kprobe, post_handler) DEFINE_MEMBER(kprobe, post_handler)
#if LINUX_VERSION_CODE < KERNEL_VERSION_5_15 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)
DEFINE_MEMBER(kprobe, fault_handler) DEFINE_MEMBER(kprobe, fault_handler)
#endif #endif
DEFINE_MEMBER(kprobe, flags) DEFINE_MEMBER(kprobe, flags)
DYNAMIC_STRUCT_END(kprobe) DYNAMIC_STRUCT_END(kprobe)
#endif #endif
#include <linux/mm.h>
#include <linux/mm_types.h>
DYNAMIC_STRUCT_BEGIN(vm_area_struct) DYNAMIC_STRUCT_BEGIN(vm_area_struct)
DEFINE_MEMBER(vm_area_struct,vm_start) DEFINE_MEMBER(vm_area_struct,vm_start)
DEFINE_MEMBER(vm_area_struct,vm_end) DEFINE_MEMBER(vm_area_struct,vm_end)
@@ -128,9 +115,9 @@ DYNAMIC_STRUCT_BEGIN(vm_area_struct)
DEFINE_MEMBER(vm_area_struct,vm_pgoff) DEFINE_MEMBER(vm_area_struct,vm_pgoff)
DEFINE_MEMBER(vm_area_struct,vm_file) DEFINE_MEMBER(vm_area_struct,vm_file)
DEFINE_MEMBER(vm_area_struct,vm_private_data) DEFINE_MEMBER(vm_area_struct,vm_private_data)
#ifdef CONFIG_ANON_VMA_NAME #ifdef CONFIG_ANON_VMA_NAME
DEFINE_MEMBER(vm_area_struct, anon_name) DEFINE_MEMBER(vm_area_struct, anon_name)
#endif #endif
DEFINE_MEMBER(vm_area_struct, vm_ops) DEFINE_MEMBER(vm_area_struct, vm_ops)
DYNAMIC_STRUCT_END(vm_area_struct) DYNAMIC_STRUCT_END(vm_area_struct)
@@ -141,8 +128,6 @@ DYNAMIC_STRUCT_BEGIN(vm_operations_struct)
DEFINE_MEMBER(vm_operations_struct, access) DEFINE_MEMBER(vm_operations_struct, access)
DYNAMIC_STRUCT_END(vm_operations_struct) DYNAMIC_STRUCT_END(vm_operations_struct)
#include <linux/netlink.h>
DYNAMIC_STRUCT_BEGIN(netlink_kernel_cfg) DYNAMIC_STRUCT_BEGIN(netlink_kernel_cfg)
DEFINE_MEMBER(netlink_kernel_cfg, groups) DEFINE_MEMBER(netlink_kernel_cfg, groups)
DEFINE_MEMBER(netlink_kernel_cfg, flags) DEFINE_MEMBER(netlink_kernel_cfg, flags)
@@ -150,13 +135,11 @@ DYNAMIC_STRUCT_BEGIN(netlink_kernel_cfg)
DEFINE_MEMBER(netlink_kernel_cfg, cb_mutex) DEFINE_MEMBER(netlink_kernel_cfg, cb_mutex)
DEFINE_MEMBER(netlink_kernel_cfg, bind) DEFINE_MEMBER(netlink_kernel_cfg, bind)
DEFINE_MEMBER(netlink_kernel_cfg, unbind) DEFINE_MEMBER(netlink_kernel_cfg, unbind)
#if LINUX_VERSION_CODE < KERNEL_VERSION_6_1 #if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)
DEFINE_MEMBER(netlink_kernel_cfg, compare) DEFINE_MEMBER(netlink_kernel_cfg, compare)
#endif #endif
DYNAMIC_STRUCT_END(netlink_kernel_cfg) DYNAMIC_STRUCT_END(netlink_kernel_cfg)
#include <linux/sched.h>
DYNAMIC_STRUCT_BEGIN(task_struct) DYNAMIC_STRUCT_BEGIN(task_struct)
DEFINE_MEMBER(task_struct, pid) DEFINE_MEMBER(task_struct, pid)
DEFINE_MEMBER(task_struct, tgid) DEFINE_MEMBER(task_struct, tgid)
@@ -186,104 +169,110 @@ DYNAMIC_STRUCT_BEGIN(task_struct)
DEFINE_MEMBER(task_struct, thread) DEFINE_MEMBER(task_struct, thread)
DYNAMIC_STRUCT_END(task_struct) DYNAMIC_STRUCT_END(task_struct)
// =====================================================================================================================
#define STRUCT_INFO(name) &(name##_info) #define STRUCT_INFO(name) &(name##_info)
static static struct DynamicStructInfo *dynamic_struct_infos[] = {
struct DynamicStructInfo* dynamic_struct_infos[] = {
STRUCT_INFO(mount), STRUCT_INFO(mount),
STRUCT_INFO(vfsmount), STRUCT_INFO(vfsmount),
STRUCT_INFO(mnt_namespace), STRUCT_INFO(mnt_namespace),
#ifdef CONFIG_KPROBES #ifdef CONFIG_KPROBES
STRUCT_INFO(kprobe), STRUCT_INFO(kprobe),
#endif #endif
STRUCT_INFO(vm_area_struct), STRUCT_INFO(vm_area_struct),
STRUCT_INFO(vm_operations_struct), STRUCT_INFO(vm_operations_struct),
STRUCT_INFO(netlink_kernel_cfg), STRUCT_INFO(netlink_kernel_cfg),
STRUCT_INFO(task_struct) STRUCT_INFO(task_struct)
}; };
// return 0 if successful /*
// return -1 if struct not defined * return 0 if successful
int sukisu_super_find_struct( * return -1 if struct not defined
const char* struct_name, */
size_t* out_size, int sukisu_super_find_struct(const char *struct_name, size_t *out_size, int *out_members)
int* out_members {
) { for (size_t i = 0; i < (sizeof(dynamic_struct_infos) / sizeof(dynamic_struct_infos[0])); i++) {
for(size_t i = 0; i < (sizeof(dynamic_struct_infos) / sizeof(dynamic_struct_infos[0])); i++) { struct DynamicStructInfo *info = dynamic_struct_infos[i];
struct DynamicStructInfo* info = dynamic_struct_infos[i];
if(strcmp(struct_name, info->name) == 0) { if (strcmp(struct_name, info->name) == 0) {
if(out_size) if (out_size)
*out_size = info->total_size; *out_size = info->total_size;
if(out_members)
if (out_members)
*out_members = info->count; *out_members = info->count;
return 0; return 0;
} }
} }
return -1; return -1;
} }
EXPORT_SYMBOL(sukisu_super_find_struct); EXPORT_SYMBOL(sukisu_super_find_struct);
// Dynamic access struct /*
// return 0 if successful * Dynamic access struct
// return -1 if struct not defined * return 0 if successful
// return -2 if member not defined * return -1 if struct not defined
int sukisu_super_access ( * return -2 if member not defined
const char* struct_name, */
const char* member_name, int sukisu_super_access(const char *struct_name, const char *member_name, size_t *out_offset,
size_t* out_offset, size_t *out_size)
size_t* out_size {
) { for (size_t i = 0; i < (sizeof(dynamic_struct_infos) / sizeof(dynamic_struct_infos[0])); i++) {
for(size_t i = 0; i < (sizeof(dynamic_struct_infos) / sizeof(dynamic_struct_infos[0])); i++) { struct DynamicStructInfo *info = dynamic_struct_infos[i];
struct DynamicStructInfo* info = dynamic_struct_infos[i];
if(strcmp(struct_name, info->name) == 0) { if (strcmp(struct_name, info->name) == 0) {
for (size_t i1 = 0; i1 < info->count; i1++) { for (size_t i1 = 0; i1 < info->count; i1++) {
if (strcmp(info->members[i1].name, member_name) == 0) { if (strcmp(info->members[i1].name, member_name) == 0) {
if(out_offset) if (out_offset)
*out_offset = info->members[i].offset; *out_offset = info->members[i].offset;
if(out_size)
if (out_size)
*out_size = info->members[i].size; *out_size = info->members[i].size;
return 0; return 0;
} }
} }
return -2; return -2;
} }
} }
return -1; return -1;
} }
EXPORT_SYMBOL(sukisu_super_access); EXPORT_SYMBOL(sukisu_super_access);
// 动态 container_of 宏
#define DYNAMIC_CONTAINER_OF(offset, member_ptr) ({ \ #define DYNAMIC_CONTAINER_OF(offset, member_ptr) ({ \
(offset != (size_t)-1) ? (void*)((char*)(member_ptr) - offset) : NULL; \ (offset != (size_t)-1) ? (void*)((char*)(member_ptr) - offset) : NULL; \
}) })
// Dynamic container_of /*
// return 0 if success * Dynamic container_of
// return -1 if current struct not defined * return 0 if success
// return -2 if target member not defined * return -1 if current struct not defined
int sukisu_super_container_of( * return -2 if target member not defined
const char* struct_name, */
const char* member_name, int sukisu_super_container_of(const char *struct_name, const char *member_name, void *ptr,
void* ptr, void **out_ptr)
void** out_ptr {
) { if (ptr == NULL)
if(ptr == NULL) {
return -3; return -3;
}
for(size_t i = 0; i < (sizeof(dynamic_struct_infos) / sizeof(dynamic_struct_infos[0])); i++) { for (size_t i = 0; i < (sizeof(dynamic_struct_infos) / sizeof(dynamic_struct_infos[0])); i++) {
struct DynamicStructInfo* info = dynamic_struct_infos[i]; struct DynamicStructInfo *info = dynamic_struct_infos[i];
if(strcmp(struct_name, info->name) == 0) {
if (strcmp(struct_name, info->name) == 0) {
for (size_t i1 = 0; i1 < info->count; i1++) { for (size_t i1 = 0; i1 < info->count; i1++) {
if (strcmp(info->members[i1].name, member_name) == 0) { if (strcmp(info->members[i1].name, member_name) == 0) {
*out_ptr = (void*) DYNAMIC_CONTAINER_OF(info->members[i1].offset, ptr); *out_ptr = (void *)DYNAMIC_CONTAINER_OF(info->members[i1].offset, ptr);
return 0; return 0;
} }
} }
return -2; return -2;
} }
} }
return -1; return -1;
} }
EXPORT_SYMBOL(sukisu_super_container_of); EXPORT_SYMBOL(sukisu_super_container_of);

View File

@@ -6,34 +6,10 @@
#include "kpm.h" #include "kpm.h"
#include "compact.h" #include "compact.h"
// return 0 if successful extern int sukisu_super_find_struct(const char *struct_name, size_t *out_size, int *out_members);
// return -1 if struct not defined extern int sukisu_super_access(const char *struct_name, const char *member_name, size_t *out_offset,
int sukisu_super_find_struct( size_t *out_size);
const char* struct_name, extern int sukisu_super_container_of(const char *struct_name, const char *member_name, void *ptr,
size_t* out_size, void **out_ptr);
int* out_members
);
// Dynamic access struct
// return 0 if successful
// return -1 if struct not defined
// return -2 if member not defined
int sukisu_super_access (
const char* struct_name,
const char* member_name,
size_t* out_offset,
size_t* out_size
);
// Dynamic container_of
// return 0 if success
// return -1 if current struct not defined
// return -2 if target member not defined
int sukisu_super_container_of(
const char* struct_name,
const char* member_name,
void* ptr,
void** out_ptr
);
#endif #endif