diff --git a/README.md b/README.md index 14b76ea..86bb660 100644 --- a/README.md +++ b/README.md @@ -1,86 +1,2 @@ -**Read this in other languages: [English](README.md), [中文](README_zh.md).** -# Automated Kernel Driver Builder - -This GitHub Action automates the process of building Android kernel drivers in the cloud, eliminating the need for local compilation environments. It solves common issues like accessing Google's source repositories and reduces compilation time to under 30min. - -## Key Features - -- ✅ **Cloud-based compilation** - No local setup required -- ✅ **Automatic source handling** - Fetches official Android kernel sources -- ✅ **Version-aware building** - Automatically selects correct build system -- ✅ **Parameterized inputs** - Customize builds via workflow inputs -- ✅ **Artifact packaging** - Downloads compiled drivers and kernel images - -## Usage Guide - -### 1. Repository Setup -1. Create a `code` directory in your repository -2. Place these files in the `code` directory: - - Driver source files (`.c` and `.h`) - - `Makefile` for your driver - - Any additional dependencies - -### 2. Running the Workflow -1. Go to your GitHub repository's **Actions** tab -2. Select **Android Kernel Driver Builder** -3. Click **Run workflow** -4. Provide these parameters: - - `android_version`: Your Android version (Kernel) (e.g., `14`) - - `kernel_version`: Kernel version (e.g., `6.1`) - - `driver_name`: Your driver filename (e.g., `mydriver.ko`) - - `target_arch`: Device architecture (default: `aarch64`) - -### 3. Retrieving Results -After successful compilation (30minutes): -1. Go to the completed workflow run -2. Download the `kernel-driver-` artifact -3. Extract to find: - - Compiled driver (`.ko` file) - - Kernel images (`boot.img`) - - Build logs - -## Configuration Reference - -### Input Parameters - -| Parameter | Description | Example | -|-----------|-------------|---------| -| `android_version` | Android OS version | `11`, `12`, `13`, `14` | -| `kernel_version` | Linux kernel version | `5.10`, `5.15`, `6.1` | -| `driver_name` | Output driver filename | `custom_driver.ko` | -| `target_arch` | Device CPU architecture | `aarch64`, `x86_64` | - -### Technical Notes - -1. **Build System Selection**: - - Android 11 and earlier: Legacy `build.sh` system - - Android 12 and later: Modern Bazel build system - -2. **Source Management**: - - Automatically fetches kernel sources from Google's repositories - - Uses parallel downloading for faster sync - -3. **Driver Integration**: - - Automatically adds driver to kernel build system - - Registers driver as GKI module - - Handles Makefile modifications - -## Troubleshooting - -**Q: Build fails with "repo sync" errors** -A: Retry the workflow. Google's servers can occasionally timeout. - -**Q: Driver not found in output artifacts** -A: Verify: -- Correct `driver_name` parameter (must match Makefile) -- Source files are in `/code` directory -- Makefile produces expected `.ko` filename - -**Q: "Kernel configuration not found" error** -A: Confirm your kernel_version matches existing branches at [Android Kernel Sources](https://android.googlesource.com/kernel/manifest/) - -## Support - -For issues and feature requests: -- [Open an Issue](https://github.com/systemnb/compile_android_driver/issues) -- Provide workflow logs and input parameters +陈依涵的内核驱动项目,采用systemnb的Action编译。 +由于本人还是初学者,所以会不定期学习新内容并更新 diff --git a/README_zh.md b/README_zh.md deleted file mode 100644 index 70cadf9..0000000 --- a/README_zh.md +++ /dev/null @@ -1,85 +0,0 @@ -**其他语言版本: [English](README.md), [中文](README_zh.md).** -# 自动化内核驱动构建工具 -本 GitHub Action 可在云端自动化编译 Android 内核驱动程序,无需本地编译环境。解决访问 Google 源码仓库等问题,编译时间控制在 30min内。 - -## 核心功能 - -- ✅ **云端编译** - 无需本地环境配置 -- ✅ **自动源码管理** - 从官方仓库获取 Android 内核源码 -- ✅ **版本感知构建** - 自动选择正确的构建系统 -- ✅ **参数化输入** - 通过工作流参数自定义构建 -- ✅ **结果打包** - 下载编译好的驱动和内核镜像 - -## 使用指南 - -### 1. 仓库设置 -1. 在仓库中创建 `code` 目录 -2. 将以下文件放入 `code` 目录: - - 驱动源文件 (`.c` 和 `.h`) - - 驱动的 `Makefile` - - 其他依赖文件 - -### 2. 运行工作流 -1. 转到 GitHub 仓库的 **Actions** 标签页 -2. 选择 **Android Kernel Driver Builder** -3. 点击 **Run workflow** -4. 提供以下参数: - - `android_version`: Android 版本(内核) (例如 `14`) - - `kernel_version`: 内核版本 (例如 `6.1`) - - `driver_name`: 驱动文件名 (例如 `mydriver.ko`) - - `target_arch`: 设备架构 (默认 `aarch64`) - -### 3. 获取结果 -编译成功后 (30 分钟): -1. 转到完成的工作流运行 -2. 下载 `kernel-driver-<架构>` 产物 -3. 解压后包含: - - 编译好的驱动 (`.ko` 文件) - - 内核镜像 (`boot.img`) - - 构建日志 - -## 配置参考 - -### 输入参数 - -| 参数 | 说明 | 示例 | -|------|------|------| -| `android_version` | Android 系统版本 | `11`, `12`, `13`, `14` | -| `kernel_version` | Linux 内核版本 | `5.10`, `5.15`, `6.1` | -| `driver_name` | 驱动文件名 | `custom_driver.ko` | -| `target_arch` | 设备 CPU 架构 | `aarch64`, `x86_64` | - -### 技术说明 - -1. **构建系统选择**: - - Android 11 及更早版本:使用传统 `build.sh` 系统 - - Android 12 及更新版本:使用现代 Bazel 构建系统 - -2. **源码管理**: - - 自动从 Google 仓库获取内核源码 - - 使用并行下载加速同步过程 - -3. **驱动集成**: - - 自动将驱动添加到内核构建系统 - - 注册驱动为 GKI 模块 - - 自动处理 Makefile 修改 - -## 故障排除 - -**Q: "repo sync" 步骤失败** -A: 重新运行工作流,Google 服务器偶尔会出现超时 - -**Q: 输出产物中找不到驱动文件** -A: 检查: -- `driver_name` 参数是否正确(需与 Makefile 匹配) -- 源文件是否在 `/code` 目录 -- Makefile 是否生成预期的 `.ko` 文件 - -**Q: 出现 "Kernel configuration not found" 错误** -A: 确认内核版本在 [Android 内核源码](https://android.googlesource.com/kernel/manifest/) 中存在对应分支 - -## 支持 - -问题反馈和功能请求: -- [提交 Issue](https://github.com/systemnb/compile_android_driver/issues) -- 请提供工作流日志和输入参数 diff --git a/code/Makefile b/code/Makefile index 1ed512a..308dfcf 100644 --- a/code/Makefile +++ b/code/Makefile @@ -1 +1 @@ -obj-m += rwProcMem_module.o +obj-m += arm64_hw_bp.o \ No newline at end of file diff --git a/code/api_proxy.h b/code/api_proxy.h deleted file mode 100644 index 083a53d..0000000 --- a/code/api_proxy.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef API_PROXY_H_ -#define API_PROXY_H_ -#include "ver_control.h" -#include "linux_kernel_api.h" -#include -#include -#include -#include - -//声明 -////////////////////////////////////////////////////////////////////////// -static inline int x_atoi(const char arr[]); -static inline bool x_isdigit(char c); -static inline struct task_struct* x_get_current(void); -static inline void * x_kmalloc(size_t size, gfp_t flags); -static inline unsigned long x_copy_from_user(void *to, const void __user *from, unsigned long n); -static inline unsigned long x_copy_to_user(void __user *to, const void *from, unsigned long n); - -//实现 -////////////////////////////////////////////////////////////////////////// -static inline bool x_isdigit(char c) { return (unsigned)(c - '0') < 10; } -static inline int x_atoi(const char arr[]) { - int index = 0; - int flag = 1; - int num = 0; - - if (arr == NULL) { return -1; } - while (isspace(arr[index])) { index++; } - if (arr[index] == '-') { flag = -1; } - if (arr[index] == '-' || arr[index] == '+') { index++; } - while (arr[index] >= '0' && arr[index] <= '9') { num = num * 10 + arr[index] - '0'; index++; } - return flag * num; -} - -static struct task_struct *x_get_current(void) { - unsigned long sp_el0; - asm ("mrs %0, sp_el0" : "=r" (sp_el0)); - return (struct task_struct *)sp_el0; -} - -static void * x_kmalloc(size_t size, gfp_t flags) { - return __kmalloc(size, flags); -} - -static unsigned long x_copy_from_user(void *to, const void __user *from, unsigned long n) { - return __arch_copy_from_user(to, from, n); -} - -static unsigned long x_copy_to_user(void __user *to, const void *from, unsigned long n) { - return __arch_copy_to_user(to, from, n); -} -#endif /* API_PROXY_H_ */ - - diff --git a/code/arm64_hw_bp.c b/code/arm64_hw_bp.c new file mode 100644 index 0000000..dce1569 --- /dev/null +++ b/code/arm64_hw_bp.c @@ -0,0 +1,905 @@ +/* + * 硬件断点正确绑定到线程(task_struct)而非进程ID + * 适配Linux 5.10+内核 + */ + +#include "arm64_hw_bp.h" + +// 断点数据结构 - 修复:存储task_struct而非pid +typedef struct _HW_BREAKPOINT_INFO { + pid_t tid; // 线程ID + pid_t tgid; // 线程组ID(进程ID) + uintptr_t addr; + uint32_t type; // 断点类型 + bool active; + struct perf_event *pe; // perf事件 +} HW_BREAKPOINT_INFO, *PHW_BREAKPOINT_INFO; + +typedef struct _BREAKPOINT_OPERATION { + pid_t tid; // 线程ID + uintptr_t addr; + uint32_t type; +} BREAKPOINT_OPERATION, *PBREAKPOINT_OPERATION; + +typedef struct _COPY_MEMORY { + pid_t pid; // 进程ID + uintptr_t addr; + void __user *buffer; + size_t size; +} COPY_MEMORY, *PCOPY_MEMORY; + +typedef struct _MODULE_BASE { + pid_t pid; + char __user *name; + uintptr_t base; +} MODULE_BASE, *PMODULE_BASE; + +// 新增:最近命中断点的信息结构 +typedef struct _LAST_HIT_INFO { + pid_t tid; // 最近命中断点的线程ID + pid_t tgid; // 线程组ID + uintptr_t addr; // 断点地址 + uint64_t timestamp; // 时间戳(纳秒) + uint32_t count; // 命中次数 + struct user_pt_regs regs; +} LAST_HIT_INFO, *PLAST_HIT_INFO; + +// IOCTL操作码 +enum HW_BREAKPOINT_OPERATIONS { + OP_INIT_KEY = 0x600, + OP_READ_MEM = 0x601, + OP_WRITE_MEM = 0x602, + OP_MODULE_BASE = 0x603, + OP_SET_BREAKPOINT = 0x604, + OP_CLEAR_BREAKPOINT = 0x605, + OP_LIST_BREAKPOINTS = 0x606, + OP_CLEAR_ALL_BREAKPOINTS = 0x607, + OP_GET_LAST_HIT_TID = 0x608, // 新增:获取最近命中的线程ID + OP_GET_LAST_HIT_INFO = 0x609, // 新增:获取最近命中的详细信息 + OP_RESUME_THREAD = 0x60A, // 恢复被暂停的线程 +}; + +// 内部断点结构 +struct hw_breakpoint_entry { + HW_BREAKPOINT_INFO info; + struct task_struct *task; // 指向线程的task_struct + struct list_head list; +}; + +// 全局变量 +static DEFINE_MUTEX(bp_mutex); +static LIST_HEAD(bp_list); +static int bp_count = 0; +static LAST_HIT_INFO g_LastHitInfo = {0}; // 新增:最近命中的断点信息 +#define MAX_BREAKPOINTS 16 + +// 函数声明 +static phys_addr_t translate_linear_address(struct mm_struct *mm, uintptr_t va); +static bool read_physical_address(phys_addr_t pa, void __user *buffer, size_t size); +static bool write_physical_address(phys_addr_t pa, const void __user *buffer, size_t size); +static bool read_process_memory(pid_t pid, uintptr_t addr, void __user *buffer, size_t size); +static bool write_process_memory(pid_t pid, uintptr_t addr, const void __user *buffer, size_t size); +static uintptr_t get_module_base(pid_t pid, const char *name); +static void hw_breakpoint_handler(struct perf_event *bp, struct perf_sample_data *data, struct pt_regs *regs); +static int set_hw_breakpoint(pid_t tid, uintptr_t addr, uint32_t type); +static int clear_hw_breakpoint(pid_t tid, uintptr_t addr); +static void clear_all_breakpoints(void); +static struct task_struct *get_thread_by_tid(pid_t tid); +static int resume_thread(pid_t tid); + +// 根据线程ID获取task_struct +static struct task_struct *get_thread_by_tid(pid_t tid) +{ + struct task_struct *task = NULL; + struct pid *pid_struct = NULL; + + pid_struct = find_get_pid(tid); + if (!pid_struct) + return NULL; + + task = get_pid_task(pid_struct, PIDTYPE_PID); + put_pid(pid_struct); + + return task; +} + +// 物理地址翻译函数 +static phys_addr_t translate_linear_address(struct mm_struct *mm, uintptr_t va) +{ + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + pud_t *pud; + phys_addr_t page_addr; + uintptr_t page_offset; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) + p4d_t *p4d; + + pgd = pgd_offset(mm, va); + if (pgd_none(*pgd) || pgd_bad(*pgd)) + return 0; + + p4d = p4d_offset(pgd, va); + if (p4d_none(*p4d) || p4d_bad(*p4d)) + return 0; + + pud = pud_offset(p4d, va); +#else + pgd = pgd_offset(mm, va); + if (pgd_none(*pgd) || pgd_bad(*pgd)) + return 0; + + pud = pud_offset(pgd, va); +#endif + + if (pud_none(*pud) || pud_bad(*pud)) + return 0; + + pmd = pmd_offset(pud, va); + if (pmd_none(*pmd)) + return 0; + + pte = pte_offset_kernel(pmd, va); + if (pte_none(*pte) || !pte_present(*pte)) + return 0; + + page_addr = (phys_addr_t)(pte_pfn(*pte) << PAGE_SHIFT); + page_offset = va & (PAGE_SIZE - 1); + + return page_addr + page_offset; +} + +// 检查物理地址范围 +static inline bool is_valid_phys_addr_range(phys_addr_t addr, size_t size) +{ + return (addr + size <= virt_to_phys(high_memory)); +} + +// 读取物理地址 +static bool read_physical_address(phys_addr_t pa, void __user *buffer, size_t size) +{ + void *mapped; + + if (!pfn_valid(__phys_to_pfn(pa))) + return false; + + if (!is_valid_phys_addr_range(pa, size)) + return false; + + mapped = ioremap_cache(pa, size); + if (!mapped) + return false; + + if (copy_to_user(buffer, mapped, size)) { + iounmap(mapped); + return false; + } + + iounmap(mapped); + return true; +} + +// 写入物理地址 +static bool write_physical_address(phys_addr_t pa, const void __user *buffer, size_t size) +{ + void *mapped; + + if (!pfn_valid(__phys_to_pfn(pa))) + return false; + + if (!is_valid_phys_addr_range(pa, size)) + return false; + + mapped = ioremap_cache(pa, size); + if (!mapped) + return false; + + if (copy_from_user(mapped, buffer, size)) { + iounmap(mapped); + return false; + } + + iounmap(mapped); + return true; +} + +// 读取进程内存 +static bool read_process_memory(pid_t pid, uintptr_t addr, + void __user *buffer, size_t size) +{ + struct task_struct *task = NULL; + struct mm_struct *mm = NULL; + struct pid *pid_struct = NULL; + phys_addr_t pa; + bool result = false; + struct vm_area_struct *vma; + + pid_struct = find_get_pid(pid); + if (!pid_struct) + return false; + + task = get_pid_task(pid_struct, PIDTYPE_PID); + if (!task) { + put_pid(pid_struct); + return false; + } + + mm = get_task_mm(task); + put_pid(pid_struct); + + if (!mm) { + put_task_struct(task); + return false; + } + + // Linux 5.10使用mmap_lock而不是mmap_sem +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0) + mmap_read_lock(mm); +#else + down_read(&mm->mmap_sem); +#endif + + pa = translate_linear_address(mm, addr); + + if (pa) { + result = read_physical_address(pa, buffer, size); + } else { + vma = find_vma(mm, addr); + if (vma) { + if (clear_user(buffer, size) == 0) { + result = true; + } + } + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0) + mmap_read_unlock(mm); +#else + up_read(&mm->mmap_sem); +#endif + + mmput(mm); + put_task_struct(task); + return result; +} + +// 写入进程内存 +static bool write_process_memory(pid_t pid, uintptr_t addr, + const void __user *buffer, size_t size) +{ + struct task_struct *task = NULL; + struct mm_struct *mm = NULL; + struct pid *pid_struct = NULL; + phys_addr_t pa; + bool result = false; + + pid_struct = find_get_pid(pid); + if (!pid_struct) + return false; + + task = get_pid_task(pid_struct, PIDTYPE_PID); + if (!task) { + put_pid(pid_struct); + return false; + } + + mm = get_task_mm(task); + put_pid(pid_struct); + + if (!mm) { + put_task_struct(task); + return false; + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0) + mmap_read_lock(mm); +#else + down_read(&mm->mmap_sem); +#endif + + pa = translate_linear_address(mm, addr); + + if (pa) { + result = write_physical_address(pa, buffer, size); + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0) + mmap_read_unlock(mm); +#else + up_read(&mm->mmap_sem); +#endif + + mmput(mm); + put_task_struct(task); + return result; +} + +// 获取模块基址 +#define ARC_PATH_MAX 256 +static uintptr_t get_module_base(pid_t pid, const char *name) +{ + struct task_struct *task = NULL; + struct mm_struct *mm = NULL; + struct pid *pid_struct = NULL; + struct vm_area_struct *vma = NULL; + uintptr_t base_addr = 0; + int path_len; + char buf[ARC_PATH_MAX]; + char *path_nm; + + pid_struct = find_get_pid(pid); + if (!pid_struct) + return 0; + + task = get_pid_task(pid_struct, PIDTYPE_PID); + if (!task) { + put_pid(pid_struct); + return 0; + } + + mm = get_task_mm(task); + put_pid(pid_struct); + + if (!mm) { + put_task_struct(task); + return 0; + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0) + mmap_read_lock(mm); +#else + down_read(&mm->mmap_sem); +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) + struct vma_iterator vmi; + vma_iter_init(&vmi, mm, 0); + for_each_vma(vmi, vma) { +#else + for (vma = mm->mmap; vma; vma = vma->vm_next) { +#endif + if (!vma->vm_file) + continue; + + path_nm = file_path(vma->vm_file, buf, ARC_PATH_MAX - 1); + if (IS_ERR(path_nm)) + continue; + + path_len = strlen(path_nm); + if (path_len <= 0) + continue; + + if (strstr(path_nm, name) != NULL) { + base_addr = vma->vm_start; + break; + } + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0) + mmap_read_unlock(mm); +#else + up_read(&mm->mmap_sem); +#endif + + mmput(mm); + put_task_struct(task); + return base_addr; +} + +//断点回调 +static void hw_breakpoint_handler(struct perf_event *bp, + struct perf_sample_data *data, + struct pt_regs *regs) +{ + struct hw_breakpoint_entry *entry = bp->overflow_handler_context; + struct task_struct *task = current; + + if (!entry) { + printk(KERN_ERR "No breakpoint context found\n"); + return; + } + + if (task->pid != entry->info.tid) { + printk(KERN_WARNING "[HW_BP] Breakpoint triggered by unexpected thread: %d\n", task->pid); + return; + } + + // 更新最近命中信息 + mutex_lock(&bp_mutex); + g_LastHitInfo.tid = task->pid; + g_LastHitInfo.tgid = task->tgid; + g_LastHitInfo.addr = entry->info.addr; + g_LastHitInfo.timestamp = ktime_get_real_ns(); + g_LastHitInfo.count++; + memcpy(&g_LastHitInfo.regs, regs, sizeof(g_LastHitInfo.regs)); + mutex_unlock(&bp_mutex); + + printk(KERN_INFO "[HW_BP] Breakpoint hit by thread %d, sending SIGSTOP...\n", task->pid); + + // 暂停当前线程 + send_sig_info(SIGSTOP, SEND_SIG_PRIV, task); +} + +// 设置硬件断点 - 修复版本:作用在线程上 +static int set_hw_breakpoint(pid_t tid, uintptr_t addr, uint32_t type) +{ + struct task_struct *task = NULL; + struct perf_event_attr attr; + struct hw_breakpoint_entry *entry; + struct hw_breakpoint_entry *tmp; + int bp_len; + int ret = 0; + + // 检查断点数量限制 + mutex_lock(&bp_mutex); + if (bp_count >= MAX_BREAKPOINTS) { + mutex_unlock(&bp_mutex); + printk(KERN_ERR "Maximum breakpoints reached (%d)\n", MAX_BREAKPOINTS); + return -ENOSPC; + } + mutex_unlock(&bp_mutex); + + // 根据线程ID获取task_struct + task = get_thread_by_tid(tid); + if (!task) { + printk(KERN_ERR "Thread %d not found\n", tid); + return -ESRCH; + } + + mutex_lock(&bp_mutex); + + // 检查是否已存在断点 + list_for_each_entry(tmp, &bp_list, list) { + if (tmp->info.tid == tid && tmp->info.addr == addr) { + printk(KERN_INFO "Breakpoint already exists at 0x%lx for thread %d\n", + (unsigned long)addr, tid); + ret = -EEXIST; + goto out_unlock; + } + } + + // 分配断点条目 + entry = kmalloc(sizeof(struct hw_breakpoint_entry), GFP_KERNEL); + if (!entry) { + ret = -ENOMEM; + goto out_unlock; + } + + // 初始化断点信息 + memset(entry, 0, sizeof(struct hw_breakpoint_entry)); + + // 设置perf事件属性 + memset(&attr, 0, sizeof(struct perf_event_attr)); + attr.type = PERF_TYPE_BREAKPOINT; + attr.size = sizeof(struct perf_event_attr); + + // 设置断点类型和大小 + bp_len = 4; // 默认4字节 + + switch (type) { + case BP_TYPE_INST: + attr.bp_type = HW_BREAKPOINT_X; + bp_len = 4; + break; + case BP_TYPE_READ: + attr.bp_type = HW_BREAKPOINT_R; + bp_len = 8; + break; + case BP_TYPE_WRITE: + attr.bp_type = HW_BREAKPOINT_W; + bp_len = 8; + break; + case BP_TYPE_RW: + attr.bp_type = HW_BREAKPOINT_RW; + bp_len = 8; + break; + default: + kfree(entry); + ret = -EINVAL; + goto out_unlock; + } + + attr.bp_addr = addr; + attr.bp_len = bp_len; + attr.sample_period = 1; + attr.sample_type = PERF_SAMPLE_IP; + attr.wakeup_events = 1; + attr.exclude_kernel = 1; + attr.exclude_hv = 1; + + // 创建perf事件 - 关键:传递给具体的task_struct(线程) + entry->info.pe = perf_event_create_kernel_counter(&attr, -1, task, + hw_breakpoint_handler, entry); + + if (IS_ERR(entry->info.pe)) { + ret = PTR_ERR(entry->info.pe); + printk(KERN_ERR "Failed to create hardware breakpoint: %d\n", ret); + kfree(entry); + goto out_unlock; + } + + // 初始化断点信息 + entry->info.tid = tid; + entry->info.tgid = task->tgid; + entry->info.addr = addr; + entry->info.type = type; + entry->info.active = true; + entry->task = get_task_struct(task); // 增加引用计数 + INIT_LIST_HEAD(&entry->list); + + // 添加到链表 + list_add_tail(&entry->list, &bp_list); + bp_count++; + + // 启用断点 + perf_event_enable(entry->info.pe); + + printk(KERN_INFO "Hardware breakpoint set at 0x%lx for thread %d (TGID %d, type: %u)\n", + (unsigned long)addr, tid, task->tgid, type); + + ret = 0; + +out_unlock: + mutex_unlock(&bp_mutex); + if (task) + put_task_struct(task); + return ret; +} + +// 清除硬件断点 +static int clear_hw_breakpoint(pid_t tid, uintptr_t addr) +{ + struct hw_breakpoint_entry *entry, *tmp; + int ret = -ENOENT; + + mutex_lock(&bp_mutex); + + list_for_each_entry_safe(entry, tmp, &bp_list, list) { + if (entry->info.tid == tid && entry->info.addr == addr) { + // 禁用并释放perf事件 + if (entry->info.pe) { + perf_event_disable(entry->info.pe); + perf_event_release_kernel(entry->info.pe); + } + + // 释放task引用 + if (entry->task) { + put_task_struct(entry->task); + } + + // 从链表删除 + list_del(&entry->list); + kfree(entry); + bp_count--; + + printk(KERN_INFO "Hardware breakpoint cleared at 0x%lx for thread %d\n", + (unsigned long)addr, tid); + ret = 0; + break; + } + } + + mutex_unlock(&bp_mutex); + return ret; +} + +// 清除所有断点 +static void clear_all_breakpoints(void) +{ + struct hw_breakpoint_entry *entry, *tmp; + + mutex_lock(&bp_mutex); + + list_for_each_entry_safe(entry, tmp, &bp_list, list) { + if (entry->info.pe) { + perf_event_disable(entry->info.pe); + perf_event_release_kernel(entry->info.pe); + } + + // 释放task引用 + if (entry->task) { + put_task_struct(entry->task); + } + + list_del(&entry->list); + kfree(entry); + } + + bp_count = 0; + mutex_unlock(&bp_mutex); + + printk(KERN_INFO "All hardware breakpoints cleared\n"); +} + +static int resume_thread(pid_t tid) +{ + struct task_struct *task; + int ret = 0; + + task = get_thread_by_tid(tid); + if (!task) { + printk(KERN_ERR "Thread %d not found\n", tid); + return -ESRCH; + } + + printk(KERN_INFO "Resuming thread %d\n", tid); + send_sig_info(SIGCONT, SEND_SIG_PRIV, task); + + put_task_struct(task); + return ret; +} + +// IOCTL分发函数 +static int dispatch_open(struct inode *node, struct file *file) +{ + return 0; +} + +static int dispatch_close(struct inode *node, struct file *file) +{ + return 0; +} + +static long dispatch_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + static char key[256] = {0}; + static bool is_verified = false; + long ret = 0; + + switch (cmd) { + case OP_INIT_KEY: + if (!is_verified) { + if (copy_from_user(key, (void __user *)arg, sizeof(key) - 1) == 0) { + key[sizeof(key) - 1] = '\0'; + is_verified = true; + printk(KERN_INFO "Key initialized successfully\n"); + } else { + return -EFAULT; + } + } + break; + + case OP_READ_MEM: { + COPY_MEMORY cm; + + if (copy_from_user(&cm, (void __user *)arg, sizeof(cm))) + return -EFAULT; + + if (!read_process_memory(cm.pid, cm.addr, cm.buffer, cm.size)) + return -EIO; + + break; + } + + case OP_WRITE_MEM: { + COPY_MEMORY cm; + + if (copy_from_user(&cm, (void __user *)arg, sizeof(cm))) + return -EFAULT; + + if (!write_process_memory(cm.pid, cm.addr, cm.buffer, cm.size)) + return -EIO; + + break; + } + + case OP_MODULE_BASE: { + MODULE_BASE mb; + char module_name[256]; + + if (copy_from_user(&mb, (void __user *)arg, sizeof(mb))) + return -EFAULT; + + if (!mb.name) + return -EFAULT; + + if (copy_from_user(module_name, mb.name, sizeof(module_name) - 1)) + return -EFAULT; + module_name[sizeof(module_name) - 1] = '\0'; + + mb.base = get_module_base(mb.pid, module_name); + + if (copy_to_user((void __user *)arg, &mb, sizeof(mb))) + return -EFAULT; + + break; + } + + case OP_SET_BREAKPOINT: { + BREAKPOINT_OPERATION bp_op; + + if (copy_from_user(&bp_op, (void __user *)arg, sizeof(bp_op))) + return -EFAULT; + + ret = set_hw_breakpoint(bp_op.tid, bp_op.addr, bp_op.type); + if (ret < 0) + return ret; + + break; + } + + case OP_CLEAR_BREAKPOINT: { + BREAKPOINT_OPERATION bp_op; + + if (copy_from_user(&bp_op, (void __user *)arg, sizeof(bp_op))) + return -EFAULT; + + ret = clear_hw_breakpoint(bp_op.tid, bp_op.addr); + if (ret < 0) + return ret; + + break; + } + + case OP_LIST_BREAKPOINTS: { + struct hw_breakpoint_entry *entry; + HW_BREAKPOINT_INFO info; + int idx = 0; + + mutex_lock(&bp_mutex); + + list_for_each_entry(entry, &bp_list, list) { + // 复制信息到用户空间 + memset(&info, 0, sizeof(info)); + info.tid = entry->info.tid; + info.tgid = entry->info.tgid; + info.addr = entry->info.addr; + info.type = entry->info.type; + info.active = entry->info.active; + + if (copy_to_user((void __user *)(arg + idx * sizeof(info)), + &info, sizeof(info))) { + mutex_unlock(&bp_mutex); + return -EFAULT; + } + idx++; + } + + mutex_unlock(&bp_mutex); + break; + } + + case OP_CLEAR_ALL_BREAKPOINTS: { + clear_all_breakpoints(); + break; + } + + case OP_GET_LAST_HIT_TID: { + pid_t last_hit_tid; + + mutex_lock(&bp_mutex); + last_hit_tid = g_LastHitInfo.tid; + mutex_unlock(&bp_mutex); + + if (copy_to_user((void __user *)arg, &last_hit_tid, sizeof(last_hit_tid))) + return -EFAULT; + + break; + } + + case OP_GET_LAST_HIT_INFO: { + LAST_HIT_INFO last_hit_info; + + mutex_lock(&bp_mutex); + last_hit_info = g_LastHitInfo; + mutex_unlock(&bp_mutex); + + if (copy_to_user((void __user *)arg, &last_hit_info, sizeof(last_hit_info))) + return -EFAULT; + + break; + } + + case OP_RESUME_THREAD: { + pid_t tid; + + if (copy_from_user(&tid, (void __user *)arg, sizeof(tid))) + return -EFAULT; + + ret = resume_thread(tid); + if (ret < 0) + return ret; + + break; + } + + default: + return -ENOTTY; + } + + return ret; +} + +// 文件操作结构 +static const struct file_operations dispatch_fops = { + .owner = THIS_MODULE, + .open = dispatch_open, + .release = dispatch_close, + .unlocked_ioctl = dispatch_ioctl, + .compat_ioctl = dispatch_ioctl, +}; + +// misc设备定义 +static struct miscdevice misc_dev = { + .minor = MISC_DYNAMIC_MINOR, + .name = DEVICE_NAME, + .fops = &dispatch_fops, + .mode = 0666, +}; + +// 模块初始化 +static int __init driver_entry(void) +{ + int ret; + int breakpoint_slots = 0; + + printk(KERN_INFO "ARM64 Hardware Breakpoint Module (Hook PC Version) loading...\n"); + +#ifndef CONFIG_ARM64 + printk(KERN_ERR "This module is for ARM64 architecture only!\n"); + return -ENODEV; +#endif + + // 检查是否支持硬件断点 +#ifdef CONFIG_HAVE_HW_BREAKPOINT + printk(KERN_INFO "Hardware breakpoint support detected\n"); + + // 尝试通过配置推断断点槽数量 +#if defined(CONFIG_ARM64_HW_BREAKPOINT) + // 如果定义了ARM64_HW_BREAKPOINT,通常支持更多断点 + breakpoint_slots = 16; +#else + // 保守估计 + breakpoint_slots = 4; +#endif + + printk(KERN_INFO "Estimated hardware breakpoint slots: %d\n", breakpoint_slots); +#else + printk(KERN_ERR "Hardware breakpoints not supported on this CPU\n"); + return -ENODEV; +#endif + + // 初始化列表和全局变量 + INIT_LIST_HEAD(&bp_list); + + // 初始化最近命中信息 + memset(&g_LastHitInfo, 0, sizeof(g_LastHitInfo)); + + ret = misc_register(&misc_dev); + if (ret) { + printk(KERN_ERR "Failed to register misc device: %d\n", ret); + return ret; + } + + printk(KERN_INFO "ARM64 Hardware Breakpoint Module loaded. Device: /dev/%s\n", DEVICE_NAME); + printk(KERN_INFO "Maximum hardware breakpoints: %d\n", MAX_BREAKPOINTS); + printk(KERN_INFO "Hook PC feature: Modify PC register to jump to hook address on breakpoint hit\n"); + printk(KERN_INFO "Last hit tracking: Record TID of last breakpoint hit (IOCTL 0x%x)\n", OP_GET_LAST_HIT_TID); + printk(KERN_INFO "NOTE: Hardware breakpoints operate on threads, not processes\n"); + printk(KERN_INFO "Use thread IDs (gettid()) instead of process IDs (getpid())\n"); + + return 0; +} + +// 模块卸载 +static void __exit driver_unload(void) +{ + printk(KERN_INFO "ARM64 Hardware Breakpoint Module unloading...\n"); + + // 清除所有断点 + clear_all_breakpoints(); + + // 注销设备 + misc_deregister(&misc_dev); + + printk(KERN_INFO "ARM64 Hardware Breakpoint Module unloaded\n"); +} + +module_init(driver_entry); +module_exit(driver_unload); + +MODULE_DESCRIPTION("ARM64 Hardware Breakpoint Kernel Module with Hook PC Feature"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("陈依涵"); +MODULE_VERSION("2.2"); \ No newline at end of file diff --git a/code/arm64_hw_bp.h b/code/arm64_hw_bp.h new file mode 100644 index 0000000..ee15725 --- /dev/null +++ b/code/arm64_hw_bp.h @@ -0,0 +1,47 @@ +#ifndef _ARM64_HW_BP_H +#define _ARM64_HW_BP_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) +#include +#include +#endif + +// 设备名称 +#define DEVICE_NAME "arm64_hw_bp" + +// 断点类型定义 +enum BP_TYPES { + BP_TYPE_INST = 0, // 指令执行断点 + BP_TYPE_READ = 1, // 数据读断点 + BP_TYPE_WRITE = 2, // 数据写断点 + BP_TYPE_RW = 3 // 数据读写断点 +}; + +#endif /* _ARM64_HW_BP_H */ \ No newline at end of file diff --git a/code/hide_procfs_dir.h b/code/hide_procfs_dir.h deleted file mode 100644 index bf1aa95..0000000 --- a/code/hide_procfs_dir.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef _HIDE_PROCFS_DIR_H_ -#define _HIDE_PROCFS_DIR_H_ - -#include "ver_control.h" - -#include -#include -#include -#include -#include -#include - -static char g_hide_dir_name[256] = {0}; - -static filldir_t old_filldir; - -#if MY_LINUX_VERSION_CODE < KERNEL_VERSION(6,1,0) -static int my_filldir(struct dir_context *buf, - const char *name, - int namelen, - loff_t offset, - u64 ino, - unsigned int d_type) -{ - if (namelen == strlen(g_hide_dir_name) && - !strncmp(name, g_hide_dir_name, namelen)) - { - return 0; - } - return old_filldir(buf, name, namelen, offset, ino, d_type); -} -#else -static bool my_filldir(struct dir_context *ctx, - const char *name, - int namelen, - loff_t offset, - u64 ino, - unsigned int d_type) -{ - if (namelen == strlen(g_hide_dir_name) && - !strncmp(name, g_hide_dir_name, namelen)) - { - return true; - } - return old_filldir(ctx, name, namelen, offset, ino, d_type); -} -#endif - -static int handler_pre(struct kprobe *kp, struct pt_regs *regs) -{ - struct dir_context *ctx = (struct dir_context *)regs->regs[1]; - old_filldir = ctx->actor; - ctx->actor = my_filldir; - return 0; -} - -static struct kprobe kp_hide_procfs_dir = { - .symbol_name = "proc_root_readdir", - .pre_handler = handler_pre, -}; - -static bool start_hide_procfs_dir(const char* hide_dir_name) -{ - //这里原理上可以换成SKRoot的汇编写法。避免kprobe。 - int ret; - strlcpy(g_hide_dir_name, hide_dir_name, sizeof(g_hide_dir_name)); - ret = register_kprobe(&kp_hide_procfs_dir); - if (ret) { - printk_debug("[hide_procfs_dir] register_kprobe failed: %d\n", ret); - return false; - } - printk_debug("[hide_procfs_dir] kprobe installed, hiding \"%s\"\n", g_hide_dir_name); - return true; -} - -static void stop_hide_procfs_dir(void) -{ - unregister_kprobe(&kp_hide_procfs_dir); - printk_debug("[hide_procfs_dir] kprobe removed\n"); -} - -#endif // _HIDE_PROCFS_DIR_H_ diff --git a/code/linux_kernel_api.h b/code/linux_kernel_api.h deleted file mode 100644 index ab693e7..0000000 --- a/code/linux_kernel_api.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef LINUX_KERNEL_API_H_ -#define LINUX_KERNEL_API_H_ -#include "ver_control.h" - -#include - -#if MY_LINUX_VERSION_CODE < KERNEL_VERSION(5,8,0) - -long probe_kernel_read(void* dst, const void* src, size_t size); - -static long x_probe_kernel_read(void* bounce, const char* ptr, size_t sz) { - return probe_kernel_read(bounce, ptr, sz); -} - -#endif - -#if MY_LINUX_VERSION_CODE >= KERNEL_VERSION(5,8,0) - -long copy_from_kernel_nofault(void* dst, const void* src, size_t size); - -static long x_probe_kernel_read(void* bounce, const char* ptr, size_t sz) { - return copy_from_kernel_nofault(bounce, ptr, sz); -} - -#endif - - -#if MY_LINUX_VERSION_CODE < KERNEL_VERSION(6,6,0) -static inline pte_t x_pte_mkwrite(pte_t pte) { - return pte_mkwrite(pte); -} -#else -static inline pte_t x_pte_mkwrite(pte_t pte) { - struct vm_area_struct vma = {.vm_flags = VM_READ}; - return pte_mkwrite(pte, &vma); -} -#endif - -#if MY_LINUX_VERSION_CODE < KERNEL_VERSION(6,6,0) -static size_t x_read_mm_struct_rss(struct mm_struct * mm, ssize_t offset) { - struct mm_rss_stat *rss_stat = (struct mm_rss_stat *)((size_t)&mm->rss_stat + offset); - size_t total_rss; - ssize_t val1, val2, val3; - val1 = atomic_long_read(&rss_stat->count[MM_FILEPAGES]); - val2 = atomic_long_read(&rss_stat->count[MM_ANONPAGES]); -#ifdef MM_SHMEMPAGES - val3 = atomic_long_read(&rss_stat->count[MM_SHMEMPAGES]); -#else - val3 = 0; -#endif - if (val1 < 0) { val1 = 0; } - if (val2 < 0) { val2 = 0; } - if (val3 < 0) { val3 = 0; } - total_rss = val1 + val2 + val3; - return total_rss; -} -#else -static size_t x_read_mm_struct_rss(struct mm_struct * mm, ssize_t offset) { - struct percpu_counter *rss_stat = (struct percpu_counter *)((size_t)&mm->rss_stat + offset); - size_t total_rss; - ssize_t val1, val2, val3; - val1 = percpu_counter_read(&rss_stat[MM_FILEPAGES]); - val2 = percpu_counter_read(&rss_stat[MM_ANONPAGES]); - - #ifdef MM_SHMEMPAGES - val3 = percpu_counter_read(&rss_stat[MM_SHMEMPAGES]); - #else - val3 = 0; - #endif - if (val1 < 0) { val1 = 0; } - if (val2 < 0) { val2 = 0; } - if (val3 < 0) { val3 = 0; } - total_rss = val1 + val2 + val3; - return total_rss; -} -#endif - -#endif /* LINUX_KERNEL_API_H_ */ diff --git a/code/phy_mem.h b/code/phy_mem.h deleted file mode 100644 index 4d6c6d8..0000000 --- a/code/phy_mem.h +++ /dev/null @@ -1,292 +0,0 @@ -#ifndef PHY_MEM_H_ -#define PHY_MEM_H_ -//声明 -////////////////////////////////////////////////////////////////////////// -#include -#include -#include -#include "phy_mem_auto_offset.h" -#include "api_proxy.h" -#include "ver_control.h" - -static inline int is_pte_can_read(pte_t* pte); -static inline int is_pte_can_write(pte_t* pte); -static inline int is_pte_can_exec(pte_t* pte); -static inline int change_pte_read_status(pte_t* pte, bool can_read); -static inline int change_pte_write_status(pte_t* pte, bool can_write); -static inline int change_pte_exec_status(pte_t* pte, bool can_exec); - -static inline size_t get_task_proc_phy_addr(struct task_struct* task, size_t virt_addr, pte_t* out_pte); -static inline size_t get_proc_phy_addr(struct pid* proc_pid_struct, size_t virt_addr, pte_t* out_pte); -static inline size_t read_ram_physical_addr(bool is_kernel_buf, size_t phy_addr, char* lpBuf, size_t read_size); -static inline size_t write_ram_physical_addr(size_t phy_addr, char* lpBuf, bool is_kernel_buf, size_t write_size); - -//实现 -////////////////////////////////////////////////////////////////////////// -#include -#include -#include - -#if MY_LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,83) -#include -#include -#endif - - -#define RETURN_VALUE(size_t_ptr___out_ret, size_t___value) *size_t_ptr___out_ret=size_t___value;break; - -#include - -static inline size_t get_task_proc_phy_addr(struct task_struct* task, size_t virt_addr, pte_t *out_pte) { - struct mm_struct *mm; - pgd_t *pgd; - p4d_t *p4d; - pud_t *pud; - pmd_t *pmd; - pte_t *pte; - unsigned long paddr = 0; - unsigned long page_addr = 0; - unsigned long page_offset = 0; - *(size_t*)out_pte = 0; - - if (!task) { - return 0; - } - mm = get_task_mm(task); - if (!mm) { - return 0; - } - pgd = x_pgd_offset(mm, virt_addr); - if (pgd == NULL) { - printk_debug("pgd is null\n"); - goto out; - } - //printk_debug("pgd_val = 0x%lx pgd addr:0x%p\n", (unsigned long int)pgd_val(*pgd), (void*)pgd); - //printk_debug("init_mm pgd val:0x%lx,pgd addr:0x%p\n", (unsigned long)pgd_val(*(mm->pgd)), (void*)mm->pgd); - printk_debug("pgd_index = %zu\n", pgd_index(virt_addr)); - if (pgd_none(*pgd)) { - printk_debug("not mapped in pgd\n"); - goto out; - } - printk_debug("pgd_offset ok\n"); - - /* - * (p4ds are folded into pgds so this doesn't get actually called, - * but the define is needed for a generic inline function.) - */ - p4d = p4d_offset(pgd, virt_addr); - //printk_debug("p4d_val = 0x%llx, p4d_index = %d\n", p4d_val(*p4d), p4d_index(virt_addr)); - printk_debug("p4d_val = 0x%llx\n", p4d_val(*p4d)); - if (p4d_none(*p4d)) - { - printk_debug("not mapped in p4d\n"); - goto out; - } - - pud = pud_offset(p4d, virt_addr); - printk_debug("pud_val = 0x%llx \n", pud_val(*pud)); - if (pud_none(*pud)) { - printk_debug("not mapped in pud\n"); - goto out; - } - printk_debug("pud_offset ok\n"); - - pmd = pmd_offset(pud, virt_addr); - printk_debug("pmd_val = 0x%llx\n", pmd_val(*pmd)); - //printk_debug("pmd_index = %d\n", pmd_index(virt_addr)); - if (pmd_none(*pmd)) { - printk_debug("not mapped in pmd\n"); - goto out; - } - printk_debug("pmd_offset ok\n"); - - pte = pte_offset_kernel(pmd, virt_addr); - printk_debug("pte_val = 0x%llx\n", pte_val(*pte)); - //printk_debug("pte_index = %d\n", pte_index(virt_addr)); - if (pte_none(*pte)) { - printk_debug("not mapped in pte\n"); - goto out; - } - printk_debug("pte_offset_kernel ok\n"); - - page_addr = page_to_phys(pte_page(*pte)); - page_offset = virt_addr & ~PAGE_MASK; - paddr = page_addr | page_offset; - - printk_debug("page_addr = %lx, page_offset = %lx\n", page_addr, page_offset); - printk_debug("vaddr = %zx, paddr = %lx\n", virt_addr, paddr); - - *(size_t*)out_pte = (size_t)pte; - -out: - mmput(mm); - return paddr; -} - - -static inline size_t get_proc_phy_addr(struct pid* proc_pid_struct, size_t virt_addr, pte_t* out_pte) { - struct task_struct* task = pid_task(proc_pid_struct, PIDTYPE_PID); - if (!task) { return 0; } - return get_task_proc_phy_addr(task, virt_addr, out_pte); -} - - -static inline int is_pte_can_read(pte_t* pte) { - if (!pte) { return 0; } -#ifdef pte_read - if (pte_read(*pte)) { return 1; } else { return 0; } -#endif - return 1; - } -static inline int is_pte_can_write(pte_t* pte) { - if (!pte) { return 0; } - if (pte_write(*pte)) { return 1; } else { return 0; } -} -static inline int is_pte_can_exec(pte_t* pte) { - if (!pte) { return 0; } -#ifdef pte_exec - if (pte_exec(*pte)) { return 1; } else { return 0; } -#endif -#ifdef pte_user_exec - if (pte_user_exec(*pte)) { return 1; } else { return 0; } -#endif - return 0; -} -static inline int change_pte_read_status(pte_t* pte, bool can_read) { - if (!pte) { return 0; } - return 1; -} -static inline int change_pte_write_status(pte_t* pte, bool can_write) { - if (!pte) { return 0; } - if (can_write) { - set_pte(pte, x_pte_mkwrite(*pte)); - } else { - set_pte(pte, pte_wrprotect(*pte)); - } - return 1; -} -static inline int change_pte_exec_status(pte_t* pte, bool can_exec) { - if (!pte) { return 0; } - if (can_exec) { -#ifdef pte_mknexec - set_pte(pte, x_pte_mkwrite(*pte)); -#endif - } else { -#ifdef pte_mkexec - set_pte(pte, x_pte_mkwrite(*pte)); -#endif - } - return 1; -} - -static inline unsigned long size_inside_page(unsigned long start, - unsigned long size) { - unsigned long sz; - - sz = PAGE_SIZE - (start & (PAGE_SIZE - 1)); - - return min(sz, size); -} - - -static inline int check_phys_addr_valid_range(size_t addr, size_t count) { - if (g_phy_total_memory_size == 0) { - init_phy_total_memory_size(); - } - return (addr + count) <= g_phy_total_memory_size; -} - - -static inline size_t read_ram_physical_addr(bool is_kernel_buf, size_t phy_addr, char* lpBuf, size_t read_size) { - void *bounce; - size_t realRead = 0; - if (!check_phys_addr_valid_range(phy_addr, read_size)) { - printk_debug(KERN_INFO "Error in check_phys_addr_valid_range:%zu,size:%zu\n", phy_addr, read_size); - return 0; - } - bounce = x_kmalloc(PAGE_SIZE, GFP_KERNEL); - if (!bounce) { - return 0; - } - - while (read_size > 0) { - size_t sz = size_inside_page(phy_addr, read_size); - - /* - * On ia64 if a page has been mapped somewhere as uncached, then - * it must also be accessed uncached by the kernel or data - * corruption may occur. - */ - - char *ptr = xlate_dev_mem_ptr(phy_addr); - int probe; - - if (!ptr) { - printk_debug(KERN_INFO "Error in x_xlate_dev_mem_ptr:0x%zx\n", phy_addr); - break; - } - probe = x_probe_kernel_read(bounce, ptr, sz); - unxlate_dev_mem_ptr(phy_addr, ptr); - if (probe) { - break; - } - if (is_kernel_buf) { - memcpy(lpBuf, bounce, sz); - } else { - unsigned long remaining = x_copy_to_user(lpBuf, bounce, sz); - if (remaining) { - printk_debug(KERN_INFO "Error in x_copy_to_user(\n"); - break; - } - } - lpBuf += sz; - phy_addr += sz; - read_size -= sz; - realRead += sz; - } - kfree(bounce); - return realRead; -} - -static inline size_t write_ram_physical_addr(size_t phy_addr, char* lpBuf, bool is_kernel_buf, size_t write_size) { - size_t realWrite = 0; - if (!check_phys_addr_valid_range(phy_addr, write_size)) { - printk_debug(KERN_INFO "Error in check_phys_addr_valid_range:0x%zx,size:%zu\n", phy_addr, write_size); - return 0; - } - - while (write_size > 0) { - size_t sz = size_inside_page(phy_addr, write_size); - - /* - * On ia64 if a page has been mapped somewhere as uncached, then - * it must also be accessed uncached by the kernel or data - * corruption may occur. - */ - - char *ptr = xlate_dev_mem_ptr(phy_addr); - if (!ptr) { - printk_debug(KERN_INFO "Error in xlate_dev_mem_ptr:0x%zx\n", phy_addr); - break; - } - if (is_kernel_buf) { - memcpy(ptr, lpBuf, sz); - } else { - unsigned long copied = x_copy_from_user(ptr, lpBuf, sz); - if (copied) { - unxlate_dev_mem_ptr(phy_addr, ptr); - realWrite += sz - copied; - printk_debug(KERN_INFO "Error in x_copy_from_user(\n"); - break; - } - } - unxlate_dev_mem_ptr(phy_addr, ptr); - - lpBuf += sz; - phy_addr += sz; - write_size -= sz; - realWrite += sz; - } - return realWrite; -} -#endif /* PHY_MEM_H_ */ \ No newline at end of file diff --git a/code/phy_mem_auto_offset.h b/code/phy_mem_auto_offset.h deleted file mode 100644 index dfebcf7..0000000 --- a/code/phy_mem_auto_offset.h +++ /dev/null @@ -1,144 +0,0 @@ -#ifndef PHY_MEM_AUTO_OFFSET_H_ -#define PHY_MEM_AUTO_OFFSET_H_ -#include "api_proxy.h" -#include "ver_control.h" - -#undef pgd_offset -#if MY_LINUX_VERSION_CODE <= KERNEL_VERSION(3,10,84) -#define my_pgd_offset(pgd, addr) (pgd+pgd_index(addr)) -#define my_pud_offset(dir, addr) ((pud_t *)__va(pud_offset_phys((dir), (addr)))) -#endif -#if MY_LINUX_VERSION_CODE < KERNEL_VERSION(5,10,43) -#define my_pgd_offset(pgd, addr) (pgd+pgd_index(addr)) -#define my_pud_offset(dir, addr) ((pud_t *)__va(pud_offset_phys((dir), (addr)))) -#endif -#if MY_LINUX_VERSION_CODE >= KERNEL_VERSION(5,10,43) -#define my_pgd_offset(pgd, address) pgd_offset_pgd(pgd, address) -#endif - -#define my_get_fs() (current_thread_info()->addr_limit) - -static size_t g_phy_total_memory_size = 0; // 物理内存总大小 -static int init_phy_total_memory_size(void) { - struct sysinfo si; - unsigned long mem_total, sav_total; - unsigned int bitcount = 0; - unsigned int mem_unit = 0; - if (g_phy_total_memory_size) { - return 0; - } - - si_meminfo(&si); - mem_unit = si.mem_unit; - - mem_total = si.totalram; - while (mem_unit > 1) { - bitcount++; - mem_unit >>= 1; - sav_total = mem_total; - mem_total <<= 1; - if (mem_total < sav_total) { - return 0; - } - } - si.totalram <<= bitcount; - g_phy_total_memory_size = __pa(si.totalram); - printk_debug(KERN_INFO "MemTotal si.totalram:%ld\n", si.totalram); - printk_debug(KERN_INFO "g_phy_total_memory_size:%ld\n", g_phy_total_memory_size); - return 0; -} - -static ssize_t g_pgd_offset_mm_struct = 0; -static bool g_init_pgd_offset_success = false; - -#if MY_LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,75) - -static int init_pgd_offset(struct mm_struct *mm) { - int is_found_pgd_offset = 0; - g_init_pgd_offset_success = false; - for (g_pgd_offset_mm_struct = -40; g_pgd_offset_mm_struct <= 80; g_pgd_offset_mm_struct += 1) { - char *rp; - size_t val; - ssize_t accurate_offset = (ssize_t)((size_t)&mm->pgd - (size_t)mm + g_pgd_offset_mm_struct); - if (accurate_offset >= sizeof(struct mm_struct) - sizeof(ssize_t)) { - return -EFAULT; - } - rp = (char*)((size_t)mm + (size_t)accurate_offset); - val = *(size_t*)(rp); - printk_debug(KERN_EMERG "init_pgd_offset %zd:%zd:%p:%ld\n", g_pgd_offset_mm_struct, accurate_offset, rp, val); - - if (val == TASK_SIZE) { - g_pgd_offset_mm_struct += sizeof(unsigned long); - printk_debug(KERN_EMERG "found g_init_pgd_offset_success:%zd\n", g_pgd_offset_mm_struct); - is_found_pgd_offset = 1; - break; - } - } - if (!is_found_pgd_offset) { - printk_debug(KERN_INFO "find pgd offset failed\n"); - return -ESPIPE; - } - g_init_pgd_offset_success = true; - printk_debug(KERN_INFO "g_pgd_offset_mm_struct:%zu\n", g_pgd_offset_mm_struct); - return 0; -} -#else -static int init_pgd_offset(struct mm_struct *mm) { - int is_found_pgd_offset = 0; - g_init_pgd_offset_success = false; - for (g_pgd_offset_mm_struct = -40; g_pgd_offset_mm_struct <= 80; g_pgd_offset_mm_struct += 1) { - char *rp; - size_t val; - ssize_t accurate_offset = (ssize_t)((size_t)&mm->pgd - (size_t)mm + g_pgd_offset_mm_struct); - if (accurate_offset >= sizeof(struct mm_struct) - sizeof(ssize_t)) { - return -EFAULT; - } - rp = (char*)((size_t)mm + (size_t)accurate_offset); - val = *(size_t*)(rp); - printk_debug(KERN_EMERG "init_pgd_offset %zd:%zd:%p:%ld\n", g_pgd_offset_mm_struct, accurate_offset, rp, val); - - if (val == TASK_SIZE) { - g_pgd_offset_mm_struct += sizeof(unsigned long); - g_pgd_offset_mm_struct += sizeof(unsigned long); - printk_debug(KERN_EMERG "found g_init_pgd_offset_success:%zd\n", g_pgd_offset_mm_struct); - is_found_pgd_offset = 1; - break; - } - } - if (!is_found_pgd_offset) { - printk_debug(KERN_INFO "find pgd offset failed\n"); - return -ESPIPE; - } - g_init_pgd_offset_success = true; - printk_debug(KERN_INFO "g_pgd_offset_mm_struct:%zu\n", g_pgd_offset_mm_struct); - return 0; -} -#endif - -static inline pgd_t *x_pgd_offset(struct mm_struct *mm, size_t addr) { - size_t pgd; - ssize_t accurate_offset; - if (g_init_pgd_offset_success == false) { - if (init_pgd_offset(mm) != 0) { - return NULL; - } - } - accurate_offset = (ssize_t)((size_t)&mm->pgd - (size_t)mm + g_pgd_offset_mm_struct); - printk_debug(KERN_INFO "x_pgd_offset accurate_offset:%zd\n", accurate_offset); - if (accurate_offset >= sizeof(struct mm_struct) - sizeof(ssize_t)) { - return NULL; - } - - //拷贝到我自己的pgd指针变量里去 - //写法一(可读性强) - //void * rv = (size_t*)((size_t)mm + (size_t)accurate_offset); - //pgd_t *pgd; - //memcpy(&pgd, rv, sizeof(pgd_t *)); - - //写法二(快些) - pgd = *(size_t*)((size_t)mm + (size_t)accurate_offset); - - return my_pgd_offset((pgd_t*)pgd, addr); -} - -#endif /* PHY_MEM_AUTO_OFFSET_H_ */ \ No newline at end of file diff --git a/code/proc_cmdline.h b/code/proc_cmdline.h deleted file mode 100644 index f6885f5..0000000 --- a/code/proc_cmdline.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef PROC_CMDLINE_H_ -#define PROC_CMDLINE_H_ -//声明 -////////////////////////////////////////////////////////////////////////// -#include -#include "ver_control.h" - -static inline struct pid * get_proc_pid_struct(int pid); -static inline int get_proc_pid(struct pid* proc_pid_struct); -static inline void release_proc_pid_struct(struct pid* proc_pid_struct); -static inline int get_proc_cmdline_addr(struct pid* proc_pid_struct, size_t * arg_start, size_t * arg_end); -static inline int get_task_proc_cmdline_addr(struct task_struct *task, size_t * arg_start, size_t * arg_end); - - -//实现 -////////////////////////////////////////////////////////////////////////// -#include "phy_mem.h" -#include "proc_cmdline_auto_offset.h" -#include "api_proxy.h" - -static inline struct pid * get_proc_pid_struct(int pid) { - return find_get_pid(pid); -} - -static inline int get_proc_pid(struct pid* proc_pid_struct) { - return proc_pid_struct->numbers[0].nr; -} - -static inline void release_proc_pid_struct(struct pid* proc_pid_struct) { - put_pid(proc_pid_struct); -} - -static inline int get_proc_cmdline_addr(struct pid* proc_pid_struct, size_t * arg_start, size_t * arg_end) { - int ret = 0; - struct task_struct *task = NULL; - - - if (g_init_arg_start_offset_success == false) { - return -ENOENT; - } - - - task = pid_task(proc_pid_struct, PIDTYPE_PID); - if (!task) { return -EFAULT; } - ret = get_task_proc_cmdline_addr(task, arg_start, arg_end); - return ret; -} - -static inline int get_task_proc_cmdline_addr(struct task_struct *task, size_t * arg_start, size_t * arg_end) { - if (g_init_arg_start_offset_success) { - struct mm_struct *mm; - ssize_t accurate_offset; - mm = get_task_mm(task); - - if (!mm) { return -EFAULT; } - - //精确偏移 - accurate_offset = (ssize_t)((size_t)&mm->arg_start - (size_t)mm + g_arg_start_offset); - if (accurate_offset >= sizeof(struct mm_struct) - sizeof(ssize_t)) { - mmput(mm); - return -EFAULT; - } - - if (down_read_mmap_lock(mm) != 0) { - mmput(mm); - return -EFAULT; - } - printk_debug(KERN_INFO "accurate_offset:%zd\n", accurate_offset); - - *arg_start = *(size_t*)((size_t)mm + (size_t)accurate_offset); - *arg_end = *(size_t*)((size_t)mm + (size_t)accurate_offset + sizeof(unsigned long)); - - printk_debug(KERN_INFO "arg_start addr:0x%p\n", (void*)*arg_start); - - up_read_mmap_lock(mm); - mmput(mm); - return 0; - } - return -ESPIPE; -} -#endif /* PROC_CMDLINE_H_ */ \ No newline at end of file diff --git a/code/proc_cmdline_auto_offset.h b/code/proc_cmdline_auto_offset.h deleted file mode 100644 index e7ba159..0000000 --- a/code/proc_cmdline_auto_offset.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef PROC_CMDLINE_AUTO_OFFSET_H_ -#define PROC_CMDLINE_AUTO_OFFSET_H_ -//声明 -////////////////////////////////////////////////////////////////////////// -#include -#include "ver_control.h" -//实现 -////////////////////////////////////////////////////////////////////////// -#include "api_proxy.h" -static ssize_t g_arg_start_offset = 0; -static bool g_init_arg_start_offset_success = false; - -typedef int(*t_get_task_proc_cmdline_addr)(struct task_struct *task, size_t * arg_start, size_t * arg_end); - -static inline int init_proc_cmdline_offset(const char* my_cmdline, - t_get_task_proc_cmdline_addr o_get_task_proc_cmdline_addr) { - - int is_found_cmdline_offset = 0; - size_t size = 4096; - char *new_cmd_line_buf = NULL; - struct task_struct * mytask = x_get_current(); - - if(g_init_arg_start_offset_success) { - return 0; - } - - new_cmd_line_buf = (char*)kmalloc(size, GFP_KERNEL); - g_init_arg_start_offset_success = true; - for (g_arg_start_offset = -64; g_arg_start_offset <= 64; g_arg_start_offset += 1) { - size_t arg_start = 0, arg_end = 0; - printk_debug(KERN_INFO "get_task_proc_cmdline_addr g_arg_start_offset %zd\n", g_arg_start_offset); - if (o_get_task_proc_cmdline_addr(mytask, &arg_start, &arg_end) == 0) { - printk_debug(KERN_INFO "get_task_proc_cmdline_addr arg_start %p\n", (void*)arg_start); - - if (arg_start > 0) { - - size_t read_size = 0; - - memset(new_cmd_line_buf, 0, size); - - while (read_size < size) { - size_t phy_addr; - size_t pfn_sz; - char *lpOutBuf; - - pte_t *pte; - phy_addr = get_task_proc_phy_addr(mytask, arg_start + read_size, (pte_t*)&pte); - printk_debug(KERN_INFO "phy_addr:0x%zx\n", phy_addr); - if (phy_addr == 0) { - break; - } - - pfn_sz = size_inside_page(phy_addr, ((size - read_size) > PAGE_SIZE) ? PAGE_SIZE : (size - read_size)); - printk_debug(KERN_INFO "pfn_sz:%zu\n", pfn_sz); - - lpOutBuf = (char*)(new_cmd_line_buf + read_size); - read_ram_physical_addr(true, phy_addr, lpOutBuf, pfn_sz); - read_size += pfn_sz; - } - - printk_debug(KERN_INFO "new_cmd_line_buf:%s, len:%ld\n", new_cmd_line_buf, strlen(new_cmd_line_buf)); - - if (strcmp(new_cmd_line_buf, my_cmdline) == 0) { - is_found_cmdline_offset = 1; - break; - } - - - } - } - } - - kfree(new_cmd_line_buf); - - if (!is_found_cmdline_offset) { - g_init_arg_start_offset_success = false; - printk_debug(KERN_INFO "find cmdline offset failed\n"); - return -ESPIPE; - } - printk_debug(KERN_INFO "g_arg_start_offset:%zu\n", g_arg_start_offset); - return 0; -} -#endif /* PROC_CMDLINE_AUTO_OFFSET_H_ */ \ No newline at end of file diff --git a/code/proc_list.h b/code/proc_list.h deleted file mode 100644 index 9786b7a..0000000 --- a/code/proc_list.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef PROC_LIST_H_ -#define PROC_LIST_H_ -#include "api_proxy.h" -#include "proc_list_auto_offset.h" -#include "ver_control.h" - -#include -#include -#include -#include -#include - -//声明 -////////////////////////////////////////////////////////////////////////// -static ssize_t get_proc_pid_list(bool is_kernel_buf, char* buf, size_t buf_size); - - -//实现 -////////////////////////////////////////////////////////////////////////// - -static ssize_t get_proc_pid_list(bool is_kernel_buf, - char* buf, - size_t buf_size) { - struct task_struct *p, *next; - ssize_t count = 0; - size_t buf_pos = 0; - - if (!g_init_task_next_offset_success || !g_init_task_pid_offset_success) { - return -EFAULT; - } - - p = &init_task; - while (1) { - uintptr_t list_next = *(uintptr_t *)((char *)p + g_task_next_offset); - next = (struct task_struct *)(list_next - g_task_next_offset); - if (next == &init_task) - break; - - count++; - - { - pid_t pid_v = *(pid_t *)((char *)next + g_task_pid_offset); - int pid_n = pid_v; - printk_debug(KERN_INFO "iter_task: pid = %d\n", pid_n); - if (buf_pos < buf_size) { - if (is_kernel_buf) { - memcpy((void*)((size_t)buf + (size_t)buf_pos), &pid_n, sizeof(pid_n)); - } else { - x_copy_to_user((void*)((size_t)buf + (size_t)buf_pos), &pid_n, sizeof(pid_n)); - } - buf_pos += sizeof(pid_n); - } - } - p = next; - } - - return count; -} - -#endif /* PROC_LIST_H_ */ - - diff --git a/code/proc_list_auto_offset.h b/code/proc_list_auto_offset.h deleted file mode 100644 index 68f2398..0000000 --- a/code/proc_list_auto_offset.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef PROC_LIST_AUTO_OFFSET_H_ -#define PROC_LIST_AUTO_OFFSET_H_ -#include -#include "ver_control.h" - -static ssize_t g_task_next_offset = 0; -static bool g_init_task_next_offset_success = false; - -static ssize_t g_task_pid_offset = 0; -static bool g_init_task_pid_offset_success = false; - -static inline int init_task_next_offset(void) { - struct task_struct * mytask = x_get_current(); - uintptr_t addr_mytask = (uintptr_t)mytask; - uintptr_t addr_mm = (uintptr_t)get_task_mm(mytask); - size_t off_mm = 0; - size_t off = 0; - if(g_init_task_next_offset_success) { - return 0; - } - - for (off = 0; off <= sizeof(struct task_struct) - sizeof(void*); off+=4) { - void *v = *(void **)(addr_mytask + off); - if ((uintptr_t)v == addr_mm) { - off_mm = off; - break; - } - } - - if(off_mm == 0) { - printk_debug(KERN_EMERG "init_task_next_offset mm_struct failed.\n"); - return -EFAULT; - } - printk_debug(KERN_EMERG "init_task_next_offset mm_struct found:%zu.\n", off_mm); - g_task_next_offset = off_mm - sizeof(mytask->pushable_dl_tasks) - sizeof(mytask->pushable_tasks) - sizeof(mytask->tasks); - g_init_task_next_offset_success = true; - printk_debug(KERN_INFO "init_task_next_offset: found tasks offset = %zu bytes\n", g_task_next_offset); - return 0; -} - -static inline int init_task_pid_offset(int pid, int tgid) { - struct task_struct *mytask = x_get_current(); - uintptr_t addr_mytask = (uintptr_t)mytask; - uintptr_t addr_mm = (uintptr_t)get_task_mm(mytask); - size_t off_mm = 0; - size_t off = 0; - - size_t off_pid_static = (uintptr_t)&mytask->pid - addr_mytask; - printk_debug(KERN_INFO - "init_task_pid_offset: mytask@%p, &pid@%p, static off_pid = %zu, sizeof(%zu, %zu)\n", - mytask, &mytask->pid, off_pid_static, sizeof(mytask->pid), sizeof(mytask->tgid)); - - if (g_init_task_pid_offset_success) { - return 0; - } - - for (off = 0; off <= sizeof(struct task_struct) - sizeof(void*); off+=4) { - void *v = *(void **)(addr_mytask + off); - if ((uintptr_t)v == addr_mm) { - off_mm = off; - break; - } - } - - if (off_mm == 0) { - printk_debug(KERN_EMERG "init_task_pid_offset: mm_struct offset not found\n"); - return -EFAULT; - } - printk_debug(KERN_INFO "init_task_pid_offset: mm_struct offset found = %zu\n", off_mm); - - for (off = off_mm; off <= sizeof(struct task_struct) - 2 * sizeof(pid_t); off += 4) { - pid_t pid_v = *(pid_t *)(addr_mytask + off); - pid_t tgid_v = *(pid_t *)(addr_mytask + off + sizeof(pid_t)); - if (pid_v == pid && tgid_v == tgid) { - g_task_pid_offset = off; - g_init_task_pid_offset_success = true; - printk_debug(KERN_INFO - "init_task_pid_offset: found pid/tgid offset = %zu (pid=%d, tgid=%d)\n", - g_task_pid_offset, pid, tgid); - return 0; - } - } - - printk_debug(KERN_EMERG - "init_task_pid_offset: failed to match pid=%d, tgid=%d\n", - pid, tgid); - return -ENOENT; -} - -#endif /* PROC_LIST_AUTO_OFFSET_H_ */ - - diff --git a/code/proc_maps.h b/code/proc_maps.h deleted file mode 100644 index 56360f7..0000000 --- a/code/proc_maps.h +++ /dev/null @@ -1,2445 +0,0 @@ -#ifndef PROC_MAPS_H_ -#define PROC_MAPS_H_ - -//声明 -////////////////////////////////////////////////////////////////////////// -#include -#include -#include -#if MY_LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,83) -#include -#include -#endif - -static inline int down_read_mmap_lock(struct mm_struct *mm); -static inline int up_read_mmap_lock(struct mm_struct *mm); -static inline size_t get_proc_map_count(struct pid* proc_pid_struct); -static int get_proc_maps_list(bool is_kernel_buf, struct pid* proc_pid_struct, char* buf, size_t buf_size); - -//实现 -////////////////////////////////////////////////////////////////////////// -#include -#include -#include -#include -#include -#include -#include -#include "api_proxy.h" -#include "proc_maps_auto_offset.h" -#include "ver_control.h" - -#define MY_PATH_MAX_LEN 1024 -#pragma pack(push,1) -struct map_entry { - unsigned long start; - unsigned long end; - unsigned char flags[4]; - char path[MY_PATH_MAX_LEN]; -}; -#pragma pack(pop) - -static inline size_t get_proc_map_count(struct pid* proc_pid_struct) { - ssize_t accurate_offset; - struct task_struct *task = pid_task(proc_pid_struct, PIDTYPE_PID); - struct mm_struct *mm = get_task_mm(task); - size_t count = 0; - if (g_init_map_count_offset_success == false) { - return 0; - } - - if (down_read_mmap_lock(mm) != 0) { - goto _exit; - } - - accurate_offset = (ssize_t)((size_t)&mm->map_count - (size_t)mm + g_map_count_offset); - printk_debug(KERN_INFO "mm->map_count accurate_offset:%zd\n", accurate_offset); - if (accurate_offset >= sizeof(struct mm_struct) - sizeof(ssize_t)) { - return 0; - } - count = *(int *)((size_t)mm + (size_t)accurate_offset); - - up_read_mmap_lock(mm); - -_exit:mmput(mm); - return count; -} - - -static inline int check_proc_map_can_read(struct pid* proc_pid_struct, size_t proc_virt_addr, size_t size) { - struct task_struct *task = pid_task(proc_pid_struct, PIDTYPE_PID); - struct mm_struct *mm; - struct vm_area_struct *vma; - int res = 0; - if (!task) { return res; } - - mm = get_task_mm(task); - - if (!mm) { return res; } - - if (down_read_mmap_lock(mm) != 0) { - goto _exit; - } - - vma = find_vma(mm, proc_virt_addr); - if (vma) { - if (vma->vm_flags & VM_READ) { - size_t read_end = proc_virt_addr + size; - if (read_end <= vma->vm_end) { - res = 1; - } - } - } - up_read_mmap_lock(mm); - -_exit:mmput(mm); - return res; -} -static inline int check_proc_map_can_write(struct pid* proc_pid_struct, size_t proc_virt_addr, size_t size) { - struct task_struct *task = pid_task(proc_pid_struct, PIDTYPE_PID); - struct mm_struct *mm; - struct vm_area_struct *vma; - int res = 0; - - if (!task) { return res; } - - mm = get_task_mm(task); - - if (!mm) { return res; } - - if (down_read_mmap_lock(mm) != 0) { - mmput(mm); - return res; - } - - vma = find_vma(mm, proc_virt_addr); - if (vma) { - if (vma->vm_flags & VM_WRITE) { - size_t read_end = proc_virt_addr + size; - if (read_end <= vma->vm_end) { - res = 1; - } - } - } - up_read_mmap_lock(mm); - mmput(mm); - return res; -} - - -#if MY_LINUX_VERSION_CODE == KERNEL_VERSION(3,10,0) -/* Check if the vma is being used as a stack by this task */ -static int vm_is_stack_for_task(struct task_struct *t, - struct vm_area_struct *vma) { - return (vma->vm_start <= KSTK_ESP(t) && vma->vm_end >= KSTK_ESP(t)); -} - -/* - * Check if the vma is being used as a stack. - * If is_group is non-zero, check in the entire thread group or else - * just check in the current task. Returns the pid of the task that - * the vma is stack for. - */ -static pid_t my_vm_is_stack(struct task_struct *task, - struct vm_area_struct *vma, int in_group) { - pid_t ret = 0; - - if (vm_is_stack_for_task(task, vma)) - return task->pid; - - if (in_group) { - struct task_struct *t; - rcu_read_lock(); - if (!pid_alive(task)) - goto done; - - t = task; - do { - if (vm_is_stack_for_task(t, vma)) { - ret = t->pid; - goto done; - } - } while_each_thread(task, t); - done: - rcu_read_unlock(); - } - - return ret; -} - -static int get_proc_maps_list(bool is_kernel_buf, struct pid* proc_pid_struct, char* buf, size_t buf_size) { - - struct task_struct *task; - struct mm_struct *mm; - struct vm_area_struct *vma; - char path_buf[MY_PATH_MAX_LEN]; - int success_cnt = 0; - - task = pid_task(proc_pid_struct, PIDTYPE_PID); - if (!task) { - return -2; - } - - mm = get_task_mm(task); - if (!mm) { - return -3; - } - - - if (is_kernel_buf) { - memset(buf, 0, buf_size); - } - //else if (clear_user(buf, buf_size)) { return -4; } //清空用户的缓冲区 - - copy_pos = (size_t)buf; - end_pos = (size_t)((size_t)buf + buf_size); - - if (down_read_mmap_lock(mm) != 0) { - mmput(mm); - return -4; - } - - for (vma = mm->mmap; vma; vma = vma->vm_next) { - struct map_entry entry; - struct file * vm_file; - if (copy_pos >= end_pos) { - break; - } - entry.start = vma->vm_start; - entry.end = vma->vm_end; - /* We don't show the stack guard page in /proc/maps */ - if (stack_guard_page_start(vma, entry.start)) - entry.start += PAGE_SIZE; - if (stack_guard_page_end(vma, entry.end)) - entry.end -= PAGE_SIZE; - - entry.flags[0] = (vma->vm_flags & VM_READ) ? 1 : 0; - entry.flags[1] = (vma->vm_flags & VM_WRITE) ? 1 : 0; - entry.flags[2] = (vma->vm_flags & VM_EXEC) ? 1 : 0; - entry.flags[3] = (vma->vm_flags & VM_MAYSHARE) ? 1 : 0; - memset(entry.path, 0, sizeof(entry.path)); - vm_file = get_vm_file(vma); - if (vm_file) { - char *path; - memset(path_buf, 0, sizeof(path_buf)); - path = d_path(&vm_file->f_path, path_buf, sizeof(path_buf)); - if (path > 0) { - strncat(entry.path, path, sizeof(entry.path) - 1); - } - } else if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) { - snprintf(entry.path, sizeof(entry.path), "%s[vdso]", entry.path); - } else { - if (vma->vm_start <= mm->brk && - vma->vm_end >= mm->start_brk) { - snprintf(entry.path, sizeof(entry.path), "%s[heap]", entry.path); - } else { - pid_t tid = my_vm_is_stack(task, vma, 1); - if (tid != 0) { - /* - * Thread stack in /proc/PID/task/TID/maps or - * the main process stack. - */ - - /* Thread stack in /proc/PID/maps */ - - sprintf(entry.path, "[stack:%d]", tid); - } - } - - } - - if (is_kernel_buf) { - memcpy((void *)copy_pos, &entry, sizeof(entry)); - } else { - if (x_copy_to_user((void *)copy_pos, &entry, sizeof(entry))) { - break; - } - } - copy_pos += sizeof(entry); - success_cnt++; - } - up_read_mmap_lock(mm); - mmput(mm); - - return success_cnt; -} - - - -#endif - - - - -#if MY_LINUX_VERSION_CODE == KERNEL_VERSION(3,10,84) -/* Check if the vma is being used as a stack by this task */ -static int vm_is_stack_for_task(struct task_struct *t, - struct vm_area_struct *vma) { - return (vma->vm_start <= KSTK_ESP(t) && vma->vm_end >= KSTK_ESP(t)); -} - -/* - * Check if the vma is being used as a stack. - * If is_group is non-zero, check in the entire thread group or else - * just check in the current task. Returns the pid of the task that - * the vma is stack for. - */ -static pid_t my_vm_is_stack(struct task_struct *task, - struct vm_area_struct *vma, int in_group) { - pid_t ret = 0; - - if (vm_is_stack_for_task(task, vma)) - return task->pid; - - if (in_group) { - struct task_struct *t; - rcu_read_lock(); - if (!pid_alive(task)) - goto done; - - t = task; - do { - if (vm_is_stack_for_task(t, vma)) { - ret = t->pid; - goto done; - } - } while_each_thread(task, t); - done: - rcu_read_unlock(); - } - - return ret; -} - -static int get_proc_maps_list(bool is_kernel_buf, struct pid* proc_pid_struct, char* buf, size_t buf_size) { - - struct task_struct *task; - struct mm_struct *mm; - struct vm_area_struct *vma; - char path_buf[MY_PATH_MAX_LEN]; - int success_cnt = 0; - size_t copy_pos; - size_t end_pos; - task = pid_task(proc_pid_struct, PIDTYPE_PID); - if (!task) { - return -2; - } - - mm = get_task_mm(task); - if (!mm) { - return -3; - } - - - if (is_kernel_buf) { - memset(buf, 0, buf_size); - } - //else if (clear_user(buf, buf_size)) { return -4; } //清空用户的缓冲区 - - - copy_pos = (size_t)buf; - end_pos = (size_t)((size_t)buf + buf_size); - - if (down_read_mmap_lock(mm) != 0) { - mmput(mm); - return -4; - } - for (vma = mm->mmap; vma; vma = vma->vm_next) { - struct map_entry entry; - struct file * vm_file; - if (copy_pos >= end_pos) { - break; - } - entry.start = vma->vm_start; - entry.end = vma->vm_end; - /* We don't show the stack guard page in /proc/maps */ - if (stack_guard_page_start(vma, entry.start)) - entry.start += PAGE_SIZE; - if (stack_guard_page_end(vma, entry.end)) - entry.end -= PAGE_SIZE; - - entry.flags[0] = (vma->vm_flags & VM_READ) ? 1 : 0; - entry.flags[1] = (vma->vm_flags & VM_WRITE) ? 1 : 0; - entry.flags[2] = (vma->vm_flags & VM_EXEC) ? 1 : 0; - entry.flags[3] = (vma->vm_flags & VM_MAYSHARE) ? 1 : 0; - memset(entry.path, 0, sizeof(entry.path)); - vm_file = get_vm_file(vma); - if (vm_file) { - char *path; - memset(path_buf, 0, sizeof(path_buf)); - path = d_path(&vm_file->f_path, path_buf, sizeof(path_buf)); - if (path > 0) { - strncat(entry.path, path, sizeof(entry.path) - 1); - } - } else if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) { - snprintf(entry.path, sizeof(entry.path), "%s[vdso]", entry.path); - } else { - if (vma->vm_start <= mm->brk && - vma->vm_end >= mm->start_brk) { - snprintf(entry.path, sizeof(entry.path), "%s[heap]", entry.path); - } else { - pid_t tid = my_vm_is_stack(task, vma, 1); - if (tid != 0) { - /* - * Thread stack in /proc/PID/task/TID/maps or - * the main process stack. - */ - - /* Thread stack in /proc/PID/maps */ - - sprintf(entry.path, "[stack:%d]", tid); - } - } - - } - - - if (is_kernel_buf) { - memcpy((void *)copy_pos, &entry, sizeof(entry)); - } else { - if (x_copy_to_user((void *)copy_pos, &entry, sizeof(entry))) { - break; - } - } - copy_pos += sizeof(entry); - success_cnt++; - } - up_read_mmap_lock(mm); - mmput(mm); - - return success_cnt; -} - -#endif - - -#if MY_LINUX_VERSION_CODE == KERNEL_VERSION(3,18,71) -/* Check if the vma is being used as a stack by this task */ -static int vm_is_stack_for_task(struct task_struct *t, - struct vm_area_struct *vma) { - return (vma->vm_start <= KSTK_ESP(t) && vma->vm_end >= KSTK_ESP(t)); -} - - -/* - * Check if the vma is being used as a stack. - * If is_group is non-zero, check in the entire thread group or else - * just check in the current task. Returns the task_struct of the task - * that the vma is stack for. Must be called under rcu_read_lock(). - */ -struct task_struct *task_of_stack(struct task_struct *task, - struct vm_area_struct *vma, bool in_group) { - if (vm_is_stack_for_task(task, vma)) - return task; - - if (in_group) { - struct task_struct *t; - - for_each_thread(task, t) { - if (vm_is_stack_for_task(t, vma)) - return t; - } - } - - return NULL; -} - - -static pid_t pid_of_stack(struct task_struct *task, - struct vm_area_struct *vma, bool is_pid) { - pid_t ret = 0; - - rcu_read_lock(); - task = task_of_stack(task, vma, is_pid); - if (task) { - ret = task->pid; - } - rcu_read_unlock(); - - return ret; -} - - -static int get_proc_maps_list(bool is_kernel_buf, struct pid* proc_pid_struct, char* buf, size_t buf_size) { - struct task_struct *task; - struct mm_struct *mm; - struct vm_area_struct *vma; - char path_buf[MY_PATH_MAX_LEN]; - int success_cnt = 0; - size_t copy_pos; - size_t end_pos; - - task = pid_task(proc_pid_struct, PIDTYPE_PID); - if (!task) { - return -2; - } - - mm = get_task_mm(task); - if (!mm) { - return -3; - } - - if (is_kernel_buf) { - memset(buf, 0, buf_size); - } - //else if (clear_user(buf, buf_size)) { return -4; } //清空用户的缓冲区 - - - copy_pos = (size_t)buf; - end_pos = (size_t)((size_t)buf + buf_size); - - if (down_read_mmap_lock(mm) != 0) { - mmput(mm); - return -4; - } - for (vma = mm->mmap; vma; vma = vma->vm_next) { - struct map_entry entry; - struct file * vm_file; - if (copy_pos >= end_pos) { - break; - } - entry.start = vma->vm_start; - entry.end = vma->vm_end; - entry.flags[0] = (vma->vm_flags & VM_READ) ? 1 : 0; - entry.flags[1] = (vma->vm_flags & VM_WRITE) ? 1 : 0; - entry.flags[2] = (vma->vm_flags & VM_EXEC) ? 1 : 0; - entry.flags[3] = (vma->vm_flags & VM_MAYSHARE) ? 1 : 0; - memset(entry.path, 0, sizeof(entry.path)); - vm_file = get_vm_file(vma); - if (vm_file) { - char *path; - memset(path_buf, 0, sizeof(path_buf)); - path = d_path(&vm_file->f_path, path_buf, sizeof(path_buf)); - if (path > 0) { - strncat(entry.path, path, sizeof(entry.path) - 1); - } - } else if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) { - snprintf(entry.path, sizeof(entry.path), "%s[vdso]", entry.path); - } else { - if (vma->vm_start <= mm->brk && - vma->vm_end >= mm->start_brk) { - snprintf(entry.path, sizeof(entry.path), "%s[heap]", entry.path); - } else { - pid_t tid = pid_of_stack(task, vma, 1); - if (tid != 0) { - /* - * Thread stack in /proc/PID/task/TID/maps or - * the main process stack. - */ - - /* Thread stack in /proc/PID/maps */ - if (vma->vm_start <= mm->start_stack && - vma->vm_end >= mm->start_stack) { - snprintf(entry.path, sizeof(entry.path), "%s[stack]", entry.path); - } else { - snprintf(entry.path, sizeof(entry.path), "[stack:%d]", tid); - } - } - - } - - } - if (is_kernel_buf) { - memcpy((void *)copy_pos, &entry, sizeof(entry)); - } else { - if (x_copy_to_user((void *)copy_pos, &entry, sizeof(entry))) { - break; - } - } - copy_pos += sizeof(entry); - success_cnt++; - } - up_read_mmap_lock(mm); - mmput(mm); - - return success_cnt; -} - -#endif - - - -#if MY_LINUX_VERSION_CODE == KERNEL_VERSION(3,18,140) -/* - * Indicate if the VMA is a stack for the given task; for - * /proc/PID/maps that is the stack of the main task. - */ -static int is_stack(struct vm_area_struct *vma) { - /* - * We make no effort to guess what a given thread considers to be - * its "stack". It's not even well-defined for programs written - * languages like Go. - */ - return vma->vm_start <= vma->vm_mm->start_stack && - vma->vm_end >= vma->vm_mm->start_stack; -} - - -static int get_proc_maps_list(bool is_kernel_buf, struct pid* proc_pid_struct, char* buf, size_t buf_size) { - struct task_struct *task; - struct mm_struct *mm; - struct vm_area_struct *vma; - char path_buf[MY_PATH_MAX_LEN]; - int success_cnt = 0; - size_t copy_pos; - size_t end_pos; - - task = pid_task(proc_pid_struct, PIDTYPE_PID); - if (!task) { - return -2; - } - - mm = get_task_mm(task); - - if (!mm) { - return -3; - } - - if (is_kernel_buf) { - memset(buf, 0, buf_size); - } - //else if (clear_user(buf, buf_size)) { return -4; } //清空用户的缓冲区 - - - copy_pos = (size_t)buf; - end_pos = (size_t)((size_t)buf + buf_size); - - if (down_read_mmap_lock(mm) != 0) { - mmput(mm); - return -4; - } - for (vma = mm->mmap; vma; vma = vma->vm_next) { - struct map_entry entry; - struct file * vm_file; - if (copy_pos >= end_pos) { - break; - } - entry.start = vma->vm_start; - entry.end = vma->vm_end; - entry.flags[0] = (vma->vm_flags & VM_READ) ? 1 : 0; - entry.flags[1] = (vma->vm_flags & VM_WRITE) ? 1 : 0; - entry.flags[2] = (vma->vm_flags & VM_EXEC) ? 1 : 0; - entry.flags[3] = (vma->vm_flags & VM_MAYSHARE) ? 1 : 0; - memset(entry.path, 0, sizeof(entry.path)); - vm_file = get_vm_file(vma); - if (vm_file) { - char *path; - memset(path_buf, 0, sizeof(path_buf)); - path = d_path(&vm_file->f_path, path_buf, sizeof(path_buf)); - if (path > 0) { - strncat(entry.path, path, sizeof(entry.path) - 1); - } - } else if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) { - snprintf(entry.path, sizeof(entry.path), "%s[vdso]", entry.path); - } else { - if (vma->vm_start <= mm->brk && - vma->vm_end >= mm->start_brk) { - snprintf(entry.path, sizeof(entry.path), "%s[heap]", entry.path); - } else { - if (is_stack(vma)) { - snprintf(entry.path, sizeof(entry.path), "%s[stack]", entry.path); - } - } - - } - - if (is_kernel_buf) { - memcpy((void *)copy_pos, &entry, sizeof(entry)); - } else { - if (x_copy_to_user((void *)copy_pos, &entry, sizeof(entry))) { - break; - } - } - copy_pos += sizeof(entry); - success_cnt++; - } - up_read_mmap_lock(mm); - mmput(mm); - - return success_cnt; -} - - -#endif - - - -#if MY_LINUX_VERSION_CODE == KERNEL_VERSION(4,4,21) -/* Check if the vma is being used as a stack by this task */ -int vma_is_stack_for_task(struct vm_area_struct *vma, struct task_struct *t) { - return (vma->vm_start <= KSTK_ESP(t) && vma->vm_end >= KSTK_ESP(t)); -} - -/* - * Indicate if the VMA is a stack for the given task; for - * /proc/PID/maps that is the stack of the main task. - */ -static int is_stack(struct task_struct *task, - struct vm_area_struct *vma, int is_pid) { - int stack = 0; - - if (is_pid) { - stack = vma->vm_start <= vma->vm_mm->start_stack && - vma->vm_end >= vma->vm_mm->start_stack; - } else { - rcu_read_lock(); - stack = vma_is_stack_for_task(vma, task); - rcu_read_unlock(); - } - return stack; -} - - -static int get_proc_maps_list(bool is_kernel_buf, struct pid* proc_pid_struct, char* buf, size_t buf_size) { - struct task_struct *task; - struct mm_struct *mm; - struct vm_area_struct *vma; - char path_buf[MY_PATH_MAX_LEN]; - int success_cnt = 0; - size_t copy_pos; - size_t end_pos; - - task = pid_task(proc_pid_struct, PIDTYPE_PID); - if (!task) { - return -2; - } - - mm = get_task_mm(task); - - if (!mm) { - return -3; - } - - if (is_kernel_buf) { - memset(buf, 0, buf_size); - } - //else if (clear_user(buf, buf_size)) { return -4; } //清空用户的缓冲区 - - copy_pos = (size_t)buf; - end_pos = (size_t)((size_t)buf + buf_size); - - if (down_read_mmap_lock(mm) != 0) { - mmput(mm); - return -4; - } - for (vma = mm->mmap; vma; vma = vma->vm_next) { - struct map_entry entry; - struct file * vm_file; - - if (copy_pos >= end_pos) { - break; - } - entry.start = vma->vm_start; - entry.end = vma->vm_end; - entry.flags[0] = (vma->vm_flags & VM_READ) ? 1 : 0; - entry.flags[1] = (vma->vm_flags & VM_WRITE) ? 1 : 0; - entry.flags[2] = (vma->vm_flags & VM_EXEC) ? 1 : 0; - entry.flags[3] = (vma->vm_flags & VM_MAYSHARE) ? 1 : 0; - memset(entry.path, 0, sizeof(entry.path)); - vm_file = get_vm_file(vma); - if (vm_file) { - char *path; - memset(path_buf, 0, sizeof(path_buf)); - path = d_path(&vm_file->f_path, path_buf, sizeof(path_buf)); - if (path > 0) { - strncat(entry.path, path, sizeof(entry.path) - 1); - } - } else if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) { - snprintf(entry.path, sizeof(entry.path), "%s[vdso]", entry.path); - } else { - if (vma->vm_start <= mm->brk && - vma->vm_end >= mm->start_brk) { - snprintf(entry.path, sizeof(entry.path), "%s[heap]", entry.path); - } else { - pid_t tid = is_stack(task, vma, 1); - if (tid != 0) { - /* - * Thread stack in /proc/PID/task/TID/maps or - * the main process stack. - */ - - /* Thread stack in /proc/PID/maps */ - sprintf(entry.path, "[stack:%d]", tid); - } - - } - - } - if (is_kernel_buf) { - memcpy((void *)copy_pos, &entry, sizeof(entry)); - } else { - if (x_copy_to_user((void *)copy_pos, &entry, sizeof(entry))) { - break; - } - } - copy_pos += sizeof(entry); - success_cnt++; - } - up_read_mmap_lock(mm); - mmput(mm); - - return success_cnt; -} - - - -#endif - - - - -#if MY_LINUX_VERSION_CODE == KERNEL_VERSION(4,4,78) -/* Check if the vma is being used as a stack by this task */ -int vma_is_stack_for_task(struct vm_area_struct *vma, struct task_struct *t) { - return (vma->vm_start <= KSTK_ESP(t) && vma->vm_end >= KSTK_ESP(t)); -} - -/* - * Indicate if the VMA is a stack for the given task; for - * /proc/PID/maps that is the stack of the main task. - */ -static int is_stack(struct task_struct *task, - struct vm_area_struct *vma, int is_pid) { - int stack = 0; - - if (is_pid) { - stack = vma->vm_start <= vma->vm_mm->start_stack && - vma->vm_end >= vma->vm_mm->start_stack; - } else { - rcu_read_lock(); - stack = vma_is_stack_for_task(vma, task); - rcu_read_unlock(); - } - return stack; -} - - -static int get_proc_maps_list(bool is_kernel_buf, struct pid* proc_pid_struct, char* buf, size_t buf_size) { - struct task_struct *task; - struct mm_struct *mm; - struct vm_area_struct *vma; - char path_buf[MY_PATH_MAX_LEN]; - int success_cnt = 0; - size_t copy_pos; - size_t end_pos; - - task = pid_task(proc_pid_struct, PIDTYPE_PID); - if (!task) { - return -2; - } - - mm = get_task_mm(task); - - if (!mm) { - return -3; - } - - - if (is_kernel_buf) { - memset(buf, 0, buf_size); - } - //else if (clear_user(buf, buf_size)) { return -4; } //清空用户的缓冲区 - - - copy_pos = (size_t)buf; - end_pos = (size_t)((size_t)buf + buf_size); - - if (down_read_mmap_lock(mm) != 0) { - mmput(mm); - return -4; - } - for (vma = mm->mmap; vma; vma = vma->vm_next) { - struct map_entry entry; - struct file * vm_file; - if (copy_pos >= end_pos) { - break; - } - entry.start = vma->vm_start; - entry.end = vma->vm_end; - entry.flags[0] = (vma->vm_flags & VM_READ) ? 1 : 0; - entry.flags[1] = (vma->vm_flags & VM_WRITE) ? 1 : 0; - entry.flags[2] = (vma->vm_flags & VM_EXEC) ? 1 : 0; - entry.flags[3] = (vma->vm_flags & VM_MAYSHARE) ? 1 : 0; - memset(entry.path, 0, sizeof(entry.path)); - vm_file = get_vm_file(vma); - if (vm_file) { - char *path; - memset(path_buf, 0, sizeof(path_buf)); - path = d_path(&vm_file->f_path, path_buf, sizeof(path_buf)); - if (path > 0) { - strncat(entry.path, path, sizeof(entry.path) - 1); - } - } else if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) { - snprintf(entry.path, sizeof(entry.path), "%s[vdso]", entry.path); - } else { - if (vma->vm_start <= mm->brk && - vma->vm_end >= mm->start_brk) { - snprintf(entry.path, sizeof(entry.path), "%s[heap]", entry.path); - } else { - pid_t tid = is_stack(task, vma, 1); - if (tid != 0) { - /* - * Thread stack in /proc/PID/task/TID/maps or - * the main process stack. - */ - - /* Thread stack in /proc/PID/maps */ - sprintf(entry.path, "[stack:%d]", tid); - } - - } - - } - if (is_kernel_buf) { - memcpy((void *)copy_pos, &entry, sizeof(entry)); - } else { - if (x_copy_to_user((void *)copy_pos, &entry, sizeof(entry))) { - break; - } - } - copy_pos += sizeof(entry); - success_cnt++; - } - up_read_mmap_lock(mm); - mmput(mm); - - return success_cnt; -} - - -#endif - - - - -#if MY_LINUX_VERSION_CODE == KERNEL_VERSION(4,4,153) -/* - * Indicate if the VMA is a stack for the given task; for - * /proc/PID/maps that is the stack of the main task. - */ -static int is_stack(struct task_struct *task, - struct vm_area_struct *vma) { - /* - * We make no effort to guess what a given thread considers to be - * its "stack". It's not even well-defined for programs written - * languages like Go. - */ - return vma->vm_start <= vma->vm_mm->start_stack && - vma->vm_end >= vma->vm_mm->start_stack; -} - - -static int get_proc_maps_list(bool is_kernel_buf, struct pid* proc_pid_struct, char* buf, size_t buf_size) { - struct task_struct *task; - struct mm_struct *mm; - struct vm_area_struct *vma; - char path_buf[MY_PATH_MAX_LEN]; - int success_cnt = 0; - size_t copy_pos; - size_t end_pos; - - task = pid_task(proc_pid_struct, PIDTYPE_PID); - if (!task) { - return -2; - } - - mm = get_task_mm(task); - - if (!mm) { - return -3; - } - - if (is_kernel_buf) { - memset(buf, 0, buf_size); - } - //else if (clear_user(buf, buf_size)) { return -4; } //清空用户的缓冲区 - - copy_pos = (size_t)buf; - end_pos = (size_t)((size_t)buf + buf_size); - - if (down_read_mmap_lock(mm) != 0) { - mmput(mm); - return -4; - } - for (vma = mm->mmap; vma; vma = vma->vm_next) { - struct map_entry entry; - struct file * vm_file; - if (copy_pos >= end_pos) { - break; - } - entry.start = vma->vm_start; - entry.end = vma->vm_end; - entry.flags[0] = (vma->vm_flags & VM_READ) ? 1 : 0; - entry.flags[1] = (vma->vm_flags & VM_WRITE) ? 1 : 0; - entry.flags[2] = (vma->vm_flags & VM_EXEC) ? 1 : 0; - entry.flags[3] = (vma->vm_flags & VM_MAYSHARE) ? 1 : 0; - memset(entry.path, 0, sizeof(entry.path)); - vm_file = get_vm_file(vma); - if (vm_file) { - char *path; - memset(path_buf, 0, sizeof(path_buf)); - path = d_path(&vm_file->f_path, path_buf, sizeof(path_buf)); - if (path > 0) { - strncat(entry.path, path, sizeof(entry.path) - 1); - } - } else if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) { - snprintf(entry.path, sizeof(entry.path), "%s[vdso]", entry.path); - } else { - if (vma->vm_start <= mm->brk && - vma->vm_end >= mm->start_brk) { - snprintf(entry.path, sizeof(entry.path), "%s[heap]", entry.path); - } else { - pid_t tid = is_stack(task, vma); - if (tid != 0) { - /* - * Thread stack in /proc/PID/task/TID/maps or - * the main process stack. - */ - - /* Thread stack in /proc/PID/maps */ - snprintf(entry.path, sizeof(entry.path), "%s[stack]", entry.path); - } - - } - - } - if (is_kernel_buf) { - memcpy((void *)copy_pos, &entry, sizeof(entry)); - } else { - if (x_copy_to_user((void *)copy_pos, &entry, sizeof(entry))) { - break; - } - } - copy_pos += sizeof(entry); - success_cnt++; - } - up_read_mmap_lock(mm); - mmput(mm); - - return success_cnt; -} - -#endif - - - -#if MY_LINUX_VERSION_CODE == KERNEL_VERSION(4,4,192) -/* - * Indicate if the VMA is a stack for the given task; for - * /proc/PID/maps that is the stack of the main task. - */ -static int is_stack(struct task_struct *task, - struct vm_area_struct *vma) { - /* - * We make no effort to guess what a given thread considers to be - * its "stack". It's not even well-defined for programs written - * languages like Go. - */ - return vma->vm_start <= vma->vm_mm->start_stack && - vma->vm_end >= vma->vm_mm->start_stack; -} - - -static int get_proc_maps_list(bool is_kernel_buf, struct pid* proc_pid_struct, char* buf, size_t buf_size) { - struct task_struct *task; - struct mm_struct *mm; - struct vm_area_struct *vma; - char path_buf[MY_PATH_MAX_LEN]; - int success_cnt = 0; - size_t copy_pos; - size_t end_pos; - - task = pid_task(proc_pid_struct, PIDTYPE_PID); - if (!task) { - return -2; - } - - mm = get_task_mm(task); - - if (!mm) { - return -3; - } - - if (is_kernel_buf) { - memset(buf, 0, buf_size); - } - //else if (clear_user(buf, buf_size)) { return -4; } //清空用户的缓冲区 - - - copy_pos = (size_t)buf; - end_pos = (size_t)((size_t)buf + buf_size); - - if (down_read_mmap_lock(mm) != 0) { - mmput(mm); - return -4; - } - for (vma = mm->mmap; vma; vma = vma->vm_next) { - struct map_entry entry; - struct file * vm_file; - if (copy_pos >= end_pos) { - break; - } - entry.start = vma->vm_start; - entry.end = vma->vm_end; - entry.flags[0] = (vma->vm_flags & VM_READ) ? 1 : 0; - entry.flags[1] = (vma->vm_flags & VM_WRITE) ? 1 : 0; - entry.flags[2] = (vma->vm_flags & VM_EXEC) ? 1 : 0; - entry.flags[3] = (vma->vm_flags & VM_MAYSHARE) ? 1 : 0; - memset(entry.path, 0, sizeof(entry.path)); - vm_file = get_vm_file(vma); - if (vm_file) { - char *path; - memset(path_buf, 0, sizeof(path_buf)); - path = d_path(&vm_file->f_path, path_buf, sizeof(path_buf)); - if (path > 0) { - strncat(entry.path, path, sizeof(entry.path) - 1); - } - - } else if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) { - snprintf(entry.path, sizeof(entry.path), "%s[vdso]", entry.path); - } else { - if (vma->vm_start <= mm->brk && - vma->vm_end >= mm->start_brk) { - snprintf(entry.path, sizeof(entry.path), "%s[heap]", entry.path); - } else { - pid_t tid = is_stack(task, vma); - if (tid != 0) { - /* - * Thread stack in /proc/PID/task/TID/maps or - * the main process stack. - */ - - /* Thread stack in /proc/PID/maps */ - snprintf(entry.path, sizeof(entry.path), "%s[stack]", entry.path); - } - - } - - } - if (is_kernel_buf) { - memcpy((void *)copy_pos, &entry, sizeof(entry)); - } else { - if (x_copy_to_user((void *)copy_pos, &entry, sizeof(entry))) { - break; - } - } - copy_pos += sizeof(entry); - success_cnt++; - } - up_read_mmap_lock(mm); - mmput(mm); - - return success_cnt; -} - - -#endif - - - -#if MY_LINUX_VERSION_CODE == KERNEL_VERSION(4,9,112) -/* - * Indicate if the VMA is a stack for the given task; for - * /proc/PID/maps that is the stack of the main task. - */ -static int is_stack(struct vm_area_struct *vma) { - /* - * We make no effort to guess what a given thread considers to be - * its "stack". It's not even well-defined for programs written - * languages like Go. - */ - return vma->vm_start <= vma->vm_mm->start_stack && - vma->vm_end >= vma->vm_mm->start_stack; -} - - - -static int get_proc_maps_list(bool is_kernel_buf, struct pid* proc_pid_struct, char* buf, size_t buf_size) { - struct task_struct *task; - struct mm_struct *mm; - struct vm_area_struct *vma; - char path_buf[MY_PATH_MAX_LEN]; - int success_cnt = 0; - size_t copy_pos; - size_t end_pos; - task = pid_task(proc_pid_struct, PIDTYPE_PID); - if (!task) { - return -2; - } - - mm = get_task_mm(task); - - if (!mm) { - return -3; - } - - if (is_kernel_buf) { - memset(buf, 0, buf_size); - } - //else if (clear_user(buf, buf_size)) { return -4; } //清空用户的缓冲区 - - copy_pos = (size_t)buf; - end_pos = (size_t)((size_t)buf + buf_size); - - if (down_read_mmap_lock(mm) != 0) { - mmput(mm); - return -4; - } - for (vma = mm->mmap; vma; vma = vma->vm_next) { - struct map_entry entry; - struct file * vm_file; - if (copy_pos >= end_pos) { - break; - } - entry.start = vma->vm_start; - entry.end = vma->vm_end; - entry.flags[0] = (vma->vm_flags & VM_READ) ? 1 : 0; - entry.flags[1] = (vma->vm_flags & VM_WRITE) ? 1 : 0; - entry.flags[2] = (vma->vm_flags & VM_EXEC) ? 1 : 0; - entry.flags[3] = (vma->vm_flags & VM_MAYSHARE) ? 1 : 0; - memset(entry.path, 0, sizeof(entry.path)); - vm_file = get_vm_file(vma); - if (vm_file) { - char *path; - memset(path_buf, 0, sizeof(path_buf)); - path = d_path(&vm_file->f_path, path_buf, sizeof(path_buf)); - if (path > 0) { - strncat(entry.path, path, sizeof(entry.path) - 1); - } - } else if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) { - snprintf(entry.path, sizeof(entry.path), "%s[vdso]", entry.path); - } else { - if (vma->vm_start <= mm->brk && - vma->vm_end >= mm->start_brk) { - snprintf(entry.path, sizeof(entry.path), "%s[heap]", entry.path); - } else { - if (is_stack(vma)) { - /* - * Thread stack in /proc/PID/task/TID/maps or - * the main process stack. - */ - - /* Thread stack in /proc/PID/maps */ - snprintf(entry.path, sizeof(entry.path), "%s[stack]", entry.path); - } - - } - - } - if (is_kernel_buf) { - memcpy((void *)copy_pos, &entry, sizeof(entry)); - } else { - if (x_copy_to_user((void *)copy_pos, &entry, sizeof(entry))) { - break; - } - } - copy_pos += sizeof(entry); - success_cnt++; - } - up_read_mmap_lock(mm); - mmput(mm); - - return success_cnt; -} - -#endif - - - -#if MY_LINUX_VERSION_CODE == KERNEL_VERSION(4,9,186) -/* - * Indicate if the VMA is a stack for the given task; for - * /proc/PID/maps that is the stack of the main task. - */ -static int is_stack(struct vm_area_struct *vma) { - /* - * We make no effort to guess what a given thread considers to be - * its "stack". It's not even well-defined for programs written - * languages like Go. - */ - return vma->vm_start <= vma->vm_mm->start_stack && - vma->vm_end >= vma->vm_mm->start_stack; -} - - - -static int get_proc_maps_list(bool is_kernel_buf, struct pid* proc_pid_struct, char* buf, size_t buf_size) { - struct task_struct *task; - struct mm_struct *mm; - struct vm_area_struct *vma; - char path_buf[MY_PATH_MAX_LEN]; - int success_cnt = 0; - size_t copy_pos; - size_t end_pos; - - task = pid_task(proc_pid_struct, PIDTYPE_PID); - if (!task) { - return -2; - } - - mm = get_task_mm(task); - - if (!mm) { - return -3; - } - - if (is_kernel_buf) { - memset(buf, 0, buf_size); - } - //else if (clear_user(buf, buf_size)) { return -4; } //清空用户的缓冲区 - - - copy_pos = (size_t)buf; - end_pos = (size_t)((size_t)buf + buf_size); - - if (down_read_mmap_lock(mm) != 0) { - mmput(mm); - return -4; - } - for (vma = mm->mmap; vma; vma = vma->vm_next) { - struct map_entry entry; - struct file * vm_file; - if (copy_pos >= end_pos) { - break; - } - entry.start = vma->vm_start; - entry.end = vma->vm_end; - entry.flags[0] = (vma->vm_flags & VM_READ) ? 1 : 0; - entry.flags[1] = (vma->vm_flags & VM_WRITE) ? 1 : 0; - entry.flags[2] = (vma->vm_flags & VM_EXEC) ? 1 : 0; - entry.flags[3] = (vma->vm_flags & VM_MAYSHARE) ? 1 : 0; - memset(entry.path, 0, sizeof(entry.path)); - vm_file = get_vm_file(vma); - if (vm_file) { - char *path; - memset(path_buf, 0, sizeof(path_buf)); - path = d_path(&vm_file->f_path, path_buf, sizeof(path_buf)); - if (path > 0) { - strncat(entry.path, path, sizeof(entry.path) - 1); - } - } else if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) { - snprintf(entry.path, sizeof(entry.path), "%s[vdso]", entry.path); - } else { - if (vma->vm_start <= mm->brk && - vma->vm_end >= mm->start_brk) { - snprintf(entry.path, sizeof(entry.path), "%s[heap]", entry.path); - } else { - if (is_stack(vma)) { - /* - * Thread stack in /proc/PID/task/TID/maps or - * the main process stack. - */ - - /* Thread stack in /proc/PID/maps */ - snprintf(entry.path, sizeof(entry.path), "%s[stack]", entry.path); - } - - } - - } - if (is_kernel_buf) { - memcpy((void *)copy_pos, &entry, sizeof(entry)); - } else { - if (x_copy_to_user((void *)copy_pos, &entry, sizeof(entry))) { - break; - } - } - copy_pos += sizeof(entry); - success_cnt++; - } - up_read_mmap_lock(mm); - mmput(mm); - - return success_cnt; -} - - -#endif - - - - - - -#if MY_LINUX_VERSION_CODE == KERNEL_VERSION(4,14,83) - - -/* - * Indicate if the VMA is a stack for the given task; for - * /proc/PID/maps that is the stack of the main task. - */ -static int is_stack(struct vm_area_struct *vma) { - /* - * We make no effort to guess what a given thread considers to be - * its "stack". It's not even well-defined for programs written - * languages like Go. - */ - return vma->vm_start <= vma->vm_mm->start_stack && - vma->vm_end >= vma->vm_mm->start_stack; -} - -static int get_proc_maps_list(bool is_kernel_buf, struct pid* proc_pid_struct, char* buf, size_t buf_size) { - struct task_struct *task; - struct mm_struct *mm; - struct vm_area_struct *vma; - char path_buf[MY_PATH_MAX_LEN]; - int success_cnt = 0; - size_t copy_pos; - size_t end_pos; - - task = pid_task(proc_pid_struct, PIDTYPE_PID); - if (!task) { - return -2; - } - - mm = get_task_mm(task); - - if (!mm) { - return -3; - } - if (is_kernel_buf) { - memset(buf, 0, buf_size); - } - //else if (clear_user(buf, buf_size)) { return -4; } //清空用户的缓冲区 - - copy_pos = (size_t)buf; - end_pos = (size_t)((size_t)buf + buf_size); - - if (down_read_mmap_lock(mm) != 0) { - mmput(mm); - return -4; - } - for (vma = mm->mmap; vma; vma = vma->vm_next) { - struct map_entry entry; - struct file * vm_file; - if (copy_pos >= end_pos) { - break; - } - entry.start = vma->vm_start; - entry.end = vma->vm_end; - entry.flags[0] = (vma->vm_flags & VM_READ) ? 1 : 0; - entry.flags[1] = (vma->vm_flags & VM_WRITE) ? 1 : 0; - entry.flags[2] = (vma->vm_flags & VM_EXEC) ? 1 : 0; - entry.flags[3] = (vma->vm_flags & VM_MAYSHARE) ? 1 : 0; - memset(entry.path, 0, sizeof(entry.path)); - vm_file = get_vm_file(vma); - if (vm_file) { - char *path; - memset(path_buf, 0, sizeof(path_buf)); - path = d_path(&vm_file->f_path, path_buf, sizeof(path_buf)); - if (path > 0) { - strncat(entry.path, path, sizeof(entry.path) - 1); - } - } else if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) { - snprintf(entry.path, sizeof(entry.path), "%s[vdso]", entry.path); - } else { - if (vma->vm_start <= mm->brk && - vma->vm_end >= mm->start_brk) { - snprintf(entry.path, sizeof(entry.path), "%s[heap]", entry.path); - } else { - if (is_stack(vma)) { - /* - * Thread stack in /proc/PID/task/TID/maps or - * the main process stack. - */ - - /* Thread stack in /proc/PID/maps */ - snprintf(entry.path, sizeof(entry.path), "%s[stack]", entry.path); - } - - } - - } - if (is_kernel_buf) { - memcpy((void *)copy_pos, &entry, sizeof(entry)); - } else { - if (x_copy_to_user((void *)copy_pos, &entry, sizeof(entry))) { - break; - } - } - copy_pos += sizeof(entry); - success_cnt++; - } - up_read_mmap_lock(mm); - mmput(mm); - - return success_cnt; -} - - -#endif - - - -#if MY_LINUX_VERSION_CODE == KERNEL_VERSION(4,14,117) - - -/* - * Indicate if the VMA is a stack for the given task; for - * /proc/PID/maps that is the stack of the main task. - */ -static int is_stack(struct vm_area_struct *vma) { - /* - * We make no effort to guess what a given thread considers to be - * its "stack". It's not even well-defined for programs written - * languages like Go. - */ - return vma->vm_start <= vma->vm_mm->start_stack && - vma->vm_end >= vma->vm_mm->start_stack; -} - -static int get_proc_maps_list(bool is_kernel_buf, struct pid* proc_pid_struct, char* buf, size_t buf_size) { - struct task_struct *task; - struct mm_struct *mm; - struct vm_area_struct *vma; - char path_buf[MY_PATH_MAX_LEN]; - int success_cnt = 0; - size_t copy_pos; - size_t end_pos; - - task = pid_task(proc_pid_struct, PIDTYPE_PID); - if (!task) { - return -2; - } - - mm = get_task_mm(task); - - if (!mm) { - return -3; - } - - - if (is_kernel_buf) { - memset(buf, 0, buf_size); - } - //else if (clear_user(buf, buf_size)) { return -4; } //清空用户的缓冲区 - - copy_pos = (size_t)buf; - end_pos = (size_t)((size_t)buf + buf_size); - - if (down_read_mmap_lock(mm) != 0) { - mmput(mm); - return -4; - } - for (vma = mm->mmap; vma; vma = vma->vm_next) { - struct map_entry entry; - struct file * vm_file; - if (copy_pos >= end_pos) { - break; - } - entry.start = vma->vm_start; - entry.end = vma->vm_end; - entry.flags[0] = (vma->vm_flags & VM_READ) ? 1 : 0; - entry.flags[1] = (vma->vm_flags & VM_WRITE) ? 1 : 0; - entry.flags[2] = (vma->vm_flags & VM_EXEC) ? 1 : 0; - entry.flags[3] = (vma->vm_flags & VM_MAYSHARE) ? 1 : 0; - memset(entry.path, 0, sizeof(entry.path)); - vm_file = get_vm_file(vma); - if (vm_file) { - char *path; - memset(path_buf, 0, sizeof(path_buf)); - path = d_path(&vm_file->f_path, path_buf, sizeof(path_buf)); - if (path > 0) { - strncat(entry.path, path, sizeof(entry.path) - 1); - } - } else if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) { - snprintf(entry.path, sizeof(entry.path), "%s[vdso]", entry.path); - } else { - if (vma->vm_start <= mm->brk && - vma->vm_end >= mm->start_brk) { - snprintf(entry.path, sizeof(entry.path), "%s[heap]", entry.path); - } else { - if (is_stack(vma)) { - /* - * Thread stack in /proc/PID/task/TID/maps or - * the main process stack. - */ - - /* Thread stack in /proc/PID/maps */ - snprintf(entry.path, sizeof(entry.path), "%s[stack]", entry.path); - } - - } - - } - - if (is_kernel_buf) { - memcpy((void *)copy_pos, &entry, sizeof(entry)); - } else { - if (x_copy_to_user((void *)copy_pos, &entry, sizeof(entry))) { - break; - } - } - copy_pos += sizeof(entry); - success_cnt++; - } - up_read_mmap_lock(mm); - mmput(mm); - - return success_cnt; -} - - - -#endif - - - -#if MY_LINUX_VERSION_CODE == KERNEL_VERSION(4,14,141) - - -/* - * Indicate if the VMA is a stack for the given task; for - * /proc/PID/maps that is the stack of the main task. - */ -static int is_stack(struct vm_area_struct *vma) { - /* - * We make no effort to guess what a given thread considers to be - * its "stack". It's not even well-defined for programs written - * languages like Go. - */ - return vma->vm_start <= vma->vm_mm->start_stack && - vma->vm_end >= vma->vm_mm->start_stack; -} - -static int get_proc_maps_list(bool is_kernel_buf, struct pid* proc_pid_struct, char* buf, size_t buf_size) { - struct task_struct *task; - struct mm_struct *mm; - struct vm_area_struct *vma; - char path_buf[MY_PATH_MAX_LEN]; - int success_cnt = 0; - size_t copy_pos; - size_t end_pos; - - task = pid_task(proc_pid_struct, PIDTYPE_PID); - if (!task) { - return -2; - } - - mm = get_task_mm(task); - - if (!mm) { - return -3; - } - if (is_kernel_buf) { - memset(buf, 0, buf_size); - } - //else if (clear_user(buf, buf_size)) { return -4; } //清空用户的缓冲区 - - copy_pos = (size_t)buf; - end_pos = (size_t)((size_t)buf + buf_size); - - if (down_read_mmap_lock(mm) != 0) { - mmput(mm); - return -4; - } - for (vma = mm->mmap; vma; vma = vma->vm_next) { - struct map_entry entry; - struct file * vm_file; - if (copy_pos >= end_pos) { - break; - } - entry.start = vma->vm_start; - entry.end = vma->vm_end; - entry.flags[0] = (vma->vm_flags & VM_READ) ? 1 : 0; - entry.flags[1] = (vma->vm_flags & VM_WRITE) ? 1 : 0; - entry.flags[2] = (vma->vm_flags & VM_EXEC) ? 1 : 0; - entry.flags[3] = (vma->vm_flags & VM_MAYSHARE) ? 1 : 0; - memset(entry.path, 0, sizeof(entry.path)); - vm_file = get_vm_file(vma); - if (vm_file) { - char *path; - memset(path_buf, 0, sizeof(path_buf)); - path = d_path(&vm_file->f_path, path_buf, sizeof(path_buf)); - if (path > 0) { - strncat(entry.path, path, sizeof(entry.path) - 1); - } - } else if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) { - snprintf(entry.path, sizeof(entry.path), "%s[vdso]", entry.path); - } else { - if (vma->vm_start <= mm->brk && - vma->vm_end >= mm->start_brk) { - snprintf(entry.path, sizeof(entry.path), "%s[heap]", entry.path); - } else { - if (is_stack(vma)) { - /* - * Thread stack in /proc/PID/task/TID/maps or - * the main process stack. - */ - - /* Thread stack in /proc/PID/maps */ - snprintf(entry.path, sizeof(entry.path), "%s[stack]", entry.path); - } - - } - - } - if (is_kernel_buf) { - memcpy((void *)copy_pos, &entry, sizeof(entry)); - } else { - if (x_copy_to_user((void *)copy_pos, &entry, sizeof(entry))) { - break; - } - } - copy_pos += sizeof(entry); - success_cnt++; - } - up_read_mmap_lock(mm); - mmput(mm); - - return success_cnt; -} - - -#endif - - - - - -#if MY_LINUX_VERSION_CODE == KERNEL_VERSION(4,19,81) - - -/* - * Indicate if the VMA is a stack for the given task; for - * /proc/PID/maps that is the stack of the main task. - */ -static int is_stack(struct vm_area_struct *vma) { - /* - * We make no effort to guess what a given thread considers to be - * its "stack". It's not even well-defined for programs written - * languages like Go. - */ - return vma->vm_start <= vma->vm_mm->start_stack && - vma->vm_end >= vma->vm_mm->start_stack; -} - -static int get_proc_maps_list(bool is_kernel_buf, struct pid* proc_pid_struct, char* buf, size_t buf_size) { - struct task_struct *task; - struct mm_struct *mm; - struct vm_area_struct *vma; - char path_buf[MY_PATH_MAX_LEN]; - int success_cnt = 0; - size_t copy_pos; - size_t end_pos; - - - task = pid_task(proc_pid_struct, PIDTYPE_PID); - if (!task) { - return -2; - } - - mm = get_task_mm(task); - - if (!mm) { - return -3; - } - if (is_kernel_buf) { - memset(buf, 0, buf_size); - } - //else if (clear_user(buf, buf_size)) { return -4; } //清空用户的缓冲区 - - copy_pos = (size_t)buf; - end_pos = (size_t)((size_t)buf + buf_size); - - if (down_read_mmap_lock(mm) != 0) { - mmput(mm); - return -4; - } - for (vma = mm->mmap; vma; vma = vma->vm_next) { - struct map_entry entry; - struct file * vm_file; - - if (copy_pos >= end_pos) { - break; - } - entry.start = vma->vm_start; - entry.end = vma->vm_end; - entry.flags[0] = (vma->vm_flags & VM_READ) ? 1 : 0; - entry.flags[1] = (vma->vm_flags & VM_WRITE) ? 1 : 0; - entry.flags[2] = (vma->vm_flags & VM_EXEC) ? 1 : 0; - entry.flags[3] = (vma->vm_flags & VM_MAYSHARE) ? 1 : 0; - memset(entry.path, 0, sizeof(entry.path)); - vm_file = get_vm_file(vma); - if (vm_file) { - char *path; - memset(path_buf, 0, sizeof(path_buf)); - path = d_path(&vm_file->f_path, path_buf, sizeof(path_buf)); - if (path > 0) { - strncat(entry.path, path, sizeof(entry.path) - 1); - } - } else if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) { - snprintf(entry.path, sizeof(entry.path), "%s[vdso]", entry.path); - } else { - if (vma->vm_start <= mm->brk && - vma->vm_end >= mm->start_brk) { - snprintf(entry.path, sizeof(entry.path), "%s[heap]", entry.path); - } else { - if (is_stack(vma)) { - /* - * Thread stack in /proc/PID/task/TID/maps or - * the main process stack. - */ - - /* Thread stack in /proc/PID/maps */ - snprintf(entry.path, sizeof(entry.path), "%s[stack]", entry.path); - } - - } - - } - if (is_kernel_buf) { - memcpy((void *)copy_pos, &entry, sizeof(entry)); - } else { - if (x_copy_to_user((void *)copy_pos, &entry, sizeof(entry))) { - break; - } - } - copy_pos += sizeof(entry); - success_cnt++; - } - up_read_mmap_lock(mm); - mmput(mm); - - return success_cnt; -} -#endif - - - - - - -#if MY_LINUX_VERSION_CODE == KERNEL_VERSION(4,19,113) - -/* - * Indicate if the VMA is a stack for the given task; for - * /proc/PID/maps that is the stack of the main task. - */ -static int is_stack(struct vm_area_struct *vma) { - /* - * We make no effort to guess what a given thread considers to be - * its "stack". It's not even well-defined for programs written - * languages like Go. - */ - return vma->vm_start <= vma->vm_mm->start_stack && - vma->vm_end >= vma->vm_mm->start_stack; -} - -static int get_proc_maps_list(bool is_kernel_buf, struct pid* proc_pid_struct, char* buf, size_t buf_size) { - struct task_struct *task; - struct mm_struct *mm; - struct vm_area_struct *vma; - char path_buf[MY_PATH_MAX_LEN]; - int success_cnt = 0; - size_t copy_pos; - size_t end_pos; - - task = pid_task(proc_pid_struct, PIDTYPE_PID); - if (!task) { - return -2; - } - - mm = get_task_mm(task); - - if (!mm) { - return -3; - } - if (is_kernel_buf) { - memset(buf, 0, buf_size); - } - //else if (clear_user(buf, buf_size)) { return -4; } //清空用户的缓冲区 - - copy_pos = (size_t)buf; - end_pos = (size_t)((size_t)buf + buf_size); - - if (down_read_mmap_lock(mm) != 0) { - mmput(mm); - return -4; - } - for (vma = mm->mmap; vma; vma = vma->vm_next) { - struct map_entry entry; - struct file * vm_file; - if (copy_pos >= end_pos) { - break; - } - entry.start = vma->vm_start; - entry.end = vma->vm_end; - entry.flags[0] = (vma->vm_flags & VM_READ) ? 1 : 0; - entry.flags[1] = (vma->vm_flags & VM_WRITE) ? 1 : 0; - entry.flags[2] = (vma->vm_flags & VM_EXEC) ? 1 : 0; - entry.flags[3] = (vma->vm_flags & VM_MAYSHARE) ? 1 : 0; - memset(entry.path, 0, sizeof(entry.path)); - vm_file = get_vm_file(vma); - if (vm_file) { - char *path; - memset(path_buf, 0, sizeof(path_buf)); - path = d_path(&vm_file->f_path, path_buf, sizeof(path_buf)); - if (path > 0) { - strncat(entry.path, path, sizeof(entry.path) - 1); - } - } else if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) { - snprintf(entry.path, sizeof(entry.path), "%s[vdso]", entry.path); - } else { - if (vma->vm_start <= mm->brk && - vma->vm_end >= mm->start_brk) { - snprintf(entry.path, sizeof(entry.path), "%s[heap]", entry.path); - } else { - if (is_stack(vma)) { - /* - * Thread stack in /proc/PID/task/TID/maps or - * the main process stack. - */ - - /* Thread stack in /proc/PID/maps */ - snprintf(entry.path, sizeof(entry.path), "%s[stack]", entry.path); - } - - } - - } - if (is_kernel_buf) { - memcpy((void *)copy_pos, &entry, sizeof(entry)); - } else { - if (x_copy_to_user((void *)copy_pos, &entry, sizeof(entry))) { - break; - } - } - copy_pos += sizeof(entry); - success_cnt++; - } - up_read_mmap_lock(mm); - mmput(mm); - - return success_cnt; -} -#endif - -#if MY_LINUX_VERSION_CODE == KERNEL_VERSION(5,4,61) - -/* - * Indicate if the VMA is a stack for the given task; for - * /proc/PID/maps that is the stack of the main task. - */ -static int is_stack(struct vm_area_struct *vma) { - /* - * We make no effort to guess what a given thread considers to be - * its "stack". It's not even well-defined for programs written - * languages like Go. - */ - return vma->vm_start <= vma->vm_mm->start_stack && - vma->vm_end >= vma->vm_mm->start_stack; -} - -static int get_proc_maps_list(bool is_kernel_buf, struct pid* proc_pid_struct, char* buf, size_t buf_size) { - struct task_struct *task; - struct mm_struct *mm; - struct vm_area_struct *vma; - char path_buf[MY_PATH_MAX_LEN]; - int success_cnt = 0; - size_t copy_pos; - size_t end_pos; - - task = pid_task(proc_pid_struct, PIDTYPE_PID); - if (!task) { - return -2; - } - - mm = get_task_mm(task); - - if (!mm) { - return -3; - } - if (is_kernel_buf) { - memset(buf, 0, buf_size); - } - //else if (clear_user(buf, buf_size)) { return -4; } //清空用户的缓冲区 - - copy_pos = (size_t)buf; - end_pos = (size_t)((size_t)buf + buf_size); - - if (down_read_mmap_lock(mm) != 0) { - mmput(mm); - return -4; - } - for (vma = mm->mmap; vma; vma = vma->vm_next) { - struct map_entry entry; - struct file * vm_file; - if (copy_pos >= end_pos) { - break; - } - entry.start = vma->vm_start; - entry.end = vma->vm_end; - entry.flags[0] = (vma->vm_flags & VM_READ) ? 1 : 0; - entry.flags[1] = (vma->vm_flags & VM_WRITE) ? 1 : 0; - entry.flags[2] = (vma->vm_flags & VM_EXEC) ? 1 : 0; - entry.flags[3] = (vma->vm_flags & VM_MAYSHARE) ? 1 : 0; - memset(entry.path, 0, sizeof(entry.path)); - vm_file = get_vm_file(vma); - if (vm_file) { - char *path; - memset(path_buf, 0, sizeof(path_buf)); - path = d_path(&vm_file->f_path, path_buf, sizeof(path_buf)); - if (path > 0) { - strncat(entry.path, path, sizeof(entry.path) - 1); - } - } else if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) { - snprintf(entry.path, sizeof(entry.path), "%s[vdso]", entry.path); - } else { - if (vma->vm_start <= mm->brk && - vma->vm_end >= mm->start_brk) { - snprintf(entry.path, sizeof(entry.path), "%s[heap]", entry.path); - } else { - if (is_stack(vma)) { - /* - * Thread stack in /proc/PID/task/TID/maps or - * the main process stack. - */ - - /* Thread stack in /proc/PID/maps */ - snprintf(entry.path, sizeof(entry.path), "%s[stack]", entry.path); - } - - } - - } - if (is_kernel_buf) { - memcpy((void *)copy_pos, &entry, sizeof(entry)); - } else { - if (x_copy_to_user((void *)copy_pos, &entry, sizeof(entry))) { - break; - } - } - copy_pos += sizeof(entry); - success_cnt++; - } - up_read_mmap_lock(mm); - mmput(mm); - - return success_cnt; -} -#endif - -#if MY_LINUX_VERSION_CODE == KERNEL_VERSION(5,10,43) - -/* - * Indicate if the VMA is a stack for the given task; for - * /proc/PID/maps that is the stack of the main task. - */ -static int is_stack(struct vm_area_struct* vma) { - /* - * We make no effort to guess what a given thread considers to be - * its "stack". It's not even well-defined for programs written - * languages like Go. - */ - return vma->vm_start <= vma->vm_mm->start_stack && - vma->vm_end >= vma->vm_mm->start_stack; -} - -static int get_proc_maps_list(bool is_kernel_buf, struct pid* proc_pid_struct, char* buf, size_t buf_size) { - struct task_struct* task; - struct mm_struct* mm; - struct vm_area_struct* vma; - char path_buf[MY_PATH_MAX_LEN]; - int success_cnt = 0; - size_t copy_pos; - size_t end_pos; - - - task = pid_task(proc_pid_struct, PIDTYPE_PID); - if (!task) { - return -2; - } - - mm = get_task_mm(task); - - if (!mm) { - return -3; - } - if (is_kernel_buf) { - memset(buf, 0, buf_size); - } - //else if (clear_user(buf, buf_size)) { return -4; } //清空用户的缓冲区 - - copy_pos = (size_t)buf; - end_pos = (size_t)((size_t)buf + buf_size); - - if (down_read_mmap_lock(mm) != 0) { - mmput(mm); - return -4; - } - for (vma = mm->mmap; vma; vma = vma->vm_next) { - struct map_entry entry; - struct file* vm_file; - if (copy_pos >= end_pos) { - break; - } - entry.start = vma->vm_start; - entry.end = vma->vm_end; - entry.flags[0] = (vma->vm_flags & VM_READ) ? 1 : 0; - entry.flags[1] = (vma->vm_flags & VM_WRITE) ? 1 : 0; - entry.flags[2] = (vma->vm_flags & VM_EXEC) ? 1 : 0; - entry.flags[3] = (vma->vm_flags & VM_MAYSHARE) ? 1 : 0; - memset(entry.path, 0, sizeof(entry.path)); - vm_file = get_vm_file(vma); - if (vm_file) { - char* path; - memset(path_buf, 0, sizeof(path_buf)); - path = d_path(&vm_file->f_path, path_buf, sizeof(path_buf)); - if (path > 0) { - strncat(entry.path, path, sizeof(entry.path) - 1); - } - } else if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) { - snprintf(entry.path, sizeof(entry.path), "%s[vdso]", entry.path); - } else { - if (vma->vm_start <= mm->brk && - vma->vm_end >= mm->start_brk) { - snprintf(entry.path, sizeof(entry.path), "%s[heap]", entry.path); - } else { - if (is_stack(vma)) { - /* - * Thread stack in /proc/PID/task/TID/maps or - * the main process stack. - */ - - /* Thread stack in /proc/PID/maps */ - snprintf(entry.path, sizeof(entry.path), "%s[stack]", entry.path); - } - - } - - } - if (is_kernel_buf) { - memcpy((void *)copy_pos, &entry, sizeof(entry)); - } else { - if (x_copy_to_user((void *)copy_pos, &entry, sizeof(entry))) { - break; - } - } - copy_pos += sizeof(entry); - success_cnt++; - } - up_read_mmap_lock(mm); - mmput(mm); - - return success_cnt; -} -#endif - -#if MY_LINUX_VERSION_CODE == KERNEL_VERSION(5,15,41) - -/* - * Indicate if the VMA is a stack for the given task; for - * /proc/PID/maps that is the stack of the main task. - */ -static int is_stack(struct vm_area_struct* vma) { - /* - * We make no effort to guess what a given thread considers to be - * its "stack". It's not even well-defined for programs written - * languages like Go. - */ - return vma->vm_start <= vma->vm_mm->start_stack && - vma->vm_end >= vma->vm_mm->start_stack; -} - -static int get_proc_maps_list(bool is_kernel_buf, struct pid* proc_pid_struct, char* buf, size_t buf_size) { - struct task_struct* task; - struct mm_struct* mm; - struct vm_area_struct* vma; - char path_buf[MY_PATH_MAX_LEN]; - int success_cnt = 0; - size_t copy_pos; - size_t end_pos; - - task = pid_task(proc_pid_struct, PIDTYPE_PID); - if (!task) { - return -2; - } - - mm = get_task_mm(task); - - if (!mm) { - return -3; - } - if (is_kernel_buf) { - memset(buf, 0, buf_size); - } - //else if (clear_user(buf, buf_size)) { return -4; } //清空用户的缓冲区 - - copy_pos = (size_t)buf; - end_pos = (size_t)((size_t)buf + buf_size); - - if (down_read_mmap_lock(mm) != 0) { - mmput(mm); - return -4; - } - for (vma = mm->mmap; vma; vma = vma->vm_next) { - struct map_entry entry; - struct file* vm_file; - if (copy_pos >= end_pos) { - break; - } - entry.start = vma->vm_start; - entry.end = vma->vm_end; - entry.flags[0] = (vma->vm_flags & VM_READ) ? 1 : 0; - entry.flags[1] = (vma->vm_flags & VM_WRITE) ? 1 : 0; - entry.flags[2] = (vma->vm_flags & VM_EXEC) ? 1 : 0; - entry.flags[3] = (vma->vm_flags & VM_MAYSHARE) ? 1 : 0; - memset(entry.path, 0, sizeof(entry.path)); - vm_file = get_vm_file(vma); - if (vm_file) { - char* path; - memset(path_buf, 0, sizeof(path_buf)); - path = d_path(&vm_file->f_path, path_buf, sizeof(path_buf)); - if (path > 0) { - strncat(entry.path, path, sizeof(entry.path) - 1); - } - } else if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) { - snprintf(entry.path, sizeof(entry.path), "%s[vdso]", entry.path); - } else { - if (vma->vm_start <= mm->brk && - vma->vm_end >= mm->start_brk) { - snprintf(entry.path, sizeof(entry.path), "%s[heap]", entry.path); - } else { - if (is_stack(vma)) { - /* - * Thread stack in /proc/PID/task/TID/maps or - * the main process stack. - */ - - /* Thread stack in /proc/PID/maps */ - snprintf(entry.path, sizeof(entry.path), "%s[stack]", entry.path); - } - - } - - } - if (is_kernel_buf) { - memcpy((void *)copy_pos, &entry, sizeof(entry)); - } else { - if (x_copy_to_user((void *)copy_pos, &entry, sizeof(entry))) { - break; - } - } - copy_pos += sizeof(entry); - success_cnt++; - } - up_read_mmap_lock(mm); - mmput(mm); - - return success_cnt; -} -#endif - -#if MY_LINUX_VERSION_CODE == KERNEL_VERSION(6,1,75) -#include -struct anon_vma_name * __weak anon_vma_name(struct vm_area_struct* vma) { - return NULL; -} - -/* - * Indicate if the VMA is a stack for the given task; for - * /proc/PID/maps that is the stack of the main task. - */ -static int is_stack(struct vm_area_struct* vma) { - /* - * We make no effort to guess what a given thread considers to be - * its "stack". It's not even well-defined for programs written - * languages like Go. - */ - return vma->vm_start <= vma->vm_mm->start_stack && - vma->vm_end >= vma->vm_mm->start_stack; -} - -static int get_proc_maps_list(bool is_kernel_buf, struct pid* proc_pid_struct, char* buf, size_t buf_size) { - struct task_struct* task; - struct mm_struct* mm; - struct vm_area_struct* vma; - char path_buf[MY_PATH_MAX_LEN] = {0}; - int success_cnt = 0; - size_t copy_pos; - size_t end_pos; - - task = pid_task(proc_pid_struct, PIDTYPE_PID); - if (!task) { - return -2; - } - - mm = get_task_mm(task); - - if (!mm) { - return -3; - } - if (is_kernel_buf) { - memset(buf, 0, buf_size); - } - //else if (clear_user(buf, buf_size)) { return -4; } //清空用户的缓冲区 - - copy_pos = (size_t)buf; - end_pos = (size_t)((size_t)buf + buf_size); - - if (down_read_mmap_lock(mm) != 0) { - mmput(mm); - return -4; - } - - { - VMA_ITERATOR(iter, mm, 0); - for_each_vma(iter, vma) { - struct map_entry entry; - struct file* vm_file; - struct anon_vma_name *anon_name = NULL; - if (copy_pos >= end_pos) { - break; - } - entry.start = vma->vm_start; - entry.end = vma->vm_end; - entry.flags[0] = (vma->vm_flags & VM_READ) ? 1 : 0; - entry.flags[1] = (vma->vm_flags & VM_WRITE) ? 1 : 0; - entry.flags[2] = (vma->vm_flags & VM_EXEC) ? 1 : 0; - entry.flags[3] = (vma->vm_flags & VM_MAYSHARE) ? 1 : 0; - memset(entry.path, 0, sizeof(entry.path)); - vm_file = get_vm_file(vma); - if (vm_file) { - char* path; - memset(path_buf, 0, sizeof(path_buf)); - path = d_path(&vm_file->f_path, path_buf, sizeof(path_buf)); - if (path > 0) { - strncat(entry.path, path, sizeof(entry.path) - 1); - } - } else if (!vma->vm_mm) { - snprintf(entry.path, sizeof(entry.path), "%s[vdso]", entry.path); - } else if (vma->vm_start <= mm->brk && - vma->vm_end >= mm->start_brk) { - snprintf(entry.path, sizeof(entry.path), "%s[heap]", entry.path); - } else if (is_stack(vma)) { - /* - * Thread stack in /proc/PID/task/TID/maps or - * the main process stack. - */ - - /* Thread stack in /proc/PID/maps */ - snprintf(entry.path, sizeof(entry.path), "%s[stack]", entry.path); - } else { - anon_name = anon_vma_name(vma); - if(anon_name) { - snprintf(entry.path, sizeof(entry.path), "[anon:%s]", anon_name->name); - } - } - - if (is_kernel_buf) { - memcpy((void *)copy_pos, &entry, sizeof(entry)); - } else { - if (x_copy_to_user((void *)copy_pos, &entry, sizeof(entry))) { - break; - } - } - copy_pos += sizeof(entry); - success_cnt++; - } - } - up_read_mmap_lock(mm); - mmput(mm); - - return success_cnt; -} -#endif - - -#if MY_LINUX_VERSION_CODE == KERNEL_VERSION(6,6,30) -#include -struct anon_vma_name * __weak anon_vma_name(struct vm_area_struct* vma) { - return NULL; -} - -static int get_proc_maps_list(bool is_kernel_buf, struct pid* proc_pid_struct, char* buf, size_t buf_size) { - struct task_struct* task; - struct mm_struct* mm; - struct vm_area_struct* vma; - char path_buf[MY_PATH_MAX_LEN]; - int success_cnt = 0; - size_t copy_pos; - size_t end_pos; - - task = pid_task(proc_pid_struct, PIDTYPE_PID); - if (!task) { - return -2; - } - - mm = get_task_mm(task); - - if (!mm) { - return -3; - } - if (is_kernel_buf) { - memset(buf, 0, buf_size); - } - //else if (clear_user(buf, buf_size)) { return -4; } //清空用户的缓冲区 - - copy_pos = (size_t)buf; - end_pos = (size_t)((size_t)buf + buf_size); - - if (down_read_mmap_lock(mm) != 0) { - mmput(mm); - return -4; - } - - { - VMA_ITERATOR(iter, mm, 0); - for_each_vma(iter, vma) { - struct map_entry entry; - struct file* vm_file; - struct anon_vma_name *anon_name = NULL; - if (copy_pos >= end_pos) { - break; - } - entry.start = vma->vm_start; - entry.end = vma->vm_end; - entry.flags[0] = (vma->vm_flags & VM_READ) ? 1 : 0; - entry.flags[1] = (vma->vm_flags & VM_WRITE) ? 1 : 0; - entry.flags[2] = (vma->vm_flags & VM_EXEC) ? 1 : 0; - entry.flags[3] = (vma->vm_flags & VM_MAYSHARE) ? 1 : 0; - memset(entry.path, 0, sizeof(entry.path)); - vm_file = get_vm_file(vma); - if (vm_file) { - char* path; - memset(path_buf, 0, sizeof(path_buf)); - path = d_path(&vm_file->f_path, path_buf, sizeof(path_buf)); - if (path > 0) { - strncat(entry.path, path, sizeof(entry.path) - 1); - } - } else if (!vma->vm_mm) { - snprintf(entry.path, sizeof(entry.path), "%s[vdso]", entry.path); - } else if (vma_is_initial_heap(vma)) { - snprintf(entry.path, sizeof(entry.path), "%s[heap]", entry.path); - } else if (vma_is_initial_stack(vma)) { - snprintf(entry.path, sizeof(entry.path), "%s[stack]", entry.path); - } else { - anon_name = anon_vma_name(vma); - if(anon_name) { - snprintf(entry.path, sizeof(entry.path), "[anon:%s]", anon_name->name); - } - } - - if (is_kernel_buf) { - memcpy((void *)copy_pos, &entry, sizeof(entry)); - } else { - if (x_copy_to_user((void *)copy_pos, &entry, sizeof(entry))) { - break; - } - } - copy_pos += sizeof(entry); - success_cnt++; - } - } - up_read_mmap_lock(mm); - mmput(mm); - - return success_cnt; -} -#endif - -//Update: vm_is_stack\vm_is_stack_for_task: /mm/util.c -//Update: get_proc_maps_list: fs\proc\task_mmu.c - -#endif /* PROC_MAPS_H_ */ \ No newline at end of file diff --git a/code/proc_maps_auto_offset.h b/code/proc_maps_auto_offset.h deleted file mode 100644 index d0cc77f..0000000 --- a/code/proc_maps_auto_offset.h +++ /dev/null @@ -1,364 +0,0 @@ -#ifndef PROC_MAPS_AUTO_OFFSET_H_ -#define PROC_MAPS_AUTO_OFFSET_H_ -#include "api_proxy.h" -#include "ver_control.h" - - -#ifndef MM_STRUCT_MMAP_LOCK -#if MY_LINUX_VERSION_CODE < KERNEL_VERSION(5,10,43) -#define MM_STRUCT_MMAP_LOCK mmap_sem -#endif -#if MY_LINUX_VERSION_CODE >= KERNEL_VERSION(5,10,43) -#define MM_STRUCT_MMAP_LOCK mmap_lock -#endif -#endif - -static ssize_t g_mmap_lock_offset = 0; -static bool g_init_mmap_lock_offset_success = false; - -static ssize_t g_map_count_offset = 0; -static bool g_init_map_count_offset_success = false; - -static ssize_t g_vm_file_offset = 0; -static bool g_init_vm_file_offset_success = false; - -static int get_mytask_maps_cnt(void) { - struct task_struct * mytask = x_get_current(); - struct mm_struct * mm = get_task_mm(mytask); - struct vm_area_struct* vma; - int cnt = 0; - #if MY_LINUX_VERSION_CODE < KERNEL_VERSION(6,1,0) - for (vma = mm->mmap; vma; vma = vma->vm_next) { - cnt++; - } - #else - { - VMA_ITERATOR(iter, mm, 0); - for_each_vma(iter, vma) { - cnt++; - } - } - #endif - return cnt; -} - - -static int init_mmap_lock_offset(void) { - int is_found_mmap_lock_offset = 0; - struct task_struct * mytask = x_get_current(); - struct mm_struct * mm = get_task_mm(mytask); - int maps_cnt = get_mytask_maps_cnt(); - if(g_init_mmap_lock_offset_success) { - return 0; - } - printk_debug(KERN_EMERG "init_mmap_lock_offset maps_cnt:%d, mm->map_count:%p:%d\n", maps_cnt, &mm->map_count, (int)mm->map_count); - - g_init_mmap_lock_offset_success = true; - for (g_mmap_lock_offset = -80; g_mmap_lock_offset <= 80; g_mmap_lock_offset += 1) { - char *rp; - int val; - ssize_t accurate_offset = (ssize_t)((size_t)&mm->MM_STRUCT_MMAP_LOCK - (size_t)mm + g_mmap_lock_offset); - if (accurate_offset >= sizeof(struct mm_struct) - sizeof(ssize_t)) { - mmput(mm); - return -EFAULT; - } - rp = (char*)((size_t)mm + (size_t)accurate_offset); - val = *(int*)(rp); - printk_debug(KERN_EMERG "init_mmap_lock_offset %zd:%zd:%p:%d\n", g_mmap_lock_offset, accurate_offset, rp, val); - - if (val == maps_cnt) { - printk_debug(KERN_EMERG "val == maps_cnt %zd:%zd:%p:%d\n", g_mmap_lock_offset, accurate_offset, rp, val); - g_mmap_lock_offset += sizeof(val); - g_mmap_lock_offset += sizeof(int); - is_found_mmap_lock_offset = 1; - break; - } - - } - - - if (!is_found_mmap_lock_offset) { - g_init_mmap_lock_offset_success = false; - mmput(mm); - printk_debug(KERN_INFO "find mmap_lock offset failed\n"); - return -ESPIPE; - } - mmput(mm); - printk_debug(KERN_INFO "found g_mmap_lock_offset:%zu\n", g_mmap_lock_offset); - return 0; -} - -static inline int down_read_mmap_lock(struct mm_struct *mm) { - ssize_t accurate_offset; - struct rw_semaphore *sem; - if (g_init_mmap_lock_offset_success == false) { - return -ENOENT; - } - - accurate_offset = (ssize_t)((size_t)&mm->MM_STRUCT_MMAP_LOCK - (size_t)mm + g_mmap_lock_offset); - printk_debug(KERN_INFO "down_read_mmap_lock accurate_offset:%zd\n", accurate_offset); - if (accurate_offset >= sizeof(struct mm_struct) - sizeof(ssize_t)) { - return -ERANGE; - } - sem = (struct rw_semaphore *)((size_t)mm + (size_t)accurate_offset); - down_read(sem); - return 0; -} - -static inline int up_read_mmap_lock(struct mm_struct *mm) { - ssize_t accurate_offset; - struct rw_semaphore *sem; - if (g_init_mmap_lock_offset_success == false) { - return -ENOENT; - } - accurate_offset = (ssize_t)((size_t)&mm->MM_STRUCT_MMAP_LOCK - (size_t)mm + g_mmap_lock_offset); - printk_debug(KERN_INFO "accurate_offset:%zd\n", accurate_offset); - if (accurate_offset >= sizeof(struct mm_struct) - sizeof(ssize_t)) { - return -ERANGE; - } - sem = (struct rw_semaphore *)((size_t)mm + (size_t)accurate_offset); - - up_read(sem); - return 0; -} - -static int init_map_count_offset(void) { - int is_found_map_count_offset = 0; - struct task_struct * mytask = x_get_current(); - struct mm_struct * mm = get_task_mm(mytask); - int maps_cnt = get_mytask_maps_cnt(); - if(g_init_map_count_offset_success) { - return 0; - } - printk_debug(KERN_EMERG "init_map_count_offset maps_cnt:%d, mm->map_count:%p:%d\n", maps_cnt, &mm->map_count, (int)mm->map_count); - - g_init_map_count_offset_success = true; - for (g_map_count_offset = -40; g_map_count_offset <= 40; g_map_count_offset += 1) { - char *rp; - int val; - ssize_t accurate_offset = (ssize_t)((size_t)&mm->map_count - (size_t)mm + g_map_count_offset); - if (accurate_offset >= sizeof(struct mm_struct) - sizeof(ssize_t)) { - mmput(mm); - return -EFAULT; - } - rp = (char*)((size_t)mm + (size_t)accurate_offset); - val = *(int*)(rp); - printk_debug(KERN_EMERG "init_map_count_offset %zd:%zd:%p:%d\n", g_map_count_offset, accurate_offset, rp, val); - - if (val == maps_cnt) { - printk_debug(KERN_EMERG "val == maps_cnt %zd:%zd:%p:%d\n", g_map_count_offset, accurate_offset, rp, val); - is_found_map_count_offset = 1; - break; - } - } - - - if (!is_found_map_count_offset) { - g_init_map_count_offset_success = false; - printk_debug(KERN_INFO "find map_count offset failed\n"); - mmput(mm); - return -ESPIPE; - } - - mmput(mm); - printk_debug(KERN_INFO "g_map_count_offset:%zu\n", g_map_count_offset); - return 0; -} - -#if MY_LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,75) -static int init_vm_file_offset(void) { - int is_found_vm_file_offset = 0; - struct vm_area_struct *vma; - struct task_struct * mytask = x_get_current(); - struct mm_struct *mm = get_task_mm(mytask); - if(g_init_vm_file_offset_success) { - return 0; - } - if (down_read_mmap_lock(mm) != 0) { - mmput(mm); - return -EFAULT; - } - - g_init_vm_file_offset_success = false; - { - VMA_ITERATOR(iter, mm, 0); - for_each_vma(iter, vma) { - if (is_found_vm_file_offset == 1) { - break; - } - for (g_vm_file_offset = -80; g_vm_file_offset <= 80; g_vm_file_offset += 1) { - char *rp; - size_t addr_val1; - size_t addr_val2; - unsigned long vm_pgoff; - ssize_t accurate_offset = (ssize_t)((size_t)&vma->vm_file - (size_t)vma + g_vm_file_offset); - //这里故意屏蔽,因为vm_file已经接近vm_area_struct结构体尾部了 - /*if (accurate_offset >= sizeof(struct vm_area_struct) - sizeof(struct file *)) - { - mmput(mm); - return -EFAULT; - }*/ - rp = (char*)((size_t)vma + (size_t)accurate_offset); - addr_val1 = *(size_t*)(rp); - rp += (size_t)sizeof(void*); - addr_val2 = *(size_t*)(rp); - printk_debug(KERN_EMERG "init_vm_file_offset %zd:%zd:%p:%zu\n", g_vm_file_offset, accurate_offset, rp, addr_val1); - if (addr_val1 > 0 && addr_val2 > 0 && addr_val1 == addr_val2) //struct list_head anon_vma_chain;里面两个值一样 - { - int vm_pgoff_offset = 0; - int found_vm_pgoff = 0; - - printk_debug(KERN_EMERG "init_vm_file_offset addr_val1 == addr_val2 %zd:%zd:%p:%zu\n", g_vm_file_offset, accurate_offset, rp, addr_val1); - rp += (size_t)sizeof(void*); - for (; vm_pgoff_offset < 8 * 5; vm_pgoff_offset += 4) { - vm_pgoff = *(unsigned long*)(rp); - if (vm_pgoff > 0 && vm_pgoff < 1000/*这个值是vm_pgoff我见过的最大值吧,如果最大值比1000还有大再改大*/) { - found_vm_pgoff = 1; - break; - } - rp += 4; - } - if (found_vm_pgoff) { - rp += (size_t)sizeof(unsigned long); - rp += (size_t)sizeof(struct file *); - - addr_val1 = *(size_t*)(rp); - rp += (size_t)sizeof(void*); - addr_val2 = *(size_t*)(rp); - - if (addr_val1 == 0 && addr_val2 == 0) { - g_vm_file_offset += sizeof(void*) * 2; - g_vm_file_offset += vm_pgoff_offset; - g_vm_file_offset += sizeof(unsigned long); - printk_debug(KERN_EMERG "init_vm_file_offset ok, addr_val1 == addr_val2 == 0 %zd:%d\n", g_vm_file_offset, vm_pgoff_offset); - is_found_vm_file_offset = 1; - break; - } - - } - - - } - } - } - } - - up_read_mmap_lock(mm); - mmput(mm); - - if (!is_found_vm_file_offset) { - printk_debug(KERN_INFO "find vm_file offset failed\n"); - return -ESPIPE; - } - g_init_vm_file_offset_success = true; - - return 0; -} -#else - -static int init_vm_file_offset(void) { - int is_found_vm_file_offset = 0; - struct vm_area_struct *vma; - struct task_struct * mytask = x_get_current(); - struct mm_struct *mm = get_task_mm(mytask); - if(g_init_vm_file_offset_success) { - return 0; - } - if (down_read_mmap_lock(mm) != 0) { - mmput(mm); - return -EFAULT; - } - - g_init_vm_file_offset_success = false; - for (vma = mm->mmap; vma; vma = vma->vm_next) { - if (is_found_vm_file_offset == 1) { - break; - } - for (g_vm_file_offset = -80; g_vm_file_offset <= 80; g_vm_file_offset += 1) { - char *rp; - size_t addr_val1; - size_t addr_val2; - unsigned long vm_pgoff; - ssize_t accurate_offset = (ssize_t)((size_t)&vma->vm_file - (size_t)vma + g_vm_file_offset); - //这里故意屏蔽,因为vm_file已经接近vm_area_struct结构体尾部了 - /*if (accurate_offset >= sizeof(struct vm_area_struct) - sizeof(struct file *)) - { - mmput(mm); - return -EFAULT; - }*/ - rp = (char*)((size_t)vma + (size_t)accurate_offset); - addr_val1 = *(size_t*)(rp); - rp += (size_t)sizeof(void*); - addr_val2 = *(size_t*)(rp); - printk_debug(KERN_EMERG "init_vm_file_offset %zd:%zd:%p:%zu\n", g_vm_file_offset, accurate_offset, rp, addr_val1); - if (addr_val1 > 0 && addr_val2 > 0 && addr_val1 == addr_val2) //struct list_head anon_vma_chain;里面两个值一样 - { - int vm_pgoff_offset = 0; - int found_vm_pgoff = 0; - - printk_debug(KERN_EMERG "init_vm_file_offset addr_val1 == addr_val2 %zd:%zd:%p:%zu\n", g_vm_file_offset, accurate_offset, rp, addr_val1); - rp += (size_t)sizeof(void*); - for (; vm_pgoff_offset < 8 * 5; vm_pgoff_offset += 4) { - vm_pgoff = *(unsigned long*)(rp); - if (vm_pgoff > 0 && vm_pgoff < 1000/*这个值是vm_pgoff我见过的最大值吧,如果最大值比1000还有大再改大*/) { - found_vm_pgoff = 1; - break; - } - rp += 4; - } - if (found_vm_pgoff) { - rp += (size_t)sizeof(unsigned long); - rp += (size_t)sizeof(struct file *); - - addr_val1 = *(size_t*)(rp); - rp += (size_t)sizeof(void*); - addr_val2 = *(size_t*)(rp); - - if (addr_val1 == 0 && addr_val2 == 0) { - g_vm_file_offset += sizeof(void*) * 2; - g_vm_file_offset += vm_pgoff_offset; - g_vm_file_offset += sizeof(unsigned long); - printk_debug(KERN_EMERG "init_vm_file_offset ok, addr_val1 == addr_val2 == 0 %zd:%d\n", g_vm_file_offset, vm_pgoff_offset); - is_found_vm_file_offset = 1; - break; - } - - } - - - } - } - } - - up_read_mmap_lock(mm); - mmput(mm); - - if (!is_found_vm_file_offset) { - printk_debug(KERN_INFO "find vm_file offset failed\n"); - return -ESPIPE; - } - g_init_vm_file_offset_success = true; - return 0; -} -#endif - -static inline struct file * get_vm_file(struct vm_area_struct *vma) { - struct file * vm_file; - ssize_t accurate_offset; - if (g_init_vm_file_offset_success == false) { - if (init_vm_file_offset() != 0) { - return NULL; - } - } - - accurate_offset = (ssize_t)((size_t)&vma->vm_file - (size_t)vma + g_vm_file_offset); - printk_debug(KERN_INFO "get_vm_file accurate_offset:%zd\n", accurate_offset); - //这里故意屏蔽,因为vm_file已经接近vm_area_struct结构体尾部了 - //if (accurate_offset >= sizeof(struct vm_area_struct) - sizeof(struct file *)) - //{ - // return NULL; - //} - vm_file = (struct file*) *(size_t*)((size_t)vma + (size_t)accurate_offset); - return vm_file; -} -#endif /* PROC_MAPS_AUTO_OFFSET_H_ */ \ No newline at end of file diff --git a/code/proc_root.h b/code/proc_root.h deleted file mode 100644 index dff6134..0000000 --- a/code/proc_root.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef PROC_ROOT_H_ -#define PROC_ROOT_H_ -#include -#include -#include "proc_root_auto_offset.h" -#include "ver_control.h" -//声明 -////////////////////////////////////////////////////////////////////////// -static inline int set_process_root(struct pid* proc_pid_struct); - - -//实现 -////////////////////////////////////////////////////////////////////////// -static uint64_t get_cap_ability_max(void) { - -#if MY_LINUX_VERSION_CODE < KERNEL_VERSION(5,8,0) - uint64_t cap_default = 0x3FFFFFFFFF; -#elif MY_LINUX_VERSION_CODE < KERNEL_VERSION(5,9,0) - uint64_t cap_default = 0xFFFFFFFFFF; -#else - uint64_t cap_default = 0x1FFFFFFFFFF; -#endif - - return cap_default; -} - -static inline int set_process_root(struct pid* proc_pid_struct) { - if (g_init_real_cred_offset_success == false) { - return -ENOENT; - } - - if (g_init_real_cred_offset_success) { - struct task_struct * task = NULL; - struct cred * cred = NULL; - char *pCred = NULL; - task = pid_task(proc_pid_struct, PIDTYPE_PID); - if (!task) { return -1; } - - pCred = (char*)&task->real_cred; - - pCred += g_real_cred_offset; - pCred += sizeof(void*); - cred = (struct cred *)*(size_t*)pCred; - if (cred) { - uint64_t cap = get_cap_ability_max(); - cred->uid = cred->suid = cred->euid = cred->fsuid = GLOBAL_ROOT_UID; - cred->gid = cred->sgid = cred->egid = cred->fsgid = GLOBAL_ROOT_GID; - memcpy(&cred->cap_inheritable, &cap, sizeof(cap)); - memcpy(&cred->cap_permitted, &cap, sizeof(cap)); - memcpy(&cred->cap_effective, &cap, sizeof(cap)); - memcpy(&cred->cap_bset, &cap, sizeof(cap)); - memcpy(&cred->cap_ambient, &cap, sizeof(cap)); - return 0; - } - return -EBADF; - - } - return -ESPIPE; - -} -#endif /* PROC_ROOT_H_ */ - - diff --git a/code/proc_root_auto_offset.h b/code/proc_root_auto_offset.h deleted file mode 100644 index df23a43..0000000 --- a/code/proc_root_auto_offset.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef PROC_ROOT_AUTO_OFFSET_H_ -#define PROC_ROOT_AUTO_OFFSET_H_ -#include -#include "ver_control.h" - -static ssize_t g_real_cred_offset = 0; -static bool g_init_real_cred_offset_success = false; - -static inline int init_proc_root_offset(const char* my_name) { - const ssize_t offset_lookup_min = -100; - const ssize_t offset_lookup_max = 300; - const ssize_t min_real_cred_offset_limit = offset_lookup_min + sizeof(void*) * 3; - if(g_init_real_cred_offset_success) { - return 0; - } - - g_init_real_cred_offset_success = false; - for (g_real_cred_offset = offset_lookup_min; g_real_cred_offset <= offset_lookup_max; g_real_cred_offset++) { - - char* pcomm = (char*)¤t->real_cred; - pcomm += g_real_cred_offset; - - printk_debug(KERN_EMERG "curent g_real_cred_offset:%zd, bytes:%x\n", g_real_cred_offset, *(unsigned char*)pcomm); - - if(g_real_cred_offset < min_real_cred_offset_limit) { - continue; - } - if (strcmp(pcomm, my_name) == 0) { - ssize_t maybe_real_cred_offset = g_real_cred_offset - sizeof(void*) * 2; - char * p_test_mem1 = (char*)¤t->real_cred + maybe_real_cred_offset; - char * p_test_mem2 = (char*)¤t->real_cred + maybe_real_cred_offset + sizeof(void*); // for get cred *cred; - if(memcmp(p_test_mem1, p_test_mem2, sizeof(void*)) != 0 ) { // becasuse the real_cred is equal the cred - maybe_real_cred_offset = g_real_cred_offset - sizeof(void*) * 3; - p_test_mem1 = (char*)¤t->real_cred + maybe_real_cred_offset; - p_test_mem2 = (char*)¤t->real_cred + maybe_real_cred_offset + sizeof(void*); // for get cred *cred; - if(memcmp(p_test_mem1, p_test_mem2, sizeof(void*)) != 0 ) { // becasuse the real_cred is equal the cred - break; // failed - } - } - g_real_cred_offset = maybe_real_cred_offset; - - printk_debug(KERN_EMERG "strcmp found %zd\n", g_real_cred_offset); - - g_init_real_cred_offset_success = true; - break; - } - - } - - if (!g_init_real_cred_offset_success) { - printk_debug(KERN_INFO "real_cred offset failed\n"); - return -ESPIPE; - } - printk_debug(KERN_INFO "g_real_cred_offset:%zu\n", g_real_cred_offset); - return 0; -} -#endif /* PROC_ROOT_AUTO_OFFSET_H_ */ - - diff --git a/code/proc_rss.h b/code/proc_rss.h deleted file mode 100644 index 35d6c30..0000000 --- a/code/proc_rss.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef PROC_RSS_H_ -#define PROC_RSS_H_ -//声明 -////////////////////////////////////////////////////////////////////////// -#include -#include "api_proxy.h" -#include "ver_control.h" -static size_t read_proc_rss_size(struct pid* proc_pid_struct); - -//实现 -////////////////////////////////////////////////////////////////////////// -#include "proc_cmdline_auto_offset.h" -static size_t read_proc_rss_size(struct pid* proc_pid_struct) { - struct task_struct *task; - struct mm_struct *mm; - task = pid_task(proc_pid_struct, PIDTYPE_PID); - if (!task) { - return 0; - } - mm = get_task_mm(task); - if (mm) { - //精确偏移 - size_t total_rss; - ssize_t offset = g_init_arg_start_offset_success ? g_arg_start_offset : 0; - total_rss = x_read_mm_struct_rss(mm, offset); - mmput(mm); - return total_rss; - } - return 0; - -} -#endif /* PROC_RSS_H_ */ \ No newline at end of file diff --git a/code/rwProcMem_module.c b/code/rwProcMem_module.c deleted file mode 100644 index ef42d7f..0000000 --- a/code/rwProcMem_module.c +++ /dev/null @@ -1,397 +0,0 @@ -#include "rwProcMem_module.h" - -#define MY_TASK_COMM_LEN 16 - -#pragma pack(push,1) -struct ioctl_request { - char cmd; /* 1 字节命令 */ - uint64_t param1; /* 参数1 */ - uint64_t param2; /* 参数2 */ - uint64_t param3; /* 参数3 */ - uint64_t buf_size; /* 紧随其后的动态数据长度 */ -}; -struct init_device_info { - int pid; - int tgid; - char my_name[MY_TASK_COMM_LEN + 1]; - char my_cmdline[1024]; -}; -struct arg_info { - uint64_t arg_start; - uint64_t arg_end; -}; -#pragma pack(pop) - -static ssize_t OnCmdInitDeviceInfo(struct ioctl_request *hdr, char __user* buf) { - long err = 0; - struct init_device_info* pinit_device_info = (struct init_device_info*)x_kmalloc(sizeof(struct init_device_info), GFP_KERNEL); - if (!pinit_device_info) { - return -ENOMEM; - } - printk_debug(KERN_INFO "CMD_INIT_DEVICE_INFO\n"); - memset(pinit_device_info, 0, sizeof(struct init_device_info)); - if (x_copy_from_user((void*)pinit_device_info, (void*)buf, sizeof(struct init_device_info)) == 0) { - printk_debug(KERN_INFO "my_cmdline:%s\n", pinit_device_info->my_cmdline); - printk_debug(KERN_INFO "my_name:%s\n", pinit_device_info->my_name); - printk_debug(KERN_INFO "pid:%d, tgid:%d\n", pinit_device_info->pid, pinit_device_info->tgid); - do { - err = init_mmap_lock_offset(); - if(err) { break; } - err = init_map_count_offset(); - if(err) { break; } - err = init_proc_cmdline_offset(pinit_device_info->my_cmdline, get_task_proc_cmdline_addr); - if(err) { break; } - err = init_proc_root_offset(pinit_device_info->my_name); - if(err) { break; } - err = init_task_next_offset(); - if(err) { break; } - err = init_task_pid_offset(pinit_device_info->pid, pinit_device_info->tgid); - } while(0); - } else { - err = -EINVAL; - } - kfree(pinit_device_info); - return err; -} - -static ssize_t OnCmdOpenProcess(struct ioctl_request *hdr, char __user* buf) { - uint64_t pid = hdr->param1, handle = 0; - struct pid * proc_pid_struct = NULL; - printk_debug(KERN_INFO "CMD_OPEN_PROCESS\n"); - - printk_debug(KERN_INFO "pid:%llu,size:%ld\n", pid, sizeof(pid)); - proc_pid_struct = get_proc_pid_struct(pid); - printk_debug(KERN_INFO "proc_pid_struct *:0x%p\n", (void*)proc_pid_struct); - if (!proc_pid_struct) { - return -EINVAL; - } - handle = (uint64_t)proc_pid_struct; - - printk_debug(KERN_INFO "handle:%llu,size:%ld\n", handle, sizeof(handle)); - if (!!x_copy_to_user((void*)buf, (void*)&handle, sizeof(handle))) { - return -EINVAL; - } - return 0; -} - -static ssize_t OnCmdCloseProcess(struct ioctl_request *hdr, char __user* buf) { - struct pid * proc_pid_struct = (struct pid *)hdr->param1; - printk_debug(KERN_INFO "CMD_CLOSE_PROCESS\n"); - printk_debug(KERN_INFO "proc_pid_struct*:0x%p,size:%ld\n", (void*)proc_pid_struct, sizeof(proc_pid_struct)); - release_proc_pid_struct(proc_pid_struct); - return 0; -} - -static ssize_t OnCmdReadProcessMemory(struct ioctl_request *hdr, char __user* buf) { - struct pid * proc_pid_struct = (struct pid *)hdr->param1; - size_t proc_virt_addr = (size_t)hdr->param2; - bool is_force_read = hdr->param3 == 1 ? true : false; - size_t size = (size_t)hdr->buf_size; - size_t read_size = 0; - - printk_debug(KERN_INFO "CMD_READ_PROCESS_MEMORY\n"); - printk_debug(KERN_INFO "READ proc_pid_struct*:0x%p,size:%ld\n", (void*)proc_pid_struct, sizeof(proc_pid_struct)); - printk_debug(KERN_INFO "READ proc_virt_addr:0x%zx,size:%ld\n", proc_virt_addr, sizeof(proc_virt_addr)); - if (is_force_read == false && !check_proc_map_can_read(proc_pid_struct, proc_virt_addr, size)) { - return -EFAULT; - } - while (read_size < size) { - size_t phy_addr = 0; - size_t pfn_sz = 0; - char *lpOutBuf = NULL; - pte_t *pte; - - bool old_pte_can_read; - phy_addr = get_proc_phy_addr(proc_pid_struct, proc_virt_addr + read_size, (pte_t*)&pte); - printk_debug(KERN_INFO "calc phy_addr:0x%zx\n", phy_addr); - - if (phy_addr == 0) { - break; - } - - old_pte_can_read = is_pte_can_read(pte); - if (is_force_read) { - if (!old_pte_can_read) { - if (!change_pte_read_status(pte, true)) { break; } - - } - } else if (!old_pte_can_read) { - break; - } - - pfn_sz = size_inside_page(phy_addr, ((size - read_size) > PAGE_SIZE) ? PAGE_SIZE : (size - read_size)); - printk_debug(KERN_INFO "pfn_sz:%zu\n", pfn_sz); - - - lpOutBuf = (char*)(buf + read_size); - read_ram_physical_addr(false, phy_addr, lpOutBuf, pfn_sz); - - if (is_force_read && old_pte_can_read == false) { - change_pte_read_status(pte, false); - } - read_size += pfn_sz; - } - return read_size; -} - -static ssize_t OnCmdWriteProcessMemory(struct ioctl_request *hdr, char __user* buf) { - struct pid * proc_pid_struct = (struct pid *)hdr->param1; - size_t proc_virt_addr = (size_t)hdr->param2; - bool is_force_write = hdr->param3 == 1 ? true : false; - size_t size = (size_t)hdr->buf_size; - size_t write_size = 0; - printk_debug(KERN_INFO "CMD_WRITE_PROCESS_MEMORY\n"); - printk_debug(KERN_INFO "WRITE proc_pid_struct*:0x%p,size:%ld\n", (void*)proc_pid_struct, sizeof(proc_pid_struct)); - printk_debug(KERN_INFO "WRITE proc_virt_addr:0x%zx,size:%ld\n", proc_virt_addr, sizeof(proc_virt_addr)); - if (is_force_write == false && !check_proc_map_can_write(proc_pid_struct, proc_virt_addr, size)) { - return -EFAULT; - } - - while (write_size < size) { - size_t phy_addr = 0; - size_t pfn_sz = 0; - char * input_buf = NULL; - - pte_t *pte; - bool old_pte_can_write; - phy_addr = get_proc_phy_addr(proc_pid_struct, proc_virt_addr + write_size, (pte_t*)&pte); - printk_debug(KERN_INFO "phy_addr:0x%zx\n", phy_addr); - if (phy_addr == 0) { - break; - } - - old_pte_can_write = is_pte_can_write(pte); - if (is_force_write) { - if (!old_pte_can_write) { - if (!change_pte_write_status(pte, true)) { break; } - } - } else if (!old_pte_can_write) { - break; - } - - pfn_sz = size_inside_page(phy_addr, ((size - write_size) > PAGE_SIZE) ? PAGE_SIZE : (size - write_size)); - printk_debug(KERN_INFO "pfn_sz:%zu\n", pfn_sz); - - input_buf = (char*)(((size_t)buf + write_size)); - write_ram_physical_addr(phy_addr, input_buf, false, pfn_sz); - - if (is_force_write && old_pte_can_write == false) { - change_pte_write_status(pte, false); - } - - write_size += pfn_sz; - } - return write_size; -} - -static ssize_t OnCmdGetProcessMapsCount(struct ioctl_request *hdr, char __user* buf) { - struct pid * proc_pid_struct = (struct pid *)hdr->param1; - printk_debug(KERN_INFO "CMD_GET_PROCESS_MAPS_COUNT\n"); - printk_debug(KERN_INFO "proc_pid_struct*:0x%p, size:%ld\n", (void*)proc_pid_struct, sizeof(proc_pid_struct)); - return get_proc_map_count(proc_pid_struct); -} - -static ssize_t OnCmdGetProcessMapsList(struct ioctl_request *hdr, char __user* buf) { - struct pid * proc_pid_struct = (struct pid *)hdr->param1; - printk_debug(KERN_INFO "CMD_GET_PROCESS_MAPS_LIST\n"); - printk_debug(KERN_INFO "proc_pid_struct*:0x%p,size:%ld\n", (void*)proc_pid_struct, sizeof(proc_pid_struct)); - printk_debug(KERN_INFO "buf_size:%llu\n", hdr->buf_size); - return get_proc_maps_list(false, proc_pid_struct, (void*)(buf), hdr->buf_size - 1); -} - -static ssize_t OnCmdCheckProcessPhyAddr(struct ioctl_request *hdr, char __user* buf) { - struct pid * proc_pid_struct = (struct pid *)hdr->param1; - size_t proc_virt_addr = (size_t)hdr->param2; - pte_t *pte; - printk_debug(KERN_INFO "CMD_CHECK_PROCESS_ADDR_PHY\n"); - printk_debug(KERN_INFO "proc_pid_struct *:0x%p,size:%ld\n", (void*)proc_pid_struct, sizeof(proc_pid_struct)); - printk_debug(KERN_INFO "proc_virt_addr :0x%zx\n", proc_virt_addr); - if (get_proc_phy_addr(proc_pid_struct, proc_virt_addr, (pte_t*)&pte)) { - return 1; - } - return 0; - -} - -static ssize_t OnCmdGetPidList(struct ioctl_request *hdr, char __user* buf) { - printk_debug(KERN_INFO "CMD_GET_PID_LIST\n"); - printk_debug(KERN_INFO "buf_size:%llu\n", hdr->buf_size); - return get_proc_pid_list(false, buf, hdr->buf_size); -} - -static ssize_t OnCmdSetProcessRoot(struct ioctl_request *hdr, char __user* buf) { - struct pid * proc_pid_struct = (struct pid *)hdr->param1; - printk_debug(KERN_INFO "CMD_SET_PROCESS_ROOT\n"); - printk_debug(KERN_INFO "proc_pid_struct*:0x%p,size:%ld\n", (void*)proc_pid_struct, sizeof(proc_pid_struct)); - return set_process_root(proc_pid_struct); -} - -static ssize_t OnCmdGetProcessRss(struct ioctl_request *hdr, char __user* buf) { - struct pid * proc_pid_struct = (struct pid *)hdr->param1; - uint64_t rss = 0; - printk_debug(KERN_INFO "CMD_GET_PROCESS_RSS\n"); - printk_debug(KERN_INFO "proc_pid_struct*:0x%p,size:%ld\n", (void*)proc_pid_struct, sizeof(proc_pid_struct)); - rss = read_proc_rss_size(proc_pid_struct); - if (!!x_copy_to_user((void*)buf, &rss, sizeof(rss))) { - return -EINVAL; - } - return 0; -} - -static ssize_t OnCmdGetProcessCmdlineAddr(struct ioctl_request *hdr, char __user* buf) { - struct pid * proc_pid_struct = (struct pid *)hdr->param1; - size_t arg_start = 0, arg_end = 0; - int res; - struct arg_info aginfo = {0}; - printk_debug(KERN_INFO "CMD_GET_PROCESS_CMDLINE_ADDR\n"); - printk_debug(KERN_INFO "proc_pid_struct *:0x%p,size:%ld\n", (void*)proc_pid_struct, sizeof(proc_pid_struct)); - res = get_proc_cmdline_addr(proc_pid_struct, &arg_start, &arg_end); - aginfo.arg_start = (uint64_t)arg_start; - aginfo.arg_end = (uint64_t)arg_end; - if (!!x_copy_to_user((void*)buf, &aginfo, sizeof(aginfo))) { - return -EINVAL; - } - return res; -} - -static ssize_t OnCmdHideKernelModule(struct ioctl_request *hdr, char __user* buf) { - printk_debug(KERN_INFO "CMD_HIDE_KERNEL_MODULE\n"); - if (g_rwProcMem_devp->is_hidden_module == false) { - g_rwProcMem_devp->is_hidden_module = true; - list_del_init(&__this_module.list); - kobject_del(&THIS_MODULE->mkobj.kobj); - } - return 0; -} - -static inline ssize_t DispatchCommand(struct ioctl_request *hdr, char __user* buf) { - switch (hdr->cmd) { - case CMD_INIT_DEVICE_INFO: - return OnCmdInitDeviceInfo(hdr, buf); - case CMD_OPEN_PROCESS: - return OnCmdOpenProcess(hdr, buf); - case CMD_READ_PROCESS_MEMORY: - return OnCmdReadProcessMemory(hdr, buf); - case CMD_WRITE_PROCESS_MEMORY: - return OnCmdWriteProcessMemory(hdr, buf); - case CMD_CLOSE_PROCESS: - return OnCmdCloseProcess(hdr, buf); - case CMD_GET_PROCESS_MAPS_COUNT: - return OnCmdGetProcessMapsCount(hdr, buf); - case CMD_GET_PROCESS_MAPS_LIST: - return OnCmdGetProcessMapsList(hdr, buf); - case CMD_CHECK_PROCESS_ADDR_PHY: - return OnCmdCheckProcessPhyAddr(hdr, buf); - case CMD_GET_PID_LIST: - return OnCmdGetPidList(hdr, buf); - case CMD_SET_PROCESS_ROOT: - return OnCmdSetProcessRoot(hdr, buf); - case CMD_GET_PROCESS_RSS: - return OnCmdGetProcessRss(hdr, buf); - case CMD_GET_PROCESS_CMDLINE_ADDR: - return OnCmdGetProcessCmdlineAddr(hdr, buf); - case CMD_HIDE_KERNEL_MODULE: - return OnCmdHideKernelModule(hdr, buf); - default: - return -EINVAL; - } - return -EINVAL; -} - -static ssize_t rwProcMem_read(struct file* filp, - char __user* buf, - size_t size, - loff_t* ppos) { - struct ioctl_request hdr = {0}; - size_t header_size = sizeof(hdr); - if (size < header_size) { - return -EINVAL; - } - if (x_copy_from_user(&hdr, buf, header_size)) { - return -EFAULT; - } - if (size < header_size + hdr.buf_size) { - return -EINVAL; - } - return DispatchCommand(&hdr, buf + header_size); -} - -#ifdef CONFIG_MODULE_GUIDE_ENTRY -static -#endif -int __init rwProcMem_dev_init(void) { - printk(KERN_EMERG "Start init.\n"); - - g_rwProcMem_devp = x_kmalloc(sizeof(struct rwProcMemDev), GFP_KERNEL); - memset(g_rwProcMem_devp, 0, sizeof(struct rwProcMemDev)); - -#ifdef CONFIG_USE_PROC_FILE_NODE - g_rwProcMem_devp->proc_parent = proc_mkdir(CONFIG_PROC_NODE_AUTH_KEY, NULL); - if(g_rwProcMem_devp->proc_parent) { - g_rwProcMem_devp->proc_entry = proc_create(CONFIG_PROC_NODE_AUTH_KEY, S_IRUGO | S_IWUGO, g_rwProcMem_devp->proc_parent, &rwProcMem_proc_ops); - start_hide_procfs_dir(CONFIG_PROC_NODE_AUTH_KEY); - } -#endif - -#ifdef CONFIG_DEBUG_PRINTK - printk(KERN_EMERG "Hello, %s debug\n", CONFIG_PROC_NODE_AUTH_KEY); - //test1(); - //test2(); - //test3(); - //test4(); - //test5(); -#else - printk(KERN_EMERG "Hello\n"); -#endif - return 0; -} - -#ifdef CONFIG_MODULE_GUIDE_ENTRY -static -#endif -void __exit rwProcMem_dev_exit(void) { - - printk(KERN_EMERG "Start exit.\n"); - -#ifdef CONFIG_USE_PROC_FILE_NODE - if(g_rwProcMem_devp->proc_entry) { - proc_remove(g_rwProcMem_devp->proc_entry); - g_rwProcMem_devp->proc_entry = NULL; - } - - if(g_rwProcMem_devp->proc_parent) { - proc_remove(g_rwProcMem_devp->proc_parent); - g_rwProcMem_devp->proc_parent = NULL; - } - stop_hide_procfs_dir(); -#endif - kfree(g_rwProcMem_devp); - printk(KERN_EMERG "Goodbye\n"); -} - -#ifndef CONFIG_MODULE_GUIDE_ENTRY -//Hook:__cfi_check_fn -unsigned char* __check_(unsigned char* result, void *ptr, void *diag) -{ - printk_debug(KERN_EMERG "my__cfi_check_fn!!!\n"); - return result; -} - -//Hook:__cfi_check_fail -unsigned char * __check_fail_(unsigned char *result) -{ - printk_debug(KERN_EMERG "my__cfi_check_fail!!!\n"); - return result; -} -#endif - -unsigned long __stack_chk_guard; - -#ifdef CONFIG_MODULE_GUIDE_ENTRY -module_init(rwProcMem_dev_init); -module_exit(rwProcMem_dev_exit); -#endif -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Linux"); -MODULE_DESCRIPTION("Linux default module"); - diff --git a/code/rwProcMem_module.h b/code/rwProcMem_module.h deleted file mode 100644 index 4909c9f..0000000 --- a/code/rwProcMem_module.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef RWPROCMEM_H_ -#define RWPROCMEM_H_ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "api_proxy.h" -#include "phy_mem.h" -#include "proc_maps.h" -#include "proc_list.h" -#include "proc_root.h" -#include "proc_rss.h" -#include "proc_cmdline.h" -#include "ver_control.h" -#include "test.h" -#ifdef CONFIG_USE_PROC_FILE_NODE -#include -#include "hide_procfs_dir.h" -#endif -////////////////////////////////////////////////////////////////// - -enum { - CMD_INIT_DEVICE_INFO = 1, // 初始化设备信息 - CMD_OPEN_PROCESS, // 打开进程 - CMD_READ_PROCESS_MEMORY, // 读取进程内存 - CMD_WRITE_PROCESS_MEMORY, // 写入进程内存 - CMD_CLOSE_PROCESS, // 关闭进程 - CMD_GET_PROCESS_MAPS_COUNT, // 获取进程的内存块地址数量 - CMD_GET_PROCESS_MAPS_LIST, // 获取进程的内存块地址列表 - CMD_CHECK_PROCESS_ADDR_PHY, // 检查进程内存是否有物理内存位置 - CMD_GET_PID_LIST, // 获取进程PID列表 - CMD_SET_PROCESS_ROOT, // 提升进程权限到Root - CMD_GET_PROCESS_RSS, // 获取进程的物理内存占用大小 - CMD_GET_PROCESS_CMDLINE_ADDR, // 获取进程cmdline的内存地址 - CMD_HIDE_KERNEL_MODULE, // 隐藏驱动 -}; - -struct rwProcMemDev { -#ifdef CONFIG_USE_PROC_FILE_NODE - struct proc_dir_entry *proc_parent; - struct proc_dir_entry *proc_entry; -#endif - bool is_hidden_module; -}; -static struct rwProcMemDev *g_rwProcMem_devp; - -static ssize_t rwProcMem_read(struct file* filp, char __user* buf, size_t size, loff_t* ppos); -static const struct proc_ops rwProcMem_proc_ops = { - .proc_read = rwProcMem_read, -}; - -#endif /* RWPROCMEM_H_ */ \ No newline at end of file diff --git a/code/test.h b/code/test.h deleted file mode 100644 index 0cc9378..0000000 --- a/code/test.h +++ /dev/null @@ -1,168 +0,0 @@ -#ifndef TEST_H_ -#define TEST_H_ -#include "phy_mem.h" -#include "proc_maps.h" -#include "proc_list.h" -#include "proc_cmdline.h" -#include "proc_rss.h" -#include "ver_control.h" - -// -//static void test1(void) { -// size_t phy_addr; -// struct file * pFile = open_pagemap(14861); -// printk(KERN_INFO "open_pagemap %d\n", pFile); -// if (pFile) { -// phy_addr = get_pagemap_phy_addr(pFile, 0x10106000); -// printk(KERN_INFO "pagemap phy_addr 0x%llx\n", phy_addr); -// -// char buf[4]; -// size_t ret; -// memset(buf, 0, 4); -// read_ram_physical_addr(true, &ret, phy_addr, buf, 4); -// if (ret) { -// int i; -// for (i = 0; i < 4; i++) { -// printk(KERN_INFO "[%d]0x%x ", i, buf[i]); -// } -// } -// close_pagemap(pFile); -// } -//} -// -///* -//static void test2(void) -//{ -// struct pid * proc_pid_struct = get_proc_pid_struct(14861); -// int map_count = get_proc_map_count(proc_pid_struct); -// printk(KERN_INFO "map_count:%d\n", map_count); -// -// char test[8 + 8 + 4 + 4096] = { 0 }; -// get_proc_maps_list(proc_pid_struct, 4096, &test,sizeof(test), true, NULL); -// -// printk("start:0x%lx,end:0x%lx,flags:%x%x%x%x,name:%s\n", -// *(unsigned long*)&test[0], -// *(unsigned long*)&test[8], -// *(unsigned char*)&test[16], -// *(unsigned char*)&test[17], -// *(unsigned char*)&test[18], -// *(unsigned char*)&test[19], -// &test[20]); -// -// -// release_proc_pid_struct(proc_pid_struct); -// -//} -//*/ -// -//static void test3(void) { -// struct pid * proc_pid_struct = get_proc_pid_struct(14861); -// printk(KERN_INFO "test3 get_proc_pid_struct:%ld\n", proc_pid_struct); -// if (proc_pid_struct) { -// size_t phy_addr = 0; -// pte_t *pte; -// get_proc_phy_addr(&phy_addr, proc_pid_struct, 0x10106000, &pte); -// printk(KERN_INFO "calc phy_addr:0x%llx\n", phy_addr); -// -// release_proc_pid_struct(proc_pid_struct); -// } -// -//} -// -// -//static void test4(void) { -// struct pid * proc_pid_struct = get_proc_pid_struct(23948); -// printk(KERN_INFO "test4 get_proc_pid_struct:%ld\n", proc_pid_struct); -// if (proc_pid_struct) { -// size_t arg_start = 0, arg_end = 0; -// int res = get_proc_cmdline_addr(proc_pid_struct, -8, &arg_start, &arg_end); -// printk(KERN_INFO "test4 get_proc_cmdline_addr arg_start:0x%llx arg_end:0x%llx\n", arg_start, arg_end); -// -// -// int i = -32; -// for (; i <= 32; i += 4) { -// size_t accurate_offset = get_proc_cmdline_maybe_addr(proc_pid_struct, i, &arg_start); -// -// -// size_t phy_addr = get_proc_phy_addr(proc_pid_struct, arg_start); -// char name[100] = { 0 }; -// -// if (phy_addr) { -// read_ram_physical_addr_to_kernel(phy_addr, &name, sizeof(name)); -// } -// printk(KERN_INFO "test4 get_proc_cmdline_maybe_addr arg_start:0x%llx 0x%llx %s\n", arg_start, phy_addr, name); -// } -// -// -// release_proc_pid_struct(proc_pid_struct); -// } -// -//} -// -// -//static void test5(void) { -// int *pid = x_kmalloc(sizeof(int) * 100, GFP_KERNEL); -// int i = 0; -// int count = get_proc_pid_list(true, (char*)pid, sizeof(int) * 100); -// printk(KERN_INFO "test5 count:%d\n", count); -// -// for (i = 0; i < 100; i++) { -// if (!!pid[i]) { -// printk(KERN_INFO "test5 pid[%d]:%d\n", i, pid[i]); -// } -// } -// -// -// kfree(pid); -// -//} -// -//static void test6(void) { -// int ret = 0; -// struct pid * proc_pid_struct = get_proc_pid_struct(17597); -// -// printk(KERN_INFO "test6 get_proc_pid_struct:%ld\n", proc_pid_struct); -// -// ret = set_process_root(proc_pid_struct); -// -// printk(KERN_INFO "test6 ret:%d\n", ret); -// -// release_proc_pid_struct(proc_pid_struct); -// -//} -// -//static void test7(void) { -// struct pid * proc_pid_struct = get_proc_pid_struct(11533); -// size_t ret = read_proc_rss_size(proc_pid_struct); -// -// printk(KERN_INFO "test7 get_proc_pid_struct:%ld, ret:%zu\n", proc_pid_struct, ret); -// -// release_proc_pid_struct(proc_pid_struct); -// -//} -// -//static void test8(void) { -// struct pid * proc_pid_struct = get_proc_pid_struct(17597); -// printk(KERN_INFO "test8 get_proc_pid_struct:%ld\n", proc_pid_struct); -// if (proc_pid_struct) { -// size_t arg_start = 0, arg_end = 0; -// int res = get_proc_cmdline_addr(proc_pid_struct, &arg_start, &arg_end); -// printk(KERN_INFO "test8 get_proc_cmdline_addr arg_start:0x%llx arg_end:0x%llx\n", arg_start, arg_end); -// release_proc_pid_struct(proc_pid_struct); -// } -// -//} -// -//static void test9(void) { -// struct pid * proc_pid_struct = get_proc_pid_struct(14861); -// printk(KERN_INFO "test9 get_proc_pid_struct:%ld\n", proc_pid_struct); -// if (proc_pid_struct) { -// -// //set_process_root(proc_pid_struct); -// -// release_proc_pid_struct(proc_pid_struct); -// } -// -//} - -#endif /* TEST_H_ */ \ No newline at end of file diff --git a/code/ver_control.h b/code/ver_control.h deleted file mode 100644 index c6cc986..0000000 --- a/code/ver_control.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef VERSION_CONTROL_H_ -#define VERSION_CONTROL_H_ - -// 独立内核模块入口模式 -#define CONFIG_MODULE_GUIDE_ENTRY - -// 生成proc用户层交互节点文件 -#define CONFIG_USE_PROC_FILE_NODE -// 隐蔽通信密钥 -#define CONFIG_PROC_NODE_AUTH_KEY "c2a2b5792edd296763fdfc72cff44380" - -// 打印内核调试信息 -//#define CONFIG_DEBUG_PRINTK - -#ifndef KERNEL_VERSION -#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) -#endif -#ifndef MY_LINUX_VERSION_CODE -//#define MY_LINUX_VERSION_CODE KERNEL_VERSION(3,10,0) -//#define MY_LINUX_VERSION_CODE KERNEL_VERSION(3,10,84) -//#define MY_LINUX_VERSION_CODE KERNEL_VERSION(3,18,71) -//#define MY_LINUX_VERSION_CODE KERNEL_VERSION(3,18,140) -//#define MY_LINUX_VERSION_CODE KERNEL_VERSION(4,4,21) -//#define MY_LINUX_VERSION_CODE KERNEL_VERSION(4,4,78) -//#define MY_LINUX_VERSION_CODE KERNEL_VERSION(4,4,153) -//#define MY_LINUX_VERSION_CODE KERNEL_VERSION(4,4,192) -//#define MY_LINUX_VERSION_CODE KERNEL_VERSION(4,9,112) -//#define MY_LINUX_VERSION_CODE KERNEL_VERSION(4,9,186) -//#define MY_LINUX_VERSION_CODE KERNEL_VERSION(4,14,83) -//#define MY_LINUX_VERSION_CODE KERNEL_VERSION(4,14,117) -//#define MY_LINUX_VERSION_CODE KERNEL_VERSION(4,14,141) -//#define MY_LINUX_VERSION_CODE KERNEL_VERSION(4,19,81) -//#define MY_LINUX_VERSION_CODE KERNEL_VERSION(4,19,113) -//#define MY_LINUX_VERSION_CODE KERNEL_VERSION(5,4,61) -//#define MY_LINUX_VERSION_CODE KERNEL_VERSION(5,10,43) -#define MY_LINUX_VERSION_CODE KERNEL_VERSION(5,15,41) -//#define MY_LINUX_VERSION_CODE KERNEL_VERSION(6,1,75) -//#define MY_LINUX_VERSION_CODE KERNEL_VERSION(6,6,30) -#endif - -#ifdef CONFIG_DEBUG_PRINTK -#define printk_debug printk -#else -static inline void printk_debug(char *fmt, ...) {} -#endif - -#endif /* VERSION_CONTROL_H_ */