Skip to content

Instantly share code, notes, and snippets.

@codic12
Created August 9, 2020 00:43
Show Gist options
  • Save codic12/e954b6153d1376615c61026b113b6fb5 to your computer and use it in GitHub Desktop.
Save codic12/e954b6153d1376615c61026b113b6fb5 to your computer and use it in GitHub Desktop.
use std::{
convert::TryInto,
env, fs,
fs::{File, OpenOptions},
io::{BufRead, BufReader, ErrorKind, Read, Seek, SeekFrom, Write},
path::Path,
process
};
fn main() -> std::io::Result<()> {
let args: Vec<String> = env::args().skip(1).collect();
if args.len() == 0 {
println!("No arguments provided. Please see `binbox help` for more information.");
process::exit(1);
}
if &args[0] == "add" {
if args.len() <= 2 {
println!("The command `add` requires at least 2 arguments: `binbox add <db_file> binary`. Example: `binbox add db.bin ./mybinary.`");
process::exit(1);
}
let db = &args[1].clone();
let mut binaries = args.clone();
binaries.drain(0..2);
if !Path::new(db).exists() {
File::create(db).expect("Unable to create the database file (maybe you don't have the correct permissions?). Try creating it yourself.");
}
for binary in binaries {
let binmap: Vec<u8> = fs::read(&binary)?;
let mut file = OpenOptions::new().append(true).read(true).open(db).unwrap();
let bytes_in_bin = File::open(&binary)?.metadata().unwrap().len();
file.write_all(format!("{}\\0{}\n", &binary, &bytes_in_bin).as_bytes())?;
file.write_all(&binmap)?;
}
} else if &args[0] == "call" || &args[0] == "call" || &args[0] == "run" {
if args.len() != 3 {
println!("The command `call` requires exactly 2 arguments: `binbox call <db_file> binary`. Example: `binbox call db.bin mybinary.`");
process::exit(1);
}
let db = &args[1].clone();
write_binary_to_temp_file(&db, &args[2])?;
}
Ok(())
}
/// Reads a specified number of bytes from a std::fs::File starting at a specified offset.
/// # Arguments
/// * `file_str`: a &str that holds the file name to open.
/// * `offset`: a u64 that holds the offset; the starting point to read bytes. If unsure, pass 0
/// to read from the beginning.
/// * `len`: a usize to specify the number of bytes to read, starting from offset.
fn read_exact_from_offset(file_str: &str, offset: u64, len: usize) -> std::io::Result<Vec<u8>> {
let mut buf = vec![0; len];
let mut file = OpenOptions::new()
.append(true)
.read(true)
.open(file_str)
.unwrap();
file.write_all("\n}".as_bytes())?;
file.seek(SeekFrom::Start(offset))?;
file.read_exact(&mut buf)?;
Ok(buf)
}
fn write_binary_to_temp_file(file_str: &str, bin_str: &str) -> std::io::Result<()> {
let file_data_binding = BufReader::new(File::open(file_str)?)
.lines()
.next()
.unwrap()
.unwrap();
let file_data: Vec<&str> = file_data_binding.split("\\0").collect();
if &bin_str == &file_data[0] {
println!("Specified binary at index zero.");
let offset = file_data.join("\\0").len();
fs::write(
"/tmp/binbox_bin",
read_exact_from_offset(
file_str,
(&offset + 1).try_into().unwrap(),
file_data[1].parse::<usize>().unwrap(),
)?,
)?;
} else {
let mut read_bytes: usize = file_data[1].parse::<usize>().unwrap();
loop {
if let Err(why) = (|| -> Result<(), Box<std::io::Error>> {
let offset = &file_data[1];
read_bytes = read_bytes + 1;
let mut lineterm_reached = false;
let mut line: Vec<u8> = "".as_bytes().to_vec();
let mut refo: Vec<u8>;
while {
refo = read_exact_from_offset(file_str, read_bytes.try_into().unwrap(), 1)?;
for n in refo.iter() {
if (*n as i8) == 0x0A {
lineterm_reached = true;
}
}
lineterm_reached == true
} {}
fs::write("lol", refo)?;
Ok(())
})() {
if why.kind() == ErrorKind::UnexpectedEof {
eprintln!("Reached end of file (ErrorKind::UnexpectedEof) without finding your binary. It seems to not exist in the provided database.");
std::process::exit(1);
} else {
eprintln!("An error occured. This is most likely a bug in the program, please report it with the following debug information:\n{}", why);
process::exit(1);
}
}
}
}
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment