c语言错误中出现asm,如何解决C语言中内联汇编错误:'重新加载'asm'时无法在类'GENERAL_REGS'中找到寄存器...

博客讨论了在C语言代码中遇到的内联汇编错误,该错误涉及到找不到特定寄存器。文章指出,这个问题可能源于目标架构仅支持有限数量的寄存器,而代码尝试使用的寄存器超过了这个限制。博主寻求解决方案,可能包括减少使用的寄存器数量或者调整代码以适应架构限制。提出了修改寄存器参数为内存参数的建议,但需要更多信息才能给出具体解决策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这是轻量级加密PRESENT算法实现的一部分,针对速度,8位,由C实现,与通过内联汇编实现的算法的pLayer相关。如何解决C语言中内联汇编错误:'重新加载'asm'时无法在类'GENERAL_REGS'中找到寄存器

// ****************** pLayer ******************************

asm volatile("clr %0 \n"

"clr %1 \n"

"clr %2 \n"

"clr %3 \n"

"clr %4 \n"

"clr %5 \n"

"clr %6 \n"

"clr %7 \n"

"sbrc %8,0 \n"

"sbr %0,1 \n"

"sbrc %8,1 \n"

"sbr %2,1 \n"

"sbrc %8,2 \n"

"sbr %4,1 \n"

"sbrc %8,3 \n"

"sbr %6,1 \n"

"sbrc %8,4 \n"

"sbr %0,2 \n"

"sbrc %8,5 \n"

"sbr %2,2 \n"

"sbrc %8,6 \n"

"sbr %4,2 \n"

"sbrc %8,7 \n"

"sbr %6,2 \n"

"sbrc %9,0 \n"

"sbr %0,4 \n"

"sbrc %9,1 \n"

"sbr %2,4 \n"

"sbrc %9,2 \n"

"sbr %4,4 \n"

"sbrc %9,3 \n"

"sbr %6,4 \n"

"sbrc %9,4 \n"

"sbr %0,8 \n"

"sbrc %9,5 \n"

"sbr %2,8 \n"

"sbrc %9,6 \n"

"sbr %4,8 \n"

"sbrc %9,7 \n"

"sbr %6,8 \n"

"sbrc %10,0 \n"

"sbr %0,16 \n"

"sbrc %10,1 \n"

"sbr %2,16 \n"

"sbrc %10,2 \n"

"sbr %4,16 \n"

"sbrc %10,3 \n"

"sbr %6,16 \n"

"sbrc %10,4 \n"

"sbr %0,32 \n"

"sbrc %10,5 \n"

"sbr %2,32 \n"

"sbrc %10,6 \n"

"sbr %4,32 \n"

"sbrc %10,7 \n"

"sbr %6,32 \n"

"sbrc %11,0 \n"

"sbr %0,64 \n"

"sbrc %11,1 \n"

"sbr %2,64 \n"

"sbrc %11,2 \n"

"sbr %4,64 \n"

"sbrc %11,3 \n"

"sbr %6,64 \n"

"sbrc %11,4 \n"

"sbr %0,128 \n"

"sbrc %11,5 \n"

"sbr %2,128 \n"

"sbrc %11,6 \n"

"sbr %4,128 \n"

"sbrc %11,7 \n"

"sbr %6,128 \n"

"sbrc %12,0 \n"

"sbr %1,1 \n"

"sbrc %12,1 \n"

"sbr %3,1 \n"

"sbrc %12,2 \n"

"sbr %5,1 \n"

"sbrc %12,3 \n"

"sbr %7,1 \n"

"sbrc %12,4 \n"

"sbr %1,2 \n"

"sbrc %12,5 \n"

"sbr %3,2 \n"

"sbrc %12,6 \n"

"sbr %5,2 \n"

"sbrc %12,7 \n"

"sbr %7,2 \n"

"sbrc %13,0 \n"

"sbr %1,4 \n"

"sbrc %13,1 \n"

"sbr %3,4 \n"

"sbrc %13,2 \n"

"sbr %5,4 \n"

"sbrc %13,3 \n"

"sbr %7,4 \n"

"sbrc %13,4 \n"

"sbr %1,8 \n"

"sbrc %13,5 \n"

"sbr %3,8 \n"

"sbrc %13,6 \n"

"sbr %5,8 \n"

"sbrc %13,7 \n"

"sbr %7,8 \n"

"sbrc %14,0 \n"

"sbr %1,16 \n"

"sbrc %14,1 \n"

"sbr %3,16 \n"

"sbrc %14,2 \n"

"sbr %5,16 \n"

"sbrc %14,3 \n"

"sbr %7,16 \n"

"sbrc %14,4 \n"

"sbr %1,32 \n"

"sbrc %14,5 \n"

"sbr %3,32 \n"

"sbrc %14,6 \n"

"sbr %5,32 \n"

"sbrc %14,7 \n"

"sbr %7,32 \n"

"sbrc %15,0 \n"

"sbr %1,64 \n"

"sbrc %15,1 \n"

"sbr %3,64 \n"

"sbrc %15,2 \n"

"sbr %5,64 \n"

"sbrc %15,3 \n"

"sbr %7,64 \n"

"sbrc %15,4 \n"

"sbr %1,128 \n"

"sbrc %15,5 \n"

"sbr %3,128 \n"

"sbrc %15,6 \n"

"sbr %5,128 \n"

"sbrc %15,7 \n"

"sbr %7,128 \n"

:"=&r" (temp_pLayer[0]),"=&r" (temp_pLayer[1]),"=&r" (temp_pLayer[2]),"=&r" (temp_pLayer[3]),"=&r" (temp_pLayer[4]),"=&r" (temp_pLayer[5]),"=&r" (temp_pLayer[6]),"=&r" (temp_pLayer[7])

:"r" (state[0]),"r" (state[1]),"r" (state[2]),"r" (state[3]),"r" (state[4]),"r" (state[5]),"r" (state[6]),"r" (state[7])

);

