Rust ptrace注入调用posix_memalign返回ENOMEM错误排查求助
问题根因
该问题和Rust内存安全机制完全无关,属于posix_memalign调用的传参逻辑错误:posix_memalign的函数原型为 int posix_memalign(void **memptr, size_t alignment, size_t size),其中第一个参数memptr必须指向被跟踪进程(traced)地址空间内的可写内存区域,用来存储分配得到的内存首地址。你当前直接将rdi寄存器设为0(空指针),相当于要求libc把分配结果写入非法的0地址,自然触发分配失败,返回错误码12(ENOMEM)。
修复方案
你代码中已经主动减了rsp预留了8字节(64位下指针大小)的栈空间,这块栈属于traced进程的合法可写内存,直接把这块空间的地址作为memptr传入即可:
// 原有逻辑不变 regs.rax = get_libc_address(pid_trace).unwrap() + get_libc_offset("posix_memalign").unwrap(); regs.rsp = regs.rsp - (size_of::<*mut *mut c_void>() as u64); // 改掉rdi的赋值,用刚预留的栈地址 regs.rdi = regs.rsp; regs.rsi = size_of::<usize>() as u64; regs.rdx = size_of::<usize>() as u64;
调用成功后,你可以通过ptrace读取traced进程中rsp指向的8字节内容,就能拿到分配得到的内存首地址。
额外注意事项
- 注意检查代码中
pid_ptrace和pid_trace是否为同一个值,避免传错进程ID导致异常。 posix_memalign要求第二个参数alignment必须是2的幂,且至少等于sizeof(void*),你当前传入的size_of::<usize>()符合要求,后续调整分配参数时需要遵守该规则。- x86_64 System V ABI要求call执行前栈必须16字节对齐,你当前减rsp后的栈地址符合对齐要求,无需额外调整。
内容的提问来源于stack exchange,提问作者Carryboo
相关产品推荐
相关产品推荐

