Environment variable injector
#![feature(getpid)] | |
use std::process::{self, Command, Output, Stdio}; | |
use std::result; | |
use std::io::{self, BufRead, Write}; | |
use std::num::ParseIntError; | |
use std::fs::File; | |
type Result<T> = result::Result<T, Box<io::Error>>; | |
fn main() { | |
let pppid = getpppid().unwrap(); | |
_inject_env_var(pppid, "TEST", "haha"); | |
} | |
fn getpppid() -> Result<u32> { | |
let mut pid: Result<u32>; | |
pid = Ok(process::id()); | |
for _ in 0..1 { | |
let pid_loc = pid.unwrap(); | |
let file = File::open(&format!("/proc/{}/status", pid_loc))?; | |
let buf = io::BufReader::new(file); | |
let ppid_out = buf.lines() | |
.filter_map(|l| match l { | |
Ok(x) => { | |
if x.contains("PPid:") { | |
return Some(x); | |
} | |
None | |
} | |
_ => None, | |
}) | |
.collect::<Vec<String>>() | |
.join(""); | |
pid = match ppid_out.split_whitespace().last() { | |
Some(x) => x.parse::<u32>().map_err(io_errorify), | |
None => panic!(), | |
}; | |
} | |
pid | |
} | |
fn _inject_env_var(pid: u32, k: &str, v: &str) { | |
let gdb_in = format!("attach {}\ncall putenv (\"{}={}\")\ndetach\n", pid, k, v); | |
_exec(&format!("gdb"), Some(&gdb_in)).unwrap(); | |
} | |
fn io_errorify(e: ParseIntError) -> Box<io::Error> { | |
Box::new(io::Error::new(io::ErrorKind::Other, e)) | |
} | |
fn _exec(command: &str, stdin: Option<&str>) -> Result<Output> { | |
let mut cmd = Command::new("sh"); | |
cmd.arg("-c").arg(command); | |
cmd.stdin(Stdio::piped()); | |
let mut chld = cmd.spawn().unwrap(); | |
if let Some(contents) = stdin { | |
chld.stdin | |
.as_mut() | |
.unwrap() | |
.write_all(contents.as_bytes()) | |
.unwrap(); | |
} | |
chld.wait_with_output().map_err(Box::new) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment