森侃 2023-12-25 22:18 采纳率: 60%
浏览 14
已结题

Linux转储进程数据段的内核模块编程


#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/highmem.h>
#define TEMP_FILE_NAME "temp_file.txt"

static int pid = 0; // 进程ID
static char *temp_data = NULL; // 用于存储进程内存页面内容的临时缓冲区

static int open_temp_file(struct file *filp) {
    filp = filp_open(TEMP_FILE_NAME, O_WRONLY | O_CREAT, 0644);
    if (IS_ERR(filp)) {
        printk(KERN_ERR "Failed to open temp file\n");
        return PTR_ERR(filp);
    }
    return 0;
}

static void close_temp_file(struct file *filp) {
    filp_close(filp, NULL);
}

static int dump_process_memory(void) {
    struct task_struct *task;
    struct mm_struct *mm;
    struct vm_area_struct *vma;
    int ret = -1;
    struct file *filp = NULL;
    unsigned long addr;

    task = pid_task(find_vpid(pid), PIDTYPE_PID);
    if (task == NULL) {
        printk(KERN_ERR "Invalid process ID\n");
        return -ESRCH;
    }

    mm = task->mm;
    if (mm == NULL) {
        printk(KERN_ERR "No memory map found for the process\n");
        return -EINVAL;
    }

    filp = open_temp_file(filp);
    if (IS_ERR(filp)) {
        return PTR_ERR(filp);
    }

    for (vma = mm->mmap; vma; vma = vma->vm_next) {
        for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE) {
            struct page *page;
            char *data;
            int i;

            page = get_user_pages(task, mm, addr, 0, 1, 0,&vma, NULL);
            if (IS_ERR(page)) {
                printk(KERN_ERR "Failed to get user pages\n");
                ret = PTR_ERR(page);
                goto out;
            }

            for (i = 0; i < PAGE_SIZE; i++) {
                if (data[i] != 0) {
                    // 写入数据到文件
                    kernel_write(filp, &data[i], 1, &filp->f_pos);
                }
            }

            kunmap(page);
        }
    }

    ret = 0;

out:
    if (filp) {
        close_temp_file(filp);
    }
    return ret;
}

static int __init csi_dump_pdata_init(void) {
    // 设置进程ID
    pid = 1234; // 请将1234替换为您要操作的进程ID

    // 执行转储进程内存操作
    if (dump_process_memory() != 0) {
        printk(KERN_ERR "Failed to dump process memory\n");
    }

    return 0;
}

static void __exit csi_dump_pdata_exit(void) {
    // 清理操作
}

module_init(csi_dump_pdata_init);
module_exit(csi_dump_pdata_exit);

错误:
/root/AAAAA/csi_dump_pdata.c:58:20: error: too many arguments to function ‘get_user_pages’
page = get_user_pages(task, mm, addr, 0, 1, 0,&vma, NULL);
这个错误要怎么修改,上下还有警告,都是这一句的警告,求帮忙修改

  • 写回答

1条回答 默认 最新

  • 指尖@韶华 2023-12-26 09:04
    关注

    您好,根据您提供的代码,get_user_pages函数的调用存在错误。get_user_pages函数的原型为:

    long get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, unsigned long nr_pages, int write, int force, struct page **pages, struct vm_area_struct **vmas);
    

    您需要将调用get_user_pages函数的地方修改为符合其原型的调用方式。根据您的代码,应该修改为:

    page = get_user_pages(task, mm, addr, 1, 0, 0, &page, &vma);
    #  请注意,这里将第四个参数nr_pages设置为1,表示获取一个页面。另外,将force参数设置为0,表示不强制获取页面。
    

    希望对您有所帮助。

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 1月19日
  • 创建了问题 12月25日

悬赏问题

  • ¥15 求高通平台Softsim调试经验
  • ¥15 canal如何实现将mysql多张表(月表)采集入库到目标表中(一张表)?
  • ¥15 wpf ScrollViewer实现冻结左侧宽度w范围内的视图
  • ¥15 栅极驱动低侧烧毁MOSFET
  • ¥30 写segy数据时出错3
  • ¥100 linux下qt运行QCefView demo报错
  • ¥50 F1C100S下的红外解码IR_RX驱动问题
  • ¥20 基于matlab的航迹融合 航迹关联 航迹插补
  • ¥15 用Matlab实现图中的光线追迹
  • ¥15 联想笔记本开机出现系统更新界面