我会试着总结一下,但这会很复杂。
我在我的大学里有一个操作系统课程,我有一个实验室工作要做。我在 Rust 工作(据说实验室工作可以用任何编译语言完成,但最初主要是为 C 设计的)。
所以我有一个跟踪程序和一个跟踪程序。
实验室工作这一步的目标是使用 ptrace 从跟踪器附加到跟踪器,然后在合适的地方注入“trap-call-trap”指令以替换现有的无用函数,函数 posix_memalign(来自libc) 在traced中,通过寄存器间接调用(使用 rax)。目标是分配内存以便以后能够将缓存代码从另一个文件调用到被跟踪的程序中。
我遇到的问题是我实现在跟踪器中执行 posix memalign 所以我知道该函数有效,但是当我在跟踪器中调用它时(通过跟踪器),并在寄存器 rax 中查找函数的返回,我总是得到一个对应于 ENOMEM 的“12”(ENOMEM 没有足够的空间/无法分配内存)。
我有 2 个独立的货运项目,以便能够与货运分开启动每个程序。一切都在这个 git 上:https ://github.com/Carrybooo/TP_SEL
很抱歉,所有的印刷品和输出都是法文,(也有一些评论,我正在上法语课程),我认为我不必与任何人分享。其中也有很多无用的代码,来自实验室前面的步骤,我保留了以防万一,所以我的代码不是很干净。
这是我附加和修改 regs 以调用函数的部分(我缩短了代码并且没有向您显示辅助函数声明,因为它会太长):
ptrace::attach(pid_ptrace) //attaching to process
wait(); //wait after attaching
inject(pid_trace, offset_fct_to_replace, false); //injecting trap-call-trap
ptrace::cont(pid_ptrace, Signal::SIGCONT);
wait(); //wait for 1st trap
let mut regs =
ptrace::getregs(pid_ptrace);
let ptr_to_ptr: *mut *mut c_void = ptr::null_mut();
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);
regs.rdi = ptr_to_ptr as u64;
regs.rsi = size_of::<usize>() as u64;
regs.rdx = size_of::<usize>() as u64;
ptrace::setregs(pid_ptrace, regs); //set regs with modification
ptrace::cont(pid_ptrace, Signal::SIGCONT);
wait();
let regs = ptrace::getregs(pid_ptrace);
ptrace::detach(pid_ptrace, Signal::SIGCONT) //detaching
在终端中运行程序会给出这样的结果:
before modification of regs:
rax = 6
rip = 55e6c932ddc1
rsp = 7ffcee0b7fb8
before function execution:
rax = 7f59b935ded0
rdi = 0
rip = 55e6c932ddc1
rsp = 7ffcee0b7fb0
after function execution:
rax = 12 <------//RESULT OF THE CALL IS HERE
rdi = 55e6cac6aba0
rip = 7f59b935df20
rsp = 7ffcee0b7f90
//end of program
所以是的,我不知道为什么我在这个调用中不断收到错误,我认为这是因为它违反了 rust 内存安全,因为编译器在跟踪的程序中从来不知道它必须分配内存,但我不确定它,也没有如何绕过它。我希望我已经足够清楚了,如果您需要更多详细信息,请告诉我,我真的提前感谢任何可以帮助我的人。欢迎任何建议。