diff --git a/Cargo.lock b/Cargo.lock index d29868d..40f7c94 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -583,6 +583,18 @@ version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +[[package]] +name = "libusb1-sys" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d0e2afce4245f2c9a418511e5af8718bcaf2fa408aefb259504d1a9cb25f27" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linux-raw-sys" version = "0.4.12" @@ -764,6 +776,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" + [[package]] name = "proc-macro-crate" version = "1.3.1" @@ -836,6 +854,20 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +[[package]] +name = "rootshell" +version = "0.1.0" + +[[package]] +name = "rusb" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45fff149b6033f25e825cbb7b2c625a11ee8e6dac09264d49beb125e39aa97bf" +dependencies = [ + "libc", + "libusb1-sys", +] + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -935,6 +967,13 @@ dependencies = [ "serde", ] +[[package]] +name = "serial" +version = "0.1.0" +dependencies = [ + "rusb", +] + [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -1181,6 +1220,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index a019f56..37d1adf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,8 @@ members = [ "orca", + "serial", + "rootshell", "wavehunter", ] resolver = "2" diff --git a/make.sh b/make.sh index af6d329..8195c15 100755 --- a/make.sh +++ b/make.sh @@ -1,3 +1,11 @@ cargo build +# Force a switch into the debug mode to enable ADB +target/x86_64-unknown-linux-gnu/debug/serial AT +adb push target/armv7-unknown-linux-gnueabihf/debug/rootshell /tmp/ +target/x86_64-unknown-linux-gnu/debug/serial "AT+SYSCMD=mv /tmp/rootshell /bin/rootshell" +sleep 1 +target/x86_64-unknown-linux-gnu/debug/serial "AT+SYSCMD=chown root /bin/rootshell" +sleep 1 +target/x86_64-unknown-linux-gnu/debug/serial "AT+SYSCMD=chmod 4755 /bin/rootshell" adb push target/armv7-unknown-linux-gnueabihf/debug/wavehunter /data/wavehunter/wavehunter adb push target/armv7-unknown-linux-gnueabihf/debug/wavehunter-reader /data/wavehunter/wavehunter-reader diff --git a/rootshell/Cargo.toml b/rootshell/Cargo.toml new file mode 100644 index 0000000..52cb6bd --- /dev/null +++ b/rootshell/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rootshell" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/rootshell/src/main.rs b/rootshell/src/main.rs new file mode 100644 index 0000000..b78b168 --- /dev/null +++ b/rootshell/src/main.rs @@ -0,0 +1,15 @@ +use std::process::Command; +use std::os::unix::process::CommandExt; +use std::env; + +fn main() { + let mut args = env::args(); + + // discard argv[0] + let _ = args.next(); + Command::new("/bin/bash") + .args(args) + .uid(0) + .gid(0) + .exec(); +} \ No newline at end of file diff --git a/serial/Cargo.toml b/serial/Cargo.toml new file mode 100644 index 0000000..dd1d59b --- /dev/null +++ b/serial/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "serial" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rusb = "0.9.3" + diff --git a/serial/src/main.rs b/serial/src/main.rs new file mode 100644 index 0000000..72cc6f5 --- /dev/null +++ b/serial/src/main.rs @@ -0,0 +1,117 @@ +use std::str; +use std::thread::sleep; +use std::time::Duration; + +use rusb::{ + Context, DeviceHandle, UsbContext, +}; + +fn main() { + let args: Vec = std::env::args().collect(); + + if args.len() < 2 { + println!("usage: {0} ", args[0]); + return; + } + + match Context::new() { + Ok(mut context) => match open_orbic(&mut context) { + Some(mut handle) => { + send_command(&mut handle, &args[1]) + }, + None => panic!("No Orbic device found"), + }, + Err(e) => panic!("Failed to initialize libusb: {0}", e), + } +} + +fn send_command( + handle: &mut DeviceHandle, + command: &String, +) { + let mut data = String::new(); + data.push_str("\r\n"); + data.push_str(command); + data.push_str("\r\n"); + + let timeout = Duration::from_secs(1); + let mut response = [0; 256]; + match handle.write_control(0x21, 0x22, 3, 1, &[], timeout) { + Ok(_) => match handle.write_bulk(0x2, data.as_bytes(), timeout) { + Ok(_) => match handle.read_bulk(0x82, &mut response, timeout) { + Ok(_) => match handle.read_bulk(0x82, &mut response, timeout) { + Ok(_) => { + let responsestr = str::from_utf8(&response).unwrap(); + if !responsestr.starts_with("\r\nOK\r\n") { + println!("Received unexpected response{0}", responsestr); + } + }, + Err(e) => panic!("Failed to read response: {0}", e), + }, + Err(e) => panic!("Failed to read submitted command: {0}", e), + } + Err(e) => panic!("Failed to write command: {0}", e), + }, + Err(e) => panic!("Failed to send control request: {0}", e), + } +} + +fn switch_device( + handle: &mut DeviceHandle, +) { + // Send a command to switch the device into generic mode, exposing serial + let timeout = Duration::from_secs(1); + match handle.write_control(0xc0, 0xa0, 0, 0, &[], timeout) { + Ok(_) => (), + Err(e) => panic!("Failed to send device switch control request: {0}", e), + } +} + +fn open_orbic( + context: &mut T, +) -> Option> { + match open_device(context, 0x05c6, 0xf601) { + Some(handle) => return Some(handle), + None => (), + } + match open_device(context, 0x11f6, 0x900e) { + Some(mut handle) => switch_device(&mut handle), + None => panic!("No Orbic device detected") + } + + for _ in 1..10 { + match open_device(context, 0x05c6, 0xf601) { + Some(handle) => return Some(handle), + None => (), + } + sleep(Duration::from_secs(10)) + } + panic!("No Orbic device detected") +} + +fn open_device( + context: &mut T, + vid: u16, + pid: u16, +) -> Option> { + let devices = match context.devices() { + Ok(d) => d, + Err(_) => return None, + }; + + for device in devices.iter() { + let device_desc = match device.device_descriptor() { + Ok(d) => d, + Err(_) => continue, + }; + + if device_desc.vendor_id() == vid && device_desc.product_id() == pid { + match device.open() { + Ok(handle) => return Some(handle), + Err(e) => panic!("device found but failed to open: {}", e), + } + } + } + + None +}