mod cpu_arch;
mod elf;
mod fetch_ld;
mod libc_deb;
mod libc_version;
pub mod opts;
mod patch_bin;
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("failed detecting libc version (is the libc an Ubuntu glibc?)");
return;
}
};
maybe_fetch_ld(opts, &ver).warn("failed fetching ld");
unstrip_libc(libc, &ver).warn("failed unstripping libc");
}
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.to_string_lossy().bold()).bright_blue()
);
set_exec(bin)?;
}
}
None => "binary not found".warn("failed setting binary to be executable"),
}
Ok(())
}
pub fn set_ld_exec(opts: &Opts) -> io::Result<()> {
match &opts.ld {
Some(ld) if !ld.is_executable() => {
println!(
"{}",
format!("setting {} executable", ld.to_string_lossy().bold()).green()
);
set_exec(ld)
}
_ => Ok(()),
}
}