build_and_parse/
build_and_parse.rs1use linux_libc_auxv::{
25 AuxVar, AuxVarFlags, InitialLinuxLibcStackLayout, InitialLinuxLibcStackLayoutBuilder,
26};
27
28fn main() {
30 let builder = InitialLinuxLibcStackLayoutBuilder::new()
31 .add_arg_v("./first_arg\0")
33 .add_arg_v("./second_arg")
34 .add_env_v("FOO=BAR\0")
35 .add_env_v("PATH=/bin")
36 .add_aux_v(AuxVar::Sysinfo(0x7ffd000 as *const _))
37 .add_aux_v(AuxVar::HwCap(0x1000))
38 .add_aux_v(AuxVar::Clktck(100))
39 .add_aux_v(AuxVar::Phdr(0x5627e17 as *const _))
40 .add_aux_v(AuxVar::Phent(56))
41 .add_aux_v(AuxVar::Phnum(13))
42 .add_aux_v(AuxVar::Base(0x7f51000 as *const _))
43 .add_aux_v(AuxVar::Flags(AuxVarFlags::empty()))
44 .add_aux_v(AuxVar::Entry(0x5627e17 as *const _))
45 .add_aux_v(AuxVar::Uid(1001))
46 .add_aux_v(AuxVar::EUid(1001))
47 .add_aux_v(AuxVar::Gid(1001))
48 .add_aux_v(AuxVar::EGid(1001))
49 .add_aux_v(AuxVar::Secure(false))
50 .add_aux_v(AuxVar::Random([
51 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
52 ]))
53 .add_aux_v(AuxVar::HwCap2(0x2))
54 .add_aux_v(AuxVar::ExecFn("/usr/bin/foo"))
55 .add_aux_v(AuxVar::Platform("x86_64"));
56
57 let mut buf = vec![0; builder.total_size()];
59
60 let user_base_addr = 0x1000;
64 unsafe {
65 builder.serialize_into_buf(buf.as_mut_slice(), user_base_addr);
66 }
67
68 let parsed = InitialLinuxLibcStackLayout::from(buf.as_slice());
71
72 println!("There are {} arguments.", parsed.argc());
73 println!(
74 "There are {} environment variables.",
75 parsed.envv_ptr_iter().count()
76 );
77 println!(
78 "There are {} auxiliary vector entries/AT variables.",
79 parsed.aux_serialized_iter().count()
80 );
81
82 println!("===== 1/2: only pointers");
83 parse_memory_safe(&parsed);
84
85 if user_base_addr == buf.as_ptr() as u64 {
86 println!("===== 2/2: dereferenced data");
87 unsafe {
89 parse_memory_unsafe(&parsed);
90 }
91 }
92}
93
94fn parse_memory_safe(parsed: &InitialLinuxLibcStackLayout) {
95 println!(" argv");
96 for (i, arg) in parsed.argv_ptr_iter().enumerate() {
98 println!(" [{}] @ {:?}", i, arg);
99 }
100
101 println!(" envp");
102 for (i, env) in parsed.envv_ptr_iter().enumerate() {
104 println!(" [{}] @ {:?}", i, env);
105 }
106
107 println!(" aux");
108 for aux in parsed.aux_serialized_iter() {
110 println!(" {:?} => {:?}", aux.key(), aux.val() as *const u8);
111 }
112}
113
114unsafe fn parse_memory_unsafe(parsed: &InitialLinuxLibcStackLayout) {
117 println!(" argv");
118 for (i, arg) in parsed.argv_iter().enumerate() {
120 println!(" [{}] {}", i, arg);
121 }
122
123 println!(" envp");
124 for (i, env) in parsed.envv_iter().enumerate() {
126 println!(" [{}] {}", i, env);
127 }
128
129 println!(" aux");
130 for aux in parsed.aux_var_iter() {
131 if let Some(bytes) = aux.value_payload_bytes() {
133 println!(
134 " {:>12?} => @ {:?}: {:?}",
135 aux.key(),
136 aux.value_raw() as *const u8,
137 bytes,
138 );
139 } else if let Some(cstr) = aux.value_payload_cstr() {
140 println!(
141 " {:>12?} => @ {:?}: {:?}",
142 aux.key(),
143 aux.value_raw() as *const u8,
144 cstr,
145 );
146 } else if let Some(flags) = aux.value_flags() {
147 println!(" {:>12?} => {:?}", aux.key(), flags,);
148 } else if let Some(boolean) = aux.value_boolean() {
149 println!(" {:>12?} => {:?}", aux.key(), boolean,);
150 } else if let Some(ptr) = aux.value_ptr() {
151 println!(" {:>12?} => {:?}", aux.key(), ptr,);
152 } else {
153 println!(" {:>12?} => {}", aux.key(), aux.value_raw());
154 }
155 }
156}