1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
mod cpu_arch;
mod elf;
mod fetch_ld;
mod libc_deb;
mod libc_version;
pub mod opts;
mod pwninit;
mod set_exec;
mod solvepy;
mod unstrip_libc;
mod warn;
pub use crate::pwninit::run;
pub use crate::pwninit::Result;
use crate::elf::detect::is_elf;
pub use crate::fetch_ld::fetch_ld;
use crate::libc_version::LibcVersion;
use crate::opts::Opts;
pub use crate::set_exec::set_exec;
pub use crate::unstrip_libc::unstrip_libc;
use crate::warn::Warn;
use crate::warn::WarnResult;
use std::os::unix::ffi::OsStrExt;
use std::path::Path;
use colored::Colorize;
use ex::io;
use is_executable::IsExecutable;
use twoway::find_bytes;
pub fn is_bin(path: &Path) -> elf::detect::Result<bool> {
Ok(is_elf(path)? && !is_libc(path)? && !is_ld(path)?)
}
fn path_contains(path: &Path, pattern: &[u8]) -> bool {
path.file_name()
.map(|name| find_bytes(name.as_bytes(), pattern).is_some())
.unwrap_or(false)
}
pub fn is_libc(path: &Path) -> elf::detect::Result<bool> {
Ok(is_elf(path)? && path_contains(path, b"libc"))
}
pub fn is_ld(path: &Path) -> elf::detect::Result<bool> {
Ok(is_elf(path)? && path_contains(path, b"ld-"))
}
fn maybe_fetch_ld(opts: &Opts, ver: &LibcVersion) -> fetch_ld::Result {
match opts.ld {
Some(_) => Ok(()),
None => fetch_ld(ver),
}
}
fn visit_libc(opts: &Opts, libc: &Path) {
let ver = match LibcVersion::detect(libc) {
Ok(ver) => ver,
Err(err) => {
err.warn();
return;
}
};
maybe_fetch_ld(opts, &ver).warn();
unstrip_libc(libc, &ver).warn();
}
pub fn maybe_visit_libc(opts: &Opts) {
if let Some(libc) = &opts.libc {
visit_libc(opts, &libc)
}
}
pub fn set_bin_exec(opts: &Opts) -> io::Result<()> {
match &opts.bin {
Some(bin) => {
if !bin.is_executable() {
println!(
"{}",
format!("setting {} executable", bin.display())
.bright_blue()
.bold()
);
set_exec(&bin)?;
}
}
None => "binary not found".warn(),
}
Ok(())
}
pub fn set_ld_exec(opts: &Opts) -> io::Result<()> {
match &opts.ld {
Some(ld) if !ld.is_executable() => {
println!(
"{}",
format!("setting {} executable", ld.display())
.green()
.bold()
);
set_exec(&ld)
}
_ => Ok(()),
}
}