// Copyright (C) 2020 "Maxime “pep” Buquet " // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published by the // Free Software Foundation, either version 3 of the License, or (at your // option) any later version. // // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License // for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . use std::convert::TryFrom; use std::fs; use std::path::PathBuf; use pkstrings::PKString; use structopt::StructOpt; #[derive(Debug, StructOpt)] #[structopt(name = "strings", about = "Display printable strings in [file(s)]")] struct Opt { #[structopt(parse(from_os_str), long, short)] files: Vec, } fn print_buffer(offset: usize, buffer: &String) { let trimmed = buffer.trim_matches('_'); if trimmed.len() > 0 { println!("{:#7x}: {}", offset, buffer); } } fn read_data(data: Vec) { let mut buffer = String::new(); let mut last_offset_start: usize = 0; let eos: &[u8] = &[0x50, 0x57, 0x58, 0x5f]; // end of string let mut last_pkstr: PKString = PKString::try_from(&[0x00][..]).unwrap(); for (offset, ord) in data.iter().enumerate() { // Read current chr match PKString::try_from(&[*ord][..]) { Err(_) => { if buffer.len() >= 4 { print_buffer(last_offset_start, &buffer); } buffer.clear(); last_offset_start = offset + 1; }, Ok(pkstr) => { if buffer.len() == 0 { buffer.push_str(String::from(&pkstr).as_str()); last_pkstr = pkstr; } else { let ord = &pkstr.as_slice()[0]; let last_ord: u8 = { let tmp = Vec::::from(last_pkstr.clone()); tmp[tmp.len() - 1] }; if ! eos.contains(ord) && eos.contains(&last_ord) && buffer.len() >= 4 { print_buffer(last_offset_start, &buffer); buffer.clear(); last_offset_start = offset; } buffer.push_str(String::from(&pkstr).as_str()); if buffer.len() > 1 && eos.contains(ord) && eos.contains(&last_ord) && buffer.len() >= 4 { print_buffer(last_offset_start, &buffer); buffer.clear(); last_offset_start = offset + 1; } last_pkstr = pkstr; } }, } } // Print off any remaining buffer if buffer.len() > 0 { print_buffer(last_offset_start, &buffer); } } fn main() { let opt = Opt::from_args(); for file in opt.files { let data: Vec = fs::read(file).unwrap(); read_data(data) } }