在发生这个错误代码的编译: “can't find a register in class 'GENERAL_REGS' while reloading 'asm'”

我搜索一下,究其原因,发现了一些数据,但没有得到如何解决这个问题。

是否有任何解决方案来定义一些寄存器的编译器或一些特殊的语法来纠正当前的代码。除了以另一种方式重写代码之外,还有其他方法?

感谢您的帮助。

+1

你的目标是什么架构? –

+1

听起来像您要求的目标体系结构支持的寄存器数量更多。如果hw只支持(比如说)8个寄存器,那么编写一个需要16的asm语句将不起作用。至于如何解决它:使用更少的寄存器。如果不了解更多关于目标架构的信息,难以做出更具体的描述,但要将一些参数从“r”更改为“m”。 –

+0

@duskwuff其实我没有实现代码,也没有任何解释的指令。另外我对这些代码是新的,并且不知道如何改变当前的体系结构。 –

内核源: // SPDX-License-Identifier: GPL-2.0 #include <linux/syscalls.h> #include <linux/pid.h> #include <linux/perf_event.h> #include <linux/hw_breakpoint.h> #include <linux/sched.h> #include <linux/slab.h> #include <linux/percpu.h> #include <linux/wait.h> #include <linux/mutex.h> #include <asm/fpsimd.h> #include <linux/thread_info.h> #include <linux/uaccess.h> #include <asm/ptrace.h> #include <uapi/asm/ptrace.h> #include <linux/sched/signal.h> #include <linux/rcupdate.h> #include <linux/cpumask.h> /** * 寄存器编号与名称映射(核心修复:统一LR寄存器编号) * - X0-X29 → 0-29 * - LR寄存器 → 30 * - PC寄存器 → 31 */ #define REG_X0 0 #define REG_X1 1 #define REG_X2 2 #define REG_X3 3 #define REG_X4 4 #define REG_X5 5 #define REG_X6 6 #define REG_X7 7 #define REG_X8 8 #define REG_X9 9 #define REG_X10 10 #define REG_X11 11 #define REG_X12 12 #define REG_X13 13 #define REG_X14 14 #define REG_X15 15 #define REG_X16 16 #define REG_X17 17 #define REG_X18 18 #define REG_X19 19 #define REG_X20 20 #define REG_X21 21 #define REG_X22 22 #define REG_X23 23 #define REG_X24 24 #define REG_X25 25 #define REG_X26 26 #define REG_X27 27 #define REG_X28 28 #define REG_X29 29 #define REG_LR 30 // LR寄存器固定为30 #define REG_PC 31 /** * 内核与用户态共享的数据结构 * 用于传递寄存器状态和修改结果 */ struct reg_data { int pid; // 目标进程PID int hit_flag; // 断点命中标志(0=未命中,1=命中) int modify_flag; // 修改请求标志(0=无请求,1=有请求) int modify_reg; // 要修改的寄存器编号(0-31) int modify_result; // 修改结果(0=成功, -1=无效寄存器, -2=地址无效) unsigned long long new_val; // 要修改的新值(用户输入) unsigned long long modified_val; // 修改后的实际值(回传用户) struct pt_regs regs; // 通用寄存器组(X0-X30、PC、SP等) struct user_fpsimd_state fp_regs; // 浮点寄存器组 }; // 全局变量 static struct perf_event __percpu **bp = NULL; // 硬件断点句柄(percpu型) static struct reg_data *g_reg_data = NULL; // 共享数据区 static struct mutex reg_mutex; // 保护共享数据的互斥锁 static wait_queue_head_t reg_waitq; // 通知用户态的等待队列 static bool is_initialized = false; // 初始化标志 static bool bp_active = false; // 断点活跃标志 static atomic_t callback_count = ATOMIC_INIT(0); // 活跃回调计数器(防资源提前释放) /** * 断点命中回调函数 * 功能:断点触发保存寄存器状态到共享数据区 */ static void hit_handler(struct perf_event *bp_event, struct perf_sample_data *data, struct pt_regs *regs) { struct user_fpsimd_state fp; // 浮点寄存器状态 struct task_struct *current_task; // 快速检查:断点已取消则直接返回 if (!bp_active) return; atomic_inc(&callback_count); // 增加回调计数 // 检查共享数据区有效性 if (!g_reg_data) { atomic_dec(&callback_count); return; } current_task = current; // 保存浮点寄存器状态(区分用户态/内核态) if (!user_mode(regs)) { fpsimd_save_state(&fp); // 内核态:直接保存 } else { memcpy(&fp, &current_task->thread.uw.fpsimd_state, sizeof(fp)); // 用户态:从进程读取 } // 临界区:更新共享数据 mutex_lock(&reg_mutex); if (g_reg_data) { memcpy(&g_reg_data->regs, regs, sizeof(struct pt_regs)); // 保存通用寄存器 memcpy(&g_reg_data->fp_regs, &fp, sizeof(struct user_fpsimd_state)); // 保存浮点寄存器 g_reg_data->hit_flag = 1; // 标记断点命中 pr_info("断点命中,已更新共享数据(PID:%d)\n", current->pid); } mutex_unlock(&reg_mutex); wake_up_interruptible(&reg_waitq); // 唤醒用户态进程 atomic_dec(&callback_count); // 减少回调计数 } /** * 系统调用:process_mrelease(调用号448) * 功能:设置/取消断点、修改寄存器、数据交互 */ SYSCALL_DEFINE4(process_mrelease, int, pid, unsigned long long, addr, int, len, int, type) { struct perf_event_attr attr = {}; // 断点属性配置 struct pid *pid_struct = NULL; // 目标进程PID结构体 struct task_struct *tsk = NULL; // 目标进程结构体 int ret = 0; // 系统调用返回值 int cpu; // 初始化同步机制(仅首次调用) if (!is_initialized) { mutex_init(&reg_mutex); init_waitqueue_head(&reg_waitq); is_initialized = true; } switch (type) { // 处理寄存器修改请求(type=4) case 4: mutex_lock(&reg_mutex); if (g_reg_data && g_reg_data->modify_flag) { int reg = g_reg_data->modify_reg; // 寄存器编号(0-31) unsigned long long val = g_reg_data->new_val; // 新值 unsigned long long *target_reg = NULL; // 目标寄存器指针 // 初始化修改结果 g_reg_data->modify_result = 0; g_reg_data->modified_val = 0; // 解析寄存器编号,定位目标寄存器(核心修复:LR对应30) if (reg == REG_PC) { // PC寄存器(编号31) if (!access_ok((void __user *)val, 4)) { // 验证PC地址有效性 g_reg_data->modify_result = -2; pr_err("修改PC失败:无效地址\n"); goto unlock_modify; } target_reg = &g_reg_data->regs.pc; // PC在pt_regs中的位置 } // 核心修复:LR寄存器明确处理 else if (reg == REG_LR) { // LR寄存器(编号30) target_reg = &g_reg_data->regs.regs[REG_LR]; // LR在regs数组中的位置 } else if (reg >= REG_X0 && reg <= REG_X29) { // X0-X29(编号0-29) target_reg = &g_reg_data->regs.regs[reg]; } else { // 无效编号 g_reg_data->modify_result = -1; pr_err("修改失败:无效寄存器编号 %d\n", reg); goto unlock_modify; } // 执行修改并记录结果 *target_reg = val; g_reg_data->modified_val = val; // 回传实际修改值 g_reg_data->modify_result = 0; // 标记成功 pr_info("修改寄存器成功:编号%d → 0x%llx\n", reg, val); } unlock_modify: g_reg_data->modify_flag = 0; // 清除修改请求 mutex_unlock(&reg_mutex); return ret; // 取消断点(type=5) case 5: { unsigned long flags; if (!bp_active) { pr_info("断点已取消,无需重复操作\n"); return 0; } local_irq_save(flags); // 禁用中断 bp_active = false; // 标记断点失效 // 等待所有回调完成 while (atomic_read(&callback_count) > 0) cpu_relax(); // 释放所有CPU上的断点资源 if (bp && !IS_ERR(bp)) { for_each_possible_cpu(cpu) { struct perf_event **percpu_bp = per_cpu_ptr(bp, cpu); if (*percpu_bp && !IS_ERR(*percpu_bp)) { perf_event_disable(*percpu_bp); unregister_wide_hw_breakpoint(bp); *percpu_bp = NULL; } } free_percpu(bp); bp = NULL; } // 释放共享数据区 mutex_lock(&reg_mutex); if (g_reg_data) { kfree(g_reg_data); g_reg_data = NULL; } mutex_unlock(&reg_mutex); local_irq_restore(flags); // 恢复中断 pr_info("断点已安全取消\n"); return 0; } // 拷贝数据到用户空间(type=6) case 6: if (!g_reg_data || !access_ok((void __user*)addr, sizeof(struct reg_data))) { ret = -EINVAL; pr_err("拷贝数据失败:无效地址\n"); break; } mutex_lock(&reg_mutex); if (copy_to_user((void __user*)addr, g_reg_data, sizeof(struct reg_data))) { ret = -EFAULT; pr_err("拷贝数据失败\n"); } mutex_unlock(&reg_mutex); break; // 重置标志(type=7) case 7: mutex_lock(&reg_mutex); if (g_reg_data) { g_reg_data->hit_flag = 0; g_reg_data->modify_result = 0; g_reg_data->modified_val = 0; } mutex_unlock(&reg_mutex); break; // 核心修复:新增数据设置到内核(type=8) case 8: if (!access_ok((void __user*)addr, sizeof(struct reg_data))) { ret = -EINVAL; pr_err("设置数据失败:无效地址\n"); break; } mutex_lock(&reg_mutex); if (!g_reg_data) { mutex_unlock(&reg_mutex); ret = -EFAULT; pr_err("共享数据区未初始化\n"); break; } if (copy_from_user(g_reg_data, (void __user*)addr, sizeof(struct reg_data))) { mutex_unlock(&reg_mutex); ret = -EFAULT; pr_err("设置数据失败\n"); break; } mutex_unlock(&reg_mutex); pr_info("内核共享数据已更新\n"); break; // 设置硬件断点(type=0-3:读/写/读写/执行) default: { // 清理旧断点 if (bp && !IS_ERR(bp)) { for_each_possible_cpu(cpu) { struct perf_event **percpu_bp = per_cpu_ptr(bp, cpu); if (*percpu_bp && !IS_ERR(*percpu_bp)) { perf_event_disable(*percpu_bp); unregister_wide_hw_breakpoint(bp); *percpu_bp = NULL; } } free_percpu(bp); bp = NULL; } // 初始化共享数据区 if (!g_reg_data) { g_reg_data = kmalloc(sizeof(struct reg_data), GFP_KERNEL); if (!g_reg_data) { ret = -ENOMEM; pr_err("内存分配失败\n"); return ret; } memset(g_reg_data, 0, sizeof(struct reg_data)); g_reg_data->pid = pid; } // 获取目标进程 pid_struct = find_get_pid(pid); if (!pid_struct) { ret = -ESRCH; pr_err("进程不存在:PID=%d\n", pid); break; } tsk = get_pid_task(pid_struct, PIDTYPE_PID); put_pid(pid_struct); if (!tsk || !tsk->mm) { ret = -ESRCH; pr_err("进程已退出:PID=%d\n", pid); break; } // 配置断点属性 hw_breakpoint_init(&attr); attr.bp_addr = addr; // 监控地址 attr.bp_len = (len == 8) ? HW_BREAKPOINT_LEN_8 : HW_BREAKPOINT_LEN_4; // 监控长度 // 设置断点型 switch (type) { case 0: attr.bp_type = HW_BREAKPOINT_R; break; case 1: attr.bp_type = HW_BREAKPOINT_W; break; case 2: attr.bp_type = HW_BREAKPOINT_RW; break; case 3: attr.bp_type = HW_BREAKPOINT_X; break; default: ret = -EINVAL; pr_err("无效断点型(支持0-3)\n"); goto put_task; } // 注册断点 bp = register_wide_hw_breakpoint(&attr, hit_handler, tsk); if (IS_ERR(bp)) { ret = PTR_ERR(bp); bp = NULL; pr_err("断点注册失败:%d\n", ret); goto put_task; } bp_active = true; pr_info("断点注册成功:PID=%d, 地址=0x%llx\n", pid, addr); put_task: put_task_struct(tsk); break; } } return ret; } 用户源; #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <sys/syscall.h> #include <sys/types.h> #include <poll.h> #include <signal.h> #include <stdint.h> // 系统调用号(需与内核一致) #define __NR_process_mrelease 448 /** * 寄存器编号定义(与内核严格一致) */ #define REG_X0 0 #define REG_X1 1 #define REG_X2 2 #define REG_X3 3 #define REG_X4 4 #define REG_X5 5 #define REG_X6 6 #define REG_X7 7 #define REG_X8 8 #define REG_X9 9 #define REG_X10 10 #define REG_X11 11 #define REG_X12 12 #define REG_X13 13 #define REG_X14 14 #define REG_X15 15 #define REG_X16 16 #define REG_X17 17 #define REG_X18 18 #define REG_X19 19 #define REG_X20 20 #define REG_X21 21 #define REG_X22 22 #define REG_X23 23 #define REG_X24 24 #define REG_X25 25 #define REG_X26 26 #define REG_X27 27 #define REG_X28 28 #define REG_X29 29 #define REG_LR 30 // LR寄存器 #define REG_PC 31 // PC寄存器 /** * 浮点寄存器结构(与内核user_fpsimd_state一致) */ struct user_fpsimd_state { uint64_t vregs[32]; // 32个64位浮点寄存器(V0-V31) uint32_t fpsr; // 浮点状态寄存器 uint32_t fpcr; // 浮点控制寄存器 }; /** * 通用寄存器结构(与内核pt_regs一致) */ struct pt_regs { uint64_t regs[31]; // X0-X30(索引0-30,其中30为LR) uint64_t sp; // 栈指针(SP) uint64_t pc; // 程序计数器(PC) uint64_t pstate; // 状态寄存器(PSTATE) }; /** * 共享数据结构(与内核一致) */ struct reg_data { int pid; // 目标进程PID int hit_flag; // 断点命中标志 int modify_flag; // 修改请求标志(1表示有修改请求) int modify_reg; // 要修改的寄存器编号(0-31) int modify_result; // 修改结果(0=成功, -1=无效寄存器, -2=地址无效) uint64_t new_val; // 要修改的新值 uint64_t modified_val; // 修改后的实际值 struct pt_regs regs; // 通用寄存器状态(修改后的值) struct user_fpsimd_state fp_regs; // 浮点寄存器状态 }; /** * 系统调用封装函数 */ static inline int process_mrelease(int pid, uint64_t addr, int len, int type) { return syscall(__NR_process_mrelease, pid, addr, len, type); } /** * 从内核获取寄存器数据(包括修改结果) */ static int get_reg_data(int pid, struct reg_data *data) { return process_mrelease(pid, (uint64_t)data, sizeof(*data), 6); } /** * 向内核发送寄存器修改请求 */ static int set_reg_modify_request(int pid, struct reg_data *data) { // 通过type=8将修改请求传递给内核 return process_mrelease(pid, (uint64_t)data, 0, 8); } /** * 重置断点命中标志和修改结果 */ static void reset_hit_flag(int pid) { process_mrelease(pid, 0, 0, 7); } /** * 将寄存器名称解析为编号(如"X0"→0,"LR"→30) */ static int parse_reg_name(const char *name) { if (strcasecmp(name, "PC") == 0) return REG_PC; if (strcasecmp(name, "LR") == 0) return REG_LR; if (strncasecmp(name, "X", 1) == 0 && strlen(name) > 1) { int idx; if (sscanf(name + 1, "%d", &idx) == 1) { if (idx >= 0 && idx <= 29) return idx; } } return -1; // 无效寄存器 } /** * 将寄存器编号转换为名称(如30→"LR") */ static const char* reg_num_to_name(int num) { if (num == REG_PC) return "PC"; if (num == REG_LR) return "LR"; if (num >= 0 && num <= 29) { static char buf[8]; snprintf(buf, sizeof(buf), "X%d", num); return buf; } return "未知"; } /** * 打印寄存器修改结果 */ static void print_modify_result(struct reg_data *data) { const char *reg_name = reg_num_to_name(data->modify_reg); printf("\n======= 寄存器修改结果 =======\n"); if (data->modify_result == 0) { printf("✅ 修改成功!\n"); printf("寄存器 %s 的新值:%llu (0x%llx)\n", reg_name, data->modified_val, data->modified_val); } else if (data->modify_result == -1) { printf("❌ 修改失败:无效寄存器编号\n"); } else if (data->modify_result == -2) { printf("❌ 修改失败:PC地址无效(不可访问)\n"); } printf("=============================\n"); } /** * 打印断点命中寄存器状态 */ static void print_regs(struct reg_data *data) { printf("\n======= 断点命中 @ PC: 0x%llx =======\n", data->regs.pc); printf("(十六进制地址 | 十进制值)\n"); // 打印X0-X29 printf("\n【64位通用寄存器】\n"); for (int i = 0; i < 30; i++) { printf("%-4s: 0x%llx (%20llu)\n", reg_num_to_name(i), data->regs.regs[i], data->regs.regs[i]); } // 打印LR、SP、PC、PSTATE printf("%-4s: 0x%llx (%20llu)\n", "LR", data->regs.regs[30], data->regs.regs[30]); printf("%-4s: 0x%llx (%20llu)\n", "SP", data->regs.sp, data->regs.sp); printf("%-4s: 0x%llx (%20llu)\n", "PC", data->regs.pc, data->regs.pc); printf("%-4s: 0x%llx (状态寄存器)\n", "PSTATE", data->regs.pstate); printf("=========================================\n"); } /** * 询问用户是否取消断点 */ static int ask_cancel_breakpoint(int pid) { char input[16]; printf("\n是否取消当前断点?(y/n): "); if (!fgets(input, sizeof(input), stdin)) { fprintf(stderr, "输入错误,继续监控...\n"); return 0; } if (input[0] == 'y' || input[0] == 'Y') { process_mrelease(pid, 0, 0, 5); // 发送取消断点命令 printf("已取消断点,退出程序\n"); return 1; } return 0; } /** * 信号处理函数(Ctrl+C取消断点) */ static void sigint_handler(int signum) { process_mrelease(0, 0, 0, 5); // 取消所有断点 exit(0); } int main() { int pid, type, len = 8; // len=8表示监控8字节地址 uint64_t addr; // 断点监控的地址 char input[256]; // 用户输入缓冲区 struct reg_data *user_data = NULL; // 用户态共享数据结构体 int ret = 0; // 注册信号处理(Ctrl+C清理断点) signal(SIGINT, sigint_handler); // 分配用户态共享数据内存 user_data = (struct reg_data*)malloc(sizeof(struct reg_data)); if (!user_data) { fprintf(stderr, "内存分配失败\n"); return 1; } memset(user_data, 0, sizeof(struct reg_data)); // 获取用户输入(目标进程PID、监控地址、断点型) printf("===== Linux内核硬件断点调试工具 =====\n"); printf("目标进程PID: "); if (!fgets(input, sizeof(input), stdin) || sscanf(input, "%d", &pid) != 1) { fprintf(stderr, "无效PID\n"); goto cleanup; } printf("监控地址(0x开头): "); if (!fgets(input, sizeof(input), stdin) || sscanf(input, "0x%llx", &addr) != 1) { fprintf(stderr, "无效地址\n"); goto cleanup; } printf("断点型(0-3,提示:0=读 1=写 2=读写 3=执行): "); if (!fgets(input, sizeof(input), stdin) || sscanf(input, "%d", &type) != 1 || type < 0 || type > 3) { fprintf(stderr, "无效型\n"); goto cleanup; } // 设置硬件断点 ret = process_mrelease(pid, addr, len, type); if (ret < 0) { perror("设置断点失败"); goto cleanup; } printf("\n等待断点命中...(输入Q退出)\n"); // 主循环:等待断点命中并处理 while (1) { struct pollfd pfd = {.fd = STDIN_FILENO, .events = POLLIN}; int ready = poll(&pfd, 1, 500); // 等待用户输入或超 // 从内核获取寄存器数据(检查是否命中断点) struct reg_data kernel_data; memset(&kernel_data, 0, sizeof(kernel_data)); ret = get_reg_data(pid, &kernel_data); if (ret < 0) continue; // 断点命中:处理寄存器显示和修改 if (kernel_data.hit_flag) { memcpy(user_data, &kernel_data, sizeof(struct reg_data)); print_regs(user_data); // 打印当前寄存器状态 // 询问用户是否修改寄存器 printf("\n是否修改寄存器?(y/n): "); if (!fgets(input, sizeof(input), stdin)) { reset_hit_flag(pid); // 重置命中标志 if (ask_cancel_breakpoint(pid)) break; continue; } if (input[0] == 'y' || input[0] == 'Y') { // 获取要修改的寄存器名称 printf("请输入寄存器名称(X0-X29、LR、PC): "); if (!fgets(input, sizeof(input), stdin)) { reset_hit_flag(pid); if (ask_cancel_breakpoint(pid)) break; continue; } input[strcspn(input, "\n")] = 0; // 去除换行符 // 解析寄存器编号 int reg_idx = parse_reg_name(input); if (reg_idx < 0) { fprintf(stderr, "无效寄存器名称\n"); reset_hit_flag(pid); if (ask_cancel_breakpoint(pid)) break; continue; } // 获取要修改的新值 printf("请输入新值(十进制或0x十六进制): "); if (!fgets(input, sizeof(input), stdin)) { reset_hit_flag(pid); if (ask_cancel_breakpoint(pid)) break; continue; } // 解析输入的数值(支持十进制和十六进制) uint64_t new_val; char *endptr; if (strncasecmp(input, "0x", 2) == 0) { new_val = strtoull(input + 2, &endptr, 16); // 十六进制 } else { new_val = strtoull(input, &endptr, 10); // 十进制 } if (*endptr != '\n' && *endptr != '\0') { // 检查解析是否成功 fprintf(stderr, "无效数值\n"); reset_hit_flag(pid); if (ask_cancel_breakpoint(pid)) break; continue; } // 构造修改请求(设置标志、寄存器编号、新值) struct reg_data modify_req; memset(&modify_req, 0, sizeof(modify_req)); modify_req.pid = pid; modify_req.modify_flag = 1; // 标记有修改请求 modify_req.modify_reg = reg_idx; modify_req.new_val = new_val; // 发送修改请求到内核(内核会在下次断点命中处理) ret = set_reg_modify_request(pid, &modify_req); if (ret < 0) { perror("发送修改请求失败"); reset_hit_flag(pid); if (ask_cancel_breakpoint(pid)) break; continue; } printf("修改请求已发送,等待断点命中并执行修改...\n"); } // 重置命中标志,准备下一次监控 reset_hit_flag(pid); // 询问是否取消断点 if (ask_cancel_breakpoint(pid)) break; } // 检查用户是否输入Q退出 if (ready > 0 && (pfd.revents & POLLIN)) { if (fgets(input, sizeof(input), stdin) && input[0] == 'Q') { process_mrelease(pid, 0, 0, 5); // 取消断点 printf("已退出程序\n"); break; } } } cleanup: free(user_data); // 释放用户态内存 return ret; } 帮我删除内核和用户源所有修改寄存器操作 仔细阅读linux文档和rwprocmem33 帮我修复好取消断点概率死机崩溃 长间断点死机崩溃 选择只读 写 执行概率死机崩溃 用户源增加自行输入 4 8字节长度 打印寄存器信息对其 只需打印十六进制地址 打印大写寄存器 地址不要出现0x00000开头 只需0x11111111这样 避免太乱 用户源在进行断点后接收所有日志信息 代码已经具备了系统调用 所以你不要乱碰 采用集成到内核中 不使用模块 修复好检查无问题无编译报错后完整发给我两份代码 全程中文注释 中文打印 设备:红米k70 内核:5.15
最新发布
07-24
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值