diff --git a/README.md b/README.md index 360a760..617641e 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ _ _ _ _ _ _ _ _ \ | apc '._| \__; ``` -![Tests](https://github.com/EFForg/rayhunter/actions/workflows/rust.yml/badge.svg) +![Tests](https://github.com/EFForg/rayhunter/actions/workflows/check-and-test.yml/badge.svg) Rayhunter is an IMSI Catcher Catcher for the Orbic mobile hotspot. Based on code from [QCSuper](https://github.com/P1sec/QCSuper) @@ -89,4 +89,4 @@ Now you can root your device and install rayhunter by running `./install.sh` - * **LEGAL DISCLAIMER:** Use this program at your own risk. We beilieve running this program does not currently violate any laws or regulations in the United States. However, we are not responsible for civil or criminal liability resulting from the use of this software. If you are located outside of the US please consult with an attorney in your country to help you assess the legal risks of running this program. -*Good Hunting!* \ No newline at end of file +*Good Hunting!* diff --git a/bin/src/config.rs b/bin/src/config.rs index ef910ac..c554b02 100644 --- a/bin/src/config.rs +++ b/bin/src/config.rs @@ -7,6 +7,7 @@ struct ConfigFile { qmdl_store_path: Option, port: Option, readonly_mode: Option, + ui_level: Option, } #[derive(Debug)] @@ -14,6 +15,7 @@ pub struct Config { pub qmdl_store_path: String, pub port: u16, pub readonly_mode: bool, + pub ui_level: u8, } impl Default for Config { @@ -22,6 +24,7 @@ impl Default for Config { qmdl_store_path: "/data/rayhunter/qmdl".to_string(), port: 8080, readonly_mode: false, + ui_level: 1, } } } @@ -34,6 +37,7 @@ pub fn parse_config

(path: P) -> Result where P: AsRef if let Some(path) = parsed_config.qmdl_store_path { config.qmdl_store_path = path } if let Some(port) = parsed_config.port { config.port = port } if let Some(readonly_mode) = parsed_config.readonly_mode { config.readonly_mode = readonly_mode } + if let Some(ui_level) = parsed_config.ui_level { config.ui_level = ui_level } } Ok(config) } diff --git a/bin/src/daemon.rs b/bin/src/daemon.rs index c748e34..38d89fb 100644 --- a/bin/src/daemon.rs +++ b/bin/src/daemon.rs @@ -28,6 +28,8 @@ use tokio::sync::oneshot::error::TryRecvError; use tokio::task::JoinHandle; use tokio_util::task::TaskTracker; use std::net::SocketAddr; +use std::thread::sleep; +use std::time::Duration; use tokio::net::TcpListener; use tokio::sync::{RwLock, oneshot}; use std::sync::Arc; @@ -120,7 +122,15 @@ fn run_ctrl_c_thread( }) } -async fn update_ui(task_tracker: &TaskTracker, mut ui_shutdown_rx: oneshot::Receiver<()>){ +async fn update_ui(task_tracker: &TaskTracker, config: &config::Config, mut ui_shutdown_rx: oneshot::Receiver<()>){ + let image = match config.ui_level { + 0 => {info!("silent UI!"); return}, + 1 => "subtle.png", + 2 => "orca.gif", + _ => "orca.gif" + }; + + info!("spawning UI with {}", image); task_tracker.spawn_blocking(move || { let mut fb: Framebuffer = Framebuffer::new(); loop { @@ -133,7 +143,8 @@ async fn update_ui(task_tracker: &TaskTracker, mut ui_shutdown_rx: oneshot::Rece Err(e) => panic!("what the fuck {e}") } - fb.draw_img("/data/rayhunter/orca.gif"); + fb.draw_img(image); + sleep(Duration::from_millis(100)); } }).await.unwrap(); @@ -164,7 +175,7 @@ async fn main() -> Result<(), RayhunterError> { let (server_shutdown_tx, server_shutdown_rx) = oneshot::channel::<()>(); run_ctrl_c_thread(&task_tracker, tx.clone(), server_shutdown_tx, ui_shutdown_tx, qmdl_store_lock.clone()); run_server(&task_tracker, &config, qmdl_store_lock.clone(), server_shutdown_rx, tx).await; - update_ui(&task_tracker, ui_shutdown_rx).await; + update_ui(&task_tracker, &config, ui_shutdown_rx).await; task_tracker.close(); task_tracker.wait().await; diff --git a/bin/src/framebuffer.rs b/bin/src/framebuffer.rs index 45e780d..dae2fd7 100644 --- a/bin/src/framebuffer.rs +++ b/bin/src/framebuffer.rs @@ -1,5 +1,5 @@ -use image::{io::Reader as ImageReader, AnimationDecoder, imageops::FilterType, codecs::gif::GifDecoder, DynamicImage}; -use std::{io::BufReader, fs::File, time::Duration}; +use image::{codecs::gif::GifDecoder, imageops::FilterType, AnimationDecoder, DynamicImage}; +use std::{io::Cursor, time::Duration}; use include_dir::{include_dir, Dir}; const FB_PATH:&str = "/dev/fb0"; @@ -30,9 +30,18 @@ impl Framebuffer<'_>{ fn write(&mut self, img: DynamicImage) { - let resized_img = img.resize( self.dimensions.width, self.dimensions.height, FilterType::CatmullRom); - let width = self.dimensions.width.min(resized_img.width()); - let height = self.dimensions.height.min(resized_img.height()); + let mut width = img.width(); + let mut height = img.height(); + let resized_img: DynamicImage; + if height > self.dimensions.height || + width > self.dimensions.width { + resized_img = img.resize( self.dimensions.width, self.dimensions.height, FilterType::CatmullRom); + width = self.dimensions.width.min(resized_img.width()); + height = self.dimensions.height.min(resized_img.height()); + + } else { + resized_img = img; + } let img_rgba8 = resized_img.as_rgba8().unwrap(); let mut buf = Vec::new(); for y in 0..height { @@ -49,12 +58,11 @@ impl Framebuffer<'_>{ pub fn draw_img(&mut self, img_name: &str) { - //let img_path = IMAGE_DIR.get_file(img_name).unwrap().path(); - let img_path = img_name; - if img_path.ends_with(".gif") { + let img = IMAGE_DIR.get_file(img_name).unwrap(); + if img_name.ends_with(".gif") { // this is dumb and i'm sure there's a better way to loop this - let stream = BufReader::new(File::open(&img_path).unwrap()); - let decoder = GifDecoder::new(stream).unwrap(); + let cursor = Cursor::new(img.contents()); + let decoder = GifDecoder::new(cursor).unwrap(); for maybe_frame in decoder.into_frames() { let frame = maybe_frame.unwrap(); let (numerator, _) = frame.delay().numer_denom_ms(); @@ -63,8 +71,7 @@ impl Framebuffer<'_>{ std::thread::sleep(Duration::from_millis(numerator as u64)); } } else { - let img_reader = ImageReader::open(img_path).unwrap(); - let img = img_reader.decode().unwrap(); + let img = image::load_from_memory(img.contents()).unwrap(); self.write(img); } } diff --git a/bin/static/images/subtle.png b/bin/static/images/subtle.png new file mode 100644 index 0000000..974a576 Binary files /dev/null and b/bin/static/images/subtle.png differ