panda/plugins/
proc_start_linux.rs

1//! Raw Rust bindings for proc_start_linux plugin
2//!
3//! Not designed to be used directly, but is used internally for:
4//!
5//! * [`on_rec_auxv`](crate::on_rec_auxv)
6use crate::plugin_import;
7use std::os::raw::c_int;
8
9use crate::sys::{target_ulong, CPUState, TranslationBlock};
10
11plugin_import! {
12    static PROC_START_LINUX: ProcStartLinux = extern "proc_start_linux" {
13        callbacks {
14            fn on_rec_auxv(cpu: &mut CPUState, tb: &mut TranslationBlock, auxv: &AuxvValues);
15        }
16    };
17}
18
19pub const MAX_PATH_LEN: u32 = 256;
20pub const MAX_NUM_ARGS: u32 = 10;
21pub const MAX_NUM_ENV: u32 = 20;
22
23/// A struct representing the contents of the Auxilary Vector, the
24/// information provided by the kernel when starting up a new process.
25///
26/// Resources on the auxilary vector:
27/// * <https://lwn.net/Articles/519085/>
28/// * <http://articles.manugarg.com/aboutelfauxiliaryvectors.html>
29#[repr(C)]
30#[derive(Clone)]
31pub struct AuxvValues {
32    pub argc: c_int,
33    pub argv_ptr_ptr: target_ulong,
34    pub arg_ptr: [target_ulong; 10usize],
35    pub argv: [[u8; 256usize]; 10usize],
36    pub envc: c_int,
37    pub env_ptr_ptr: target_ulong,
38    pub env_ptr: [target_ulong; 20usize],
39    pub envp: [[u8; 256usize]; 20usize],
40    pub execfn_ptr: target_ulong,
41    pub execfn: [u8; 256usize],
42    pub phdr: target_ulong,
43    pub entry: target_ulong,
44    pub ehdr: target_ulong,
45    pub hwcap: target_ulong,
46    pub hwcap2: target_ulong,
47    pub pagesz: target_ulong,
48    pub clktck: target_ulong,
49    pub phent: target_ulong,
50    pub phnum: target_ulong,
51    pub base: target_ulong,
52    pub flags: target_ulong,
53    pub uid: target_ulong,
54    pub euid: target_ulong,
55    pub gid: target_ulong,
56    pub egid: target_ulong,
57    pub secure: bool,
58    pub random: target_ulong,
59    pub platform: target_ulong,
60    pub program_header: target_ulong,
61}
62
63impl AuxvValues {
64    pub fn argv(&self) -> Vec<String> {
65        self.argv[..self.argc as usize]
66            .iter()
67            .map(|arg| {
68                String::from_utf8_lossy(&arg[..arg.iter().position(|x| *x == 0).unwrap()])
69                    .into_owned()
70            })
71            .collect()
72    }
73
74    pub fn envp(&self) -> Vec<String> {
75        self.envp[..self.envc as usize]
76            .iter()
77            .map(|env| {
78                String::from_utf8_lossy(&env[..env.iter().position(|x| *x == 0).unwrap()])
79                    .into_owned()
80            })
81            .collect()
82    }
83
84    pub fn execfn(&self) -> String {
85        let execfn = &self.execfn;
86        String::from_utf8_lossy(&execfn[..execfn.iter().position(|x| *x == 0).unwrap()])
87            .into_owned()
88    }
89}
90
91use std::fmt;
92
93struct HexDebug<D: fmt::Debug>(D);
94
95impl<D: fmt::Debug> fmt::Debug for HexDebug<D> {
96    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
97        write!(f, "{:#x?}", self.0)
98    }
99}
100
101impl fmt::Debug for AuxvValues {
102    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103        f.debug_struct("AuxvValues")
104            .field("argc", &self.argc)
105            .field("argv_ptr_ptr", &HexDebug(self.argv_ptr_ptr))
106            .field("arg_ptr", &HexDebug(&self.arg_ptr[..self.argc as usize]))
107            .field("argv", &self.argv())
108            .field("envc", &self.envc)
109            .field("env_ptr_ptr", &HexDebug(self.env_ptr_ptr))
110            .field("env_ptr", &HexDebug(&self.env_ptr[..self.envc as usize]))
111            .field("envp", &self.envp())
112            .field("execfn_ptr", &HexDebug(self.execfn_ptr))
113            .field("execfn", &self.execfn())
114            .field("phdr", &HexDebug(self.phdr))
115            .field("entry", &HexDebug(self.entry))
116            .field("ehdr", &HexDebug(self.ehdr))
117            .field("hwcap", &self.hwcap)
118            .field("hwcap2", &self.hwcap2)
119            .field("pagesz", &HexDebug(self.pagesz))
120            .field("clktck", &self.clktck)
121            .field("phent", &self.phent)
122            .field("phnum", &self.phnum)
123            .field("base", &HexDebug(self.base))
124            .field("flags", &self.flags)
125            .field("uid", &self.uid)
126            .field("euid", &self.euid)
127            .field("gid", &self.gid)
128            .field("egid", &self.egid)
129            .field("secure", &self.secure)
130            .field("random", &HexDebug(self.random))
131            .field("platform", &HexDebug(self.platform))
132            .field("program_header", &HexDebug(self.program_header))
133            .finish()
134    }
135}