diff --git a/kernel/kpm/super_access.c b/kernel/kpm/super_access.c index e69de29b..166c3388 100644 --- a/kernel/kpm/super_access.c +++ b/kernel/kpm/super_access.c @@ -0,0 +1,249 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* 包含 ARM64 重定位类型定义 */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "kpm.h" +#include "compact.h" +#include // 需要包含 offsetof 宏 + +// 结构体成员元数据 +struct DynamicStructMember { + const char* name; + size_t size; + size_t offset; +}; + +// 结构体元数据(包含总大小) +struct DynamicStructInfo { + const char* name; + size_t count; + size_t total_size; + struct DynamicStructMember* members; +}; + +// 定义结构体元数据的宏(直接使用 struct 名称) +#define DYNAMIC_STRUCT_BEGIN(struct_name) \ + static struct DynamicStructMember struct_name##_members[] = { + +#define DEFINE_MEMBER(struct_name, member) \ + { \ + .name = #member, \ + .size = sizeof(((struct struct_name*)0)->member), \ + .offset = offsetof(struct struct_name, member) \ + }, + +#define DYNAMIC_STRUCT_END(struct_name) \ + }; \ + static struct DynamicStructInfo struct_name##_info = { \ + .name = #struct_name, \ + .count = sizeof(struct_name##_members) / sizeof(struct DynamicStructMember), \ + .total_size = sizeof(struct struct_name), \ + .members = struct_name##_members \ + }; + +// ================================================================================== + +#include +#include + +// 定义元数据 +DYNAMIC_STRUCT_BEGIN(mount) + DEFINE_MEMBER(mount, mnt_parent) + DEFINE_MEMBER(mount, mnt) + DEFINE_MEMBER(mount, mnt_id) + DEFINE_MEMBER(mount, mnt_group_id) + DEFINE_MEMBER(mount, mnt_expiry_mark) + DEFINE_MEMBER(mount, mnt_master) + DEFINE_MEMBER(mount, mnt_devname) +DYNAMIC_STRUCT_END(mount) + +DYNAMIC_STRUCT_BEGIN(vfsmount) + DEFINE_MEMBER(vfsmount, mnt_root) + DEFINE_MEMBER(vfsmount, mnt_sb) + DEFINE_MEMBER(vfsmount, mnt_flags) +DYNAMIC_STRUCT_END(vfsmount) + +DYNAMIC_STRUCT_BEGIN(mnt_namespace) + DEFINE_MEMBER(mnt_namespace, count) + DEFINE_MEMBER(mnt_namespace, ns) + DEFINE_MEMBER(mnt_namespace, root) + DEFINE_MEMBER(mnt_namespace, seq) + DEFINE_MEMBER(mnt_namespace, mounts) +DYNAMIC_STRUCT_END(mnt_namespace) + +#include + +#ifdef CONFIG_KPROBES + +DYNAMIC_STRUCT_BEGIN(kprobe) + DEFINE_MEMBER(kprobe, addr) + DEFINE_MEMBER(kprobe, symbol_name) + DEFINE_MEMBER(kprobe, offset) + DEFINE_MEMBER(kprobe, pre_handler) + DEFINE_MEMBER(kprobe, post_handler) + DEFINE_MEMBER(kprobe, fault_handler) + DEFINE_MEMBER(kprobe, break_handler) + DEFINE_MEMBER(kprobe, flags) +DYNAMIC_STRUCT_END(kprobe) + +#endif + +#include +#include + +DYNAMIC_STRUCT_BEGIN(vm_area_struct) + DEFINE_MEMBER(vm_area_struct,vm_start) + DEFINE_MEMBER(vm_area_struct,vm_end) + DEFINE_MEMBER(vm_area_struct,vm_flags) + DEFINE_MEMBER(vm_area_struct,anon_vma) + DEFINE_MEMBER(vm_area_struct,vm_pgoff) + DEFINE_MEMBER(vm_area_struct,vm_file) + DEFINE_MEMBER(vm_area_struct,vm_private_data) + #ifdef CONFIG_ANON_VMA_NAME + DEFINE_MEMBER(vm_area_struct, anon_name) + #endif + DEFINE_MEMBER(vm_area_struct, vm_ops) +DYNAMIC_STRUCT_END(vm_area_struct) + +DYNAMIC_STRUCT_BEGIN(vm_operations_struct) + DEFINE_MEMBER(vm_operations_struct, open) + DEFINE_MEMBER(vm_operations_struct, close) + DEFINE_MEMBER(vm_operations_struct, name) + DEFINE_MEMBER(vm_operations_struct, access) +DYNAMIC_STRUCT_END(vm_operations_struct) + +#include + +DYNAMIC_STRUCT_BEGIN(netlink_kernel_cfg) + DEFINE_MEMBER(netlink_kernel_cfg, groups) + DEFINE_MEMBER(netlink_kernel_cfg, flags) + DEFINE_MEMBER(netlink_kernel_cfg, input) + DEFINE_MEMBER(netlink_kernel_cfg, cb_mutex) + DEFINE_MEMBER(netlink_kernel_cfg, bind) + DEFINE_MEMBER(netlink_kernel_cfg, unbind) + DEFINE_MEMBER(netlink_kernel_cfg, compare) +DYNAMIC_STRUCT_END(netlink_kernel_cfg) + +// ===================================================================================================================== + +#define STRUCT_INFO(name) &(name##_info) + +static +struct DynamicStructInfo* dynamic_struct_infos[] = { + STRUCT_INFO(mount), + STRUCT_INFO(vfsmount), + STRUCT_INFO(mnt_namespace), + #ifdef CONFIG_KPROBES + STRUCT_INFO(kprobe) + #endif + STRUCT_INFO(vm_area_struct), + STRUCT_INFO(vm_operations_struct), + STRUCT_INFO(netlink_kernel_cfg) +}; + +// return 0 if successful +// return -1 if struct not defined +int sukisu_super_find_struct( + const char* struct_name, + size_t* out_size, + int* out_members +) { + for(size_t i = 0; i < (sizeof(dynamic_struct_infos) / sizeof(dynamic_struct_infos[0])); i++) { + struct DynamicStructInfo* info = dynamic_struct_infos[i]; + if(strcmp(struct_name, info->name) == 0) { + if(out_size) + *out_size = info->total_size; + if(out_members) + *out_members = info->count; + return 0; + } + } + return -1; +} +EXPORT_SYMBOL(sukisu_super_find_struct); + +// 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 +) { + for(size_t i = 0; i < (sizeof(dynamic_struct_infos) / sizeof(dynamic_struct_infos[0])); i++) { + struct DynamicStructInfo* info = dynamic_struct_infos[i]; + if(strcmp(struct_name, info->name) == 0) { + for (size_t i1 = 0; i1 < info->count; i1++) { + if (strcmp(info->members[i1].name, member_name) == 0) { + if(out_offset) + *out_offset = info->members[i].offset; + if(out_size) + *out_size = info->members[i].size; + return 0; + } + } + return -2; + } + } + return -1; +} +EXPORT_SYMBOL(sukisu_super_access); + +// 动态 container_of 宏 +#define DYNAMIC_CONTAINER_OF(offset, member_ptr) ({ \ + (offset != (size_t)-1) ? (void*)((char*)(member_ptr) - offset) : NULL; \ +}) + +// 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 +) { + if(ptr == NULL) { + return -3; + } + for(size_t i = 0; i < (sizeof(dynamic_struct_infos) / sizeof(dynamic_struct_infos[0])); i++) { + struct DynamicStructInfo* info = dynamic_struct_infos[i]; + if(strcmp(struct_name, info->name) == 0) { + for (size_t i1 = 0; i1 < info->count; i1++) { + if (strcmp(info->members[i1].name, member_name) == 0) { + *out_ptr = (void*) DYNAMIC_CONTAINER_OF(info->members[i1].offset, ptr); + return 0; + } + } + return -2; + } + } + return -1; +} +EXPORT_SYMBOL(sukisu_super_container_of); +