diff options
author | Santo Cariotti <santo@dcariotti.me> | 2023-10-15 18:56:55 +0200 |
---|---|---|
committer | Santo Cariotti <santo@dcariotti.me> | 2023-10-15 18:56:55 +0200 |
commit | 72664d87d2fb0782ca49a5f2118c64d0cf58e3f7 (patch) | |
tree | 44f2a3e7a39de1e0aa39ff9997fc9b67bc8eb9d6 | |
parent | 2affb3567dc7fb42e97da8d5bc7a6b89bdbceb8d (diff) |
Add the possibility to redirect the output to a file
-rw-r--r-- | src/main.rs | 5 | ||||
-rw-r--r-- | src/trace.rs | 25 |
2 files changed, 25 insertions, 5 deletions
diff --git a/src/main.rs b/src/main.rs index 1859606..1a93aef 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,6 +10,9 @@ use nix::unistd::Pid; struct Args { /// Command to execute from ptrace command: String, + /// Write the output to a file instead of the standard output + #[arg(short = 'f', long = "file")] + file_to_print: Option<String>, } /// Create a fork of the program and execute the process in the child. Parent gets the pid @@ -23,7 +26,7 @@ fn main() -> anyhow::Result<()> { Err(err) => panic!("fork() failed: {err}"), }; - trace(pid)?; + trace(pid, args.file_to_print)?; Ok(()) } diff --git a/src/trace.rs b/src/trace.rs index 04b3ecd..e826c53 100644 --- a/src/trace.rs +++ b/src/trace.rs @@ -6,7 +6,12 @@ use nix::{ }, unistd::Pid, }; -use std::{os::unix::process::CommandExt, process::Command}; +use std::{ + fs::File, + io::{self, Write}, + os::unix::process::CommandExt, + process::Command, +}; /// Exec the `command` value tracing it with `ptrace` lib pub fn exec(command: &String) -> anyhow::Result<()> { @@ -25,7 +30,7 @@ pub fn exec(command: &String) -> anyhow::Result<()> { } /// Trace a process with `pid` ID -pub fn trace(pid: Pid) -> anyhow::Result<()> { +pub fn trace(pid: Pid, file_to_print: Option<String>) -> anyhow::Result<()> { // Since you have to do 2 syscalls (start and end) you have to alternate the print value, // because it could be equals except for the `rax` register. let mut have_to_print = true; @@ -33,6 +38,13 @@ pub fn trace(pid: Pid) -> anyhow::Result<()> { // First wait for the parent process _ = waitpid(pid, None)?; + // If `fiole_to_print` is not None, create a new file with that value for redirecting all the + // output (also in stdout) + let mut f = None; + if let Some(filename) = file_to_print { + f = Some(File::create(filename)?); + } + loop { have_to_print ^= true; ptrace::syscall(pid, None)?; @@ -49,10 +61,15 @@ pub fn trace(pid: Pid) -> anyhow::Result<()> { Signal::SIGTRAP => { let regs = ptrace::getregs(pid)?; if have_to_print { - println!( + let output = format!( "{}({:x}, {:x}, {:x}, ...) = {:x}", - regs.orig_rax, regs.rdi, regs.rsi, regs.rdx, regs.rax, + regs.orig_rax, regs.rdi, regs.rsi, regs.rdx, regs.rax ); + writeln!(io::stdout(), "{output}")?; + + if let Some(ref mut f) = f { + writeln!(f, "{output}")?; + } } } _ => {} |