Compare commits

...

9 Commits

Author SHA1 Message Date
Will Greenberg f6681a3703 Merge pull request #54 from EFForg/mac-bugfix
bugfix for mac install process
2024-08-05 10:11:59 -07:00
Cooper Quintin d6bc307a81 bugfix for mac install process 2024-08-05 10:10:41 -07:00
Will Greenberg 7cbb3369d8 serial: when rooting, don't panic if device is already rooted 2024-08-05 09:57:09 -07:00
Will Greenberg cb3dbff54a install-common: wait for atfwd_daemon to startup
We can't successfully run any AT commands until it has.
2024-08-05 09:57:09 -07:00
Will Greenberg 65e1cd4967 serial: split out --root process, don't wait for reboot, update usage text
We need to wait for atfwd_daemon to startup before sending any AT
commands, and I can't think of a way to reliably do that within rust.
So, instead of trying to switch the device to command mode before
executing a command, require the user to run the "--root" step
beforehand, and then start executing AT commands.
2024-08-05 09:57:09 -07:00
Will Greenberg d6fb54afb3 lib: rm unused imports 2024-08-05 09:57:09 -07:00
Will Greenberg bc93c01890 bin: rm deprecated tempdir crate 2024-08-05 09:57:09 -07:00
Will Greenberg be2d70325d Merge pull request #52 from EFForg/update-docs
fix timeout bug in rooting script and update docs
2024-08-02 14:46:51 -07:00
Cooper Quintin 5c4bd161fa fix timeout bug in rooting script and update docs 2024-08-02 14:45:55 -07:00
10 changed files with 185 additions and 213 deletions
Generated
+46 -61
View File
@@ -638,6 +638,16 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
dependencies = [
"libc",
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "exr" name = "exr"
version = "1.72.0" version = "1.72.0"
@@ -654,6 +664,12 @@ dependencies = [
"zune-inflate", "zune-inflate",
] ]
[[package]]
name = "fastrand"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
[[package]] [[package]]
name = "fdeflate" name = "fdeflate"
version = "0.3.4" version = "0.3.4"
@@ -697,12 +713,6 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
[[package]] [[package]]
name = "funty" name = "funty"
version = "2.0.0" version = "2.0.0"
@@ -1160,6 +1170,12 @@ dependencies = [
"vcpkg", "vcpkg",
] ]
[[package]]
name = "linux-raw-sys"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
[[package]] [[package]]
name = "lock_api" name = "lock_api"
version = "0.4.11" version = "0.4.11"
@@ -1545,19 +1561,6 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
[[package]]
name = "rand"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
dependencies = [
"fuchsia-cprng",
"libc",
"rand_core 0.3.1",
"rdrand",
"winapi",
]
[[package]] [[package]]
name = "rand" name = "rand"
version = "0.8.5" version = "0.8.5"
@@ -1566,7 +1569,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [ dependencies = [
"libc", "libc",
"rand_chacha", "rand_chacha",
"rand_core 0.6.4", "rand_core",
] ]
[[package]] [[package]]
@@ -1576,24 +1579,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [ dependencies = [
"ppv-lite86", "ppv-lite86",
"rand_core 0.6.4", "rand_core",
] ]
[[package]]
name = "rand_core"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
dependencies = [
"rand_core 0.4.2",
]
[[package]]
name = "rand_core"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
[[package]] [[package]]
name = "rand_core" name = "rand_core"
version = "0.6.4" version = "0.6.4"
@@ -1629,7 +1617,7 @@ dependencies = [
"once_cell", "once_cell",
"paste", "paste",
"profiling", "profiling",
"rand 0.8.5", "rand",
"rand_chacha", "rand_chacha",
"simd_helpers", "simd_helpers",
"system-deps", "system-deps",
@@ -1691,7 +1679,7 @@ dependencies = [
"rayhunter", "rayhunter",
"serde", "serde",
"serde_json", "serde_json",
"tempdir", "tempfile",
"thiserror", "thiserror",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
@@ -1719,15 +1707,6 @@ dependencies = [
"crossbeam-utils", "crossbeam-utils",
] ]
[[package]]
name = "rdrand"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
dependencies = [
"rand_core 0.3.1",
]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.4.1" version = "0.4.1"
@@ -1766,15 +1745,6 @@ version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]]
name = "remove_dir_all"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
dependencies = [
"winapi",
]
[[package]] [[package]]
name = "rgb" name = "rgb"
version = "0.8.37" version = "0.8.37"
@@ -1807,6 +1777,19 @@ version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "rustix"
version = "0.38.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
dependencies = [
"bitflags 2.6.0",
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "rustversion" name = "rustversion"
version = "1.0.14" version = "1.0.14"
@@ -2031,13 +2014,15 @@ dependencies = [
] ]
[[package]] [[package]]
name = "tempdir" name = "tempfile"
version = "0.3.7" version = "3.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
dependencies = [ dependencies = [
"rand 0.4.6", "cfg-if",
"remove_dir_all", "fastrand",
"rustix",
"windows-sys 0.52.0",
] ]
[[package]] [[package]]
+3 -3
View File
@@ -36,7 +36,7 @@ linux/qualcom devices but this is the only one we have tested on. Buy the orbic
## Setup ## Setup
1. Install the Android Debug Bridge (ADB) on your computer (don't worry about instructions for installing it on a phone/device yet). You can find instructions for doing so on your platform [here](https://www.xda-developers.com/install-adb-windows-macos-linux/#how-to-set-up-adb-on-your-computer). 1. Install the Android Debug Bridge (ADB) on your computer (don't worry about instructions for installing it on a phone/device yet). You can find instructions for doing so on your platform [here](https://www.xda-developers.com/install-adb-windows-macos-linux/#how-to-set-up-adb-on-your-computer).
2. Download the latest [rayhunter release bundle](https://github.com/EFForg/rayhunter/releases) and unzip it. 2. Download the latest [rayhunter release bundle](https://github.com/EFForg/rayhunter/releases) and extract it (on Windows use 7zip).
3. Run the install script inside the bundle corresponding to your platform (`install-linux.sh`, `install-mac.sh`). 3. Run the install script inside the bundle corresponding to your platform (`install-linux.sh`, `install-mac.sh`).
4. Once finished, rayhunter should be running! You can verify this by visiting the web UI as described below. 4. Once finished, rayhunter should be running! You can verify this by visiting the web UI as described below.
@@ -61,9 +61,9 @@ rustup target add x86_64-unknown-linux-gnu
rustup target add armv7-unknown-linux-gnueabihf rustup target add armv7-unknown-linux-gnueabihf
``` ```
Now you can root your device and install rayhunter by running `./install.sh` - **Note:** You will have to install the cross compile tooling below before running this. Now you can root your device and install rayhunter by running `./tools/install-dev.sh`
### If you aren't on linux or can't run the install scripts ### If you are on windows or can't run the install scripts
* Root your device on windows using the instructions here: https://xdaforums.com/t/resetting-verizon-orbic-speed-rc400l-firmware-flash-kajeet.4334899/#post-87855183 * Root your device on windows using the instructions here: https://xdaforums.com/t/resetting-verizon-orbic-speed-rc400l-firmware-flash-kajeet.4334899/#post-87855183
* Build for arm using `cargo build` * Build for arm using `cargo build`
+1 -1
View File
@@ -25,10 +25,10 @@ tokio-util = { version = "0.7.10", features = ["rt"] }
futures-macro = "0.3.30" futures-macro = "0.3.30"
include_dir = "0.7.3" include_dir = "0.7.3"
mime_guess = "2.0.4" mime_guess = "2.0.4"
tempdir = "0.3.7"
chrono = { version = "0.4.31", features = ["serde"] } chrono = { version = "0.4.31", features = ["serde"] }
tokio-stream = "0.1.14" tokio-stream = "0.1.14"
futures = "0.3.30" futures = "0.3.30"
clap = { version = "4.5.2", features = ["derive"] } clap = { version = "4.5.2", features = ["derive"] }
serde_json = "1.0.114" serde_json = "1.0.114"
image = "0.25.1" image = "0.25.1"
tempfile = "3.10.1"
+8 -4
View File
@@ -203,12 +203,16 @@ impl RecordingStore {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use tempdir::TempDir; use tempfile::{TempDir, Builder};
use super::*; use super::*;
fn make_temp_dir() -> TempDir {
Builder::new().prefix("qmdl_store_test").tempdir().unwrap()
}
#[tokio::test] #[tokio::test]
async fn test_load_from_empty_dir() { async fn test_load_from_empty_dir() {
let dir = TempDir::new("qmdl_store_test").unwrap(); let dir = make_temp_dir();
assert!(!RecordingStore::exists(dir.path()).await.unwrap()); assert!(!RecordingStore::exists(dir.path()).await.unwrap());
let _created_store = RecordingStore::create(dir.path()).await.unwrap(); let _created_store = RecordingStore::create(dir.path()).await.unwrap();
assert!(RecordingStore::exists(dir.path()).await.unwrap()); assert!(RecordingStore::exists(dir.path()).await.unwrap());
@@ -218,7 +222,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_creating_updating_and_closing_entries() { async fn test_creating_updating_and_closing_entries() {
let dir = TempDir::new("qmdl_store_test").unwrap(); let dir = make_temp_dir();
let mut store = RecordingStore::create(dir.path()).await.unwrap(); let mut store = RecordingStore::create(dir.path()).await.unwrap();
let _ = store.new_entry().await.unwrap(); let _ = store.new_entry().await.unwrap();
let entry_index = store.current_entry.unwrap(); let entry_index = store.current_entry.unwrap();
@@ -237,7 +241,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_repeated_new_entries() { async fn test_repeated_new_entries() {
let dir = TempDir::new("qmdl_store_test").unwrap(); let dir = make_temp_dir();
let mut store = RecordingStore::create(dir.path()).await.unwrap(); let mut store = RecordingStore::create(dir.path()).await.unwrap();
let _ = store.new_entry().await.unwrap(); let _ = store.new_entry().await.unwrap();
let entry_index = store.current_entry.unwrap(); let entry_index = store.current_entry.unwrap();
+20 -15
View File
@@ -1,5 +1,4 @@
#!/bin/env bash #!/bin/env bash
install() { install() {
if [[ -z "${SERIAL_PATH}" ]]; then if [[ -z "${SERIAL_PATH}" ]]; then
echo "SERIAL_PATH not set, did you run this from install-linux.sh or install-mac.sh?" echo "SERIAL_PATH not set, did you run this from install-linux.sh or install-mac.sh?"
@@ -21,20 +20,28 @@ check_adb() {
} }
force_debug_mode() { force_debug_mode() {
# Force a switch into the debug mode to enable ADB echo "Force a switch into the debug mode to enable ADB"
"$SERIAL_PATH" AT "$SERIAL_PATH" --root
echo -n "adb enabled, waiting for reboot" echo -n "adb enabled, waiting for reboot..."
wait_for_adb_shell wait_for_adb_shell
echo "it's alive!" echo " it's alive!"
echo -n "waiting for atfwd_daemon to startup..."
wait_for_atfwd_daemon
echo " done!"
}
wait_for_atfwd_daemon() {
until [ -n "$(adb shell 'pgrep atfwd_daemon')" ]
do
sleep 1
done
} }
wait_for_adb_shell() { wait_for_adb_shell() {
until adb shell true 2> /dev/null until adb shell true 2> /dev/null
do do
echo -n .
sleep 1 sleep 1
done done
echo
} }
setup_rootshell() { setup_rootshell() {
@@ -44,8 +51,8 @@ setup_rootshell() {
"$SERIAL_PATH" "AT+SYSCMD=chown root /bin/rootshell" "$SERIAL_PATH" "AT+SYSCMD=chown root /bin/rootshell"
sleep 1 sleep 1
"$SERIAL_PATH" "AT+SYSCMD=chmod 4755 /bin/rootshell" "$SERIAL_PATH" "AT+SYSCMD=chmod 4755 /bin/rootshell"
echo "we have root!"
adb shell /bin/rootshell -c id adb shell /bin/rootshell -c id
echo "we have root!"
} }
_adb_push() { _adb_push() {
@@ -62,36 +69,34 @@ setup_rayhunter() {
adb shell '/bin/rootshell -c "cp /tmp/misc-daemon /etc/init.d/misc-daemon"' adb shell '/bin/rootshell -c "cp /tmp/misc-daemon /etc/init.d/misc-daemon"'
adb shell '/bin/rootshell -c "chmod 755 /etc/init.d/rayhunter_daemon"' adb shell '/bin/rootshell -c "chmod 755 /etc/init.d/rayhunter_daemon"'
adb shell '/bin/rootshell -c "chmod 755 /etc/init.d/misc-daemon"' adb shell '/bin/rootshell -c "chmod 755 /etc/init.d/misc-daemon"'
echo -n "rebooting, this may take a sec..." echo -n "waiting for reboot..."
adb shell '/bin/rootshell -c reboot' adb shell '/bin/rootshell -c reboot'
# first wait for shutdown (it can take ~10s) # first wait for shutdown (it can take ~10s)
until ! adb shell true 2> /dev/null until ! adb shell true 2> /dev/null
do do
echo -n '.'
sleep 1 sleep 1
done done
# now wait for boot to finish # now wait for boot to finish
wait_for_adb_shell wait_for_adb_shell
echo "rebooted successfully!" echo " done!"
} }
test_rayhunter() { test_rayhunter() {
URL="http://localhost:8080" URL="http://localhost:8080"
adb forward tcp:8080 tcp:8080 adb forward tcp:8080 tcp:8080 > /dev/null
echo -n "checking for rayhunter server..." echo -n "checking for rayhunter server..."
SECONDS=0 SECONDS=0
while (( SECONDS < 30 )); do while (( SECONDS < 30 )); do
if curl -L --fail-with-body "$URL" -o /dev/null -s; then if curl -L --fail-with-body "$URL" -o /dev/null -s; then
echo echo "success!"
echo "success! you can access rayhunter at $URL" echo "you can access rayhunter at $URL"
return return
fi fi
sleep 1 sleep 1
echo -n "."
done done
echo "timeout reached! failed to reach rayhunter url $URL, something went wrong :(" echo "timeout reached! failed to reach rayhunter url $URL, something went wrong :("
} }
+2 -2
View File
@@ -1,6 +1,6 @@
#!/bin/env bash #!/usr/bin/env bash
set -e set -e
export SERIAL_PATH="./serial-mac-latest/serial" export SERIAL_PATH="./serial-macos-latest/serial"
. "$(dirname "$0")"/install-common.sh . "$(dirname "$0")"/install-common.sh
install install
-34
View File
@@ -1,34 +0,0 @@
#!/bin/env bash
set -e
cargo build --bin serial
cargo build --bin rootshell --target armv7-unknown-linux-gnueabihf --release
# Force a switch into the debug mode to enable ADB
cargo run --bin serial -- AT
echo -n "adb enabled, waiting for reboot"
until adb shell true 2> /dev/null
do
echo -n .
sleep 1
done
echo
echo "it's alive!"
adb push target/armv7-unknown-linux-gnueabihf/release/rootshell /tmp/
cargo run --bin serial -- "AT+SYSCMD=mv /tmp/rootshell /bin/rootshell"
sleep 1
cargo run --bin serial -- "AT+SYSCMD=chown root /bin/rootshell"
sleep 1
cargo run --bin serial -- "AT+SYSCMD=chmod 4755 /bin/rootshell"
echo "we have root!"
adb shell /bin/rootshell -c id
adb shell '/bin/rootshell -c "mkdir /data/rayhunter"'
adb push config.toml.example /data/rayhunter/config.toml
adb push scripts/rayhunter_daemon /tmp/rayhunter_daemon
adb push scripts/misc-daemon /tmp/misc-daemon
adb shell '/bin/rootshell -c "mv /tmp/rayhunter_daemon /etc/init.d/rayhunter_daemon"'
adb shell '/bin/rootshell -c "mv /tmp/misc-daemon /etc/init.d/misc-daemon"'
adb shell '/bin/rootshell -c "chmod 755 /etc/init.d/rayhunter_daemon"'
adb shell '/bin/rootshell -c "chmod 755 /etc/init.d/misc-daemon"'
./make.sh
+1 -1
View File
@@ -1,6 +1,6 @@
use std::borrow::Cow; use std::borrow::Cow;
use telcom_parser::lte_rrc::{CipheringAlgorithm_r12, DL_CCCH_MessageType, DL_CCCH_MessageType_c1, DL_DCCH_MessageType, DL_DCCH_MessageType_c1, PCCH_MessageType, PCCH_MessageType_c1, PagingUE_Identity, RRCConnectionReconfiguration, RRCConnectionReconfigurationCriticalExtensions, RRCConnectionReconfigurationCriticalExtensions_c1, RRCConnectionReconfiguration_r8_IEs, RRCConnectionRelease_v890_IEs, SCG_Configuration_r12, SecurityConfigHO_v1530HandoverType_v1530, SecurityModeCommand, SecurityModeCommandCriticalExtensions, SecurityModeCommandCriticalExtensions_c1}; use telcom_parser::lte_rrc::{CipheringAlgorithm_r12, DL_DCCH_MessageType, DL_DCCH_MessageType_c1, RRCConnectionReconfiguration, RRCConnectionReconfigurationCriticalExtensions, RRCConnectionReconfigurationCriticalExtensions_c1, SCG_Configuration_r12, SecurityConfigHO_v1530HandoverType_v1530, SecurityModeCommand, SecurityModeCommandCriticalExtensions, SecurityModeCommandCriticalExtensions_c1};
use super::analyzer::{Analyzer, Event, EventType, Severity}; use super::analyzer::{Analyzer, Event, EventType, Severity};
use super::information_element::{InformationElement, LteInformationElement}; use super::information_element::{InformationElement, LteInformationElement};
+76 -82
View File
@@ -20,38 +20,36 @@
//! Err(e) => panic!("Failed to initialize libusb: {0}", e), //! Err(e) => panic!("Failed to initialize libusb: {0}", e),
//! ```` //! ````
use std::str; use std::str;
use std::thread::sleep;
use std::time::Duration; use std::time::Duration;
use rusb::{ use rusb::{Context, DeviceHandle, UsbContext};
Context, DeviceHandle, UsbContext,
};
fn main() { fn main() {
let args: Vec<String> = std::env::args().collect(); let args: Vec<String> = std::env::args().collect();
if args.len() < 2 { if args.len() != 2 {
println!("usage: {0} <command>", args[0]); println!("usage: {0} [<command> | --root]", args[0]);
return; return;
} }
match Context::new() { match Context::new() {
Ok(mut context) => match open_orbic(&mut context) { Ok(mut context) => {
Some(mut handle) => { if args[1] == "--root" {
send_command(&mut handle, &args[1]) enable_command_mode(&mut context);
}, } else {
None => panic!("No Orbic device found"), match open_orbic(&mut context) {
}, Some(mut handle) => send_command(&mut handle, &args[1]),
Err(e) => panic!("Failed to initialize libusb: {0}", e), None => panic!("No Orbic device found"),
}
}
},
Err(e) => panic!("Failed to initialize libusb: {0}", e),
} }
} }
/// Sends an AT command to the usb device over the serial port /// Sends an AT command to the usb device over the serial port
/// ///
/// First establish a USB handle and context by calling `open_orbic(<T>) /// First establish a USB handle and context by calling `open_orbic(<T>)
fn send_command<T: UsbContext>( fn send_command<T: UsbContext>(handle: &mut DeviceHandle<T>, command: &str) {
handle: &mut DeviceHandle<T>,
command: &str,
) {
let mut data = String::new(); let mut data = String::new();
data.push_str("\r\n"); data.push_str("\r\n");
data.push_str(command); data.push_str(command);
@@ -61,95 +59,91 @@ fn send_command<T: UsbContext>(
let mut response = [0; 256]; let mut response = [0; 256];
// Set up the serial port appropriately // Set up the serial port appropriately
handle.write_control(0x21, 0x22, 3, 1, &[], timeout).expect("Failed to send control request"); handle
.write_control(0x21, 0x22, 3, 1, &[], timeout)
.expect("Failed to send control request");
// Send the command // Send the command
handle.write_bulk(0x2, data.as_bytes(), timeout).expect("Failed to write command"); handle
.write_bulk(0x2, data.as_bytes(), timeout)
.expect("Failed to write command");
// Consume the echoed command // Consume the echoed command
handle.read_bulk(0x82, &mut response, timeout).expect("Failed to read submitted command"); handle
.read_bulk(0x82, &mut response, timeout)
.expect("Failed to read submitted command");
// Read the actual response // Read the actual response
handle.read_bulk(0x82, &mut response, timeout).expect("Failed to read response"); handle
.read_bulk(0x82, &mut response, timeout)
.expect("Failed to read response");
let responsestr = str::from_utf8(&response).expect("Failed to parse response"); let responsestr = str::from_utf8(&response).expect("Failed to parse response");
if !responsestr.starts_with("\r\nOK\r\n") { if !responsestr.contains("\r\nOK\r\n") {
println!("Received unexpected response{0}", responsestr) println!("Received unexpected response{0}", responsestr);
std::process::exit(1);
} }
} }
/// Send a command to switch the device into generic mode, exposing serial /// Send a command to switch the device into generic mode, exposing serial
/// ///
/// If the device reboots while the command is still executing you may get a pipe error here, not sure what to do about this race condition. /// If the device reboots while the command is still executing you may get a pipe error here, not sure what to do about this race condition.
fn switch_device<T: UsbContext>( fn enable_command_mode<T: UsbContext>(context: &mut T) {
handle: &mut DeviceHandle<T>, if open_orbic(context).is_some() {
) { println!("Device already in command mode. Doing nothing...");
let timeout = Duration::from_secs(1); return;
if let Err(e) = handle.write_control(0x40, 0xa0, 0, 0, &[], timeout) {
// If the device reboots while the command is still executing we
// may get a pipe error here
if e == rusb::Error::Pipe {
return
}
panic!("Failed to send device switch control request: {0}", e)
} }
let timeout = Duration::from_secs(1);
if let Some(handle) = open_device(context, 0x05c6, 0xf626) {
if let Err(e) = handle.write_control(0x40, 0xa0, 0, 0, &[], timeout) {
// If the device reboots while the command is still executing we
// may get a pipe error here
if e == rusb::Error::Pipe {
return;
}
panic!("Failed to send device switch control request: {0}", e)
}
return;
}
panic!("No Orbic device found");
} }
/// Get a handle and contet for the orbic device /// Get a handle and contet for the orbic device
/// fn open_orbic<T: UsbContext>(context: &mut T) -> Option<DeviceHandle<T>> {
/// If the device isn't already in command mode this function will call swtich_device to switch it into command mode
fn open_orbic<T: UsbContext>(
context: &mut T,
) -> Option<DeviceHandle<T>> {
// Device after initial mode switch // Device after initial mode switch
if let Some(handle) = open_device(context, 0x05c6, 0xf601) { if let Some(handle) = open_device(context, 0x05c6, 0xf601) {
return Some(handle) return Some(handle);
} }
// Device with rndis enabled as well // Device with rndis enabled as well
if let Some(handle) = open_device(context, 0x05c6, 0xf622) { if let Some(handle) = open_device(context, 0x05c6, 0xf622) {
return Some(handle) return Some(handle);
} }
// Device in out-of-the-box state, need to switch to diag mode None
match open_device(context, 0x05c6, 0xf626) { }
Some(mut handle) => switch_device(&mut handle),
None => panic!("No Orbic device detected") /// Generic function to open a USB device
} fn open_device<T: UsbContext>(context: &mut T, vid: u16, pid: u16) -> Option<DeviceHandle<T>> {
let devices = match context.devices() {
for _ in 1..10 { Ok(d) => d,
if let Some(handle) = open_device(context, 0x05c6, 0xf601) { Err(_) => return None,
return Some(handle) };
}
sleep(Duration::from_secs(10)) for device in devices.iter() {
} let device_desc = match device.device_descriptor() {
panic!("No Orbic device detected") Ok(d) => d,
} Err(_) => continue,
};
/// Generic function to open a USB device
fn open_device<T: UsbContext>( if device_desc.vendor_id() == vid && device_desc.product_id() == pid {
context: &mut T, match device.open() {
vid: u16, Ok(handle) => return Some(handle),
pid: u16, Err(e) => panic!("device found but failed to open: {}", e),
) -> Option<DeviceHandle<T>> { }
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 None
+18
View File
@@ -0,0 +1,18 @@
#!/bin/env bash
set -e
mkdir build
cd build
curl -LOs "https://github.com/EFForg/rayhunter/releases/latest/download/release.tar"
curl -LOs "https://github.com/EFForg/rayhunter/releases/latest/download/release.tar.sha256"
if ! sha256sum -c --quiet release.tar.sha256; then
echo "Download corrupted! (╯°□°)╯︵ ┻━┻"
exit 1
fi
tar -xf release.tar
./install-linux.sh
cd ..
rm -rf build