Skip to content

Commit 7e49387

Browse files
author
Maxime LUCE
committed
feat(adb_client): add remount and verity commands
1 parent c9d5df5 commit 7e49387

File tree

16 files changed

+239
-6
lines changed

16 files changed

+239
-6
lines changed

adb_client/src/adb_device_ext.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::path::Path;
44
use image::{ImageBuffer, ImageFormat, Rgba};
55

66
use crate::models::AdbStatResponse;
7-
use crate::{RebootType, Result};
7+
use crate::{RebootType, RemountInfo, Result};
88

99
/// Trait representing all features available on both [`crate::ADBServerDevice`] and [`crate::ADBUSBDevice`]
1010
pub trait ADBDeviceExt {
@@ -27,6 +27,9 @@ pub trait ADBDeviceExt {
2727
/// Reboot the device using given reboot type
2828
fn reboot(&mut self, reboot_type: RebootType) -> Result<()>;
2929

30+
/// Remount the device partitions as read-write
31+
fn remount(&mut self) -> Result<Vec<RemountInfo>>;
32+
3033
/// Run `activity` from `package` on device. Return the command output.
3134
fn run_activity(&mut self, package: &str, activity: &str) -> Result<Vec<u8>> {
3235
let mut output = Vec::new();
@@ -44,6 +47,12 @@ pub trait ADBDeviceExt {
4447
/// Uninstall the package `package` from device.
4548
fn uninstall(&mut self, package: &str) -> Result<()>;
4649

50+
/// Enable dm-verity on the device
51+
fn enable_verity(&mut self) -> Result<()>;
52+
53+
/// Disable dm-verity on the device
54+
fn disable_verity(&mut self) -> Result<()>;
55+
4756
/// Inner method requesting framebuffer from an Android device
4857
fn framebuffer_inner(&mut self) -> Result<ImageBuffer<Rgba<u8>, Vec<u8>>>;
4958

adb_client/src/device/adb_message_device_commands.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use crate::{ADBDeviceExt, ADBMessageTransport, RebootType, Result, models::AdbStatResponse};
1+
use crate::{
2+
ADBDeviceExt, ADBMessageTransport, RebootType, RemountInfo, Result, models::AdbStatResponse,
3+
};
24
use std::{
35
io::{Read, Write},
46
path::Path,
@@ -31,6 +33,10 @@ impl<T: ADBMessageTransport> ADBDeviceExt for ADBMessageDevice<T> {
3133
self.reboot(reboot_type)
3234
}
3335

36+
fn remount(&mut self) -> Result<Vec<RemountInfo>> {
37+
self.remount()
38+
}
39+
3440
fn install(&mut self, apk_path: &dyn AsRef<Path>) -> Result<()> {
3541
self.install(apk_path)
3642
}
@@ -39,6 +45,14 @@ impl<T: ADBMessageTransport> ADBDeviceExt for ADBMessageDevice<T> {
3945
self.uninstall(package)
4046
}
4147

48+
fn enable_verity(&mut self) -> Result<()> {
49+
self.enable_verity()
50+
}
51+
52+
fn disable_verity(&mut self) -> Result<()> {
53+
self.disable_verity()
54+
}
55+
4256
fn framebuffer_inner(&mut self) -> Result<image::ImageBuffer<image::Rgba<u8>, Vec<u8>>> {
4357
self.framebuffer_inner()
4458
}

adb_client/src/device/adb_tcp_device.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use super::adb_message_device::ADBMessageDevice;
66
use super::models::MessageCommand;
77
use super::{ADBRsaKey, ADBTransportMessage, get_default_adb_key_path};
88
use crate::device::adb_usb_device::read_adb_private_key;
9-
use crate::{ADBDeviceExt, ADBMessageTransport, ADBTransport, Result, TcpTransport};
9+
use crate::{ADBDeviceExt, ADBMessageTransport, ADBTransport, RemountInfo, Result, TcpTransport};
1010

1111
/// Represent a device reached and available over TCP.
1212
#[derive(Debug)]
@@ -122,6 +122,11 @@ impl ADBDeviceExt for ADBTcpDevice {
122122
self.inner.reboot(reboot_type)
123123
}
124124

125+
#[inline]
126+
fn remount(&mut self) -> Result<Vec<RemountInfo>> {
127+
self.inner.remount()
128+
}
129+
125130
#[inline]
126131
fn install(&mut self, apk_path: &dyn AsRef<Path>) -> Result<()> {
127132
self.inner.install(apk_path)
@@ -132,6 +137,16 @@ impl ADBDeviceExt for ADBTcpDevice {
132137
self.inner.uninstall(package)
133138
}
134139

140+
#[inline]
141+
fn enable_verity(&mut self) -> Result<()> {
142+
self.inner.enable_verity()
143+
}
144+
145+
#[inline]
146+
fn disable_verity(&mut self) -> Result<()> {
147+
self.inner.disable_verity()
148+
}
149+
135150
#[inline]
136151
fn framebuffer_inner(&mut self) -> Result<image::ImageBuffer<image::Rgba<u8>, Vec<u8>>> {
137152
self.inner.framebuffer_inner()

adb_client/src/device/adb_usb_device.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use super::{ADBRsaKey, ADBTransportMessage};
1414
use crate::ADBDeviceExt;
1515
use crate::ADBMessageTransport;
1616
use crate::ADBTransport;
17-
use crate::{Result, RustADBError, USBTransport};
17+
use crate::{RemountInfo, Result, RustADBError, USBTransport};
1818

1919
pub fn read_adb_private_key<P: AsRef<Path>>(private_key_path: P) -> Result<Option<ADBRsaKey>> {
2020
// Try to read the private key file from given path
@@ -233,6 +233,11 @@ impl ADBDeviceExt for ADBUSBDevice {
233233
self.inner.reboot(reboot_type)
234234
}
235235

236+
#[inline]
237+
fn remount(&mut self) -> Result<Vec<RemountInfo>> {
238+
self.inner.remount()
239+
}
240+
236241
#[inline]
237242
fn install(&mut self, apk_path: &dyn AsRef<Path>) -> Result<()> {
238243
self.inner.install(apk_path)
@@ -243,6 +248,16 @@ impl ADBDeviceExt for ADBUSBDevice {
243248
self.inner.uninstall(package)
244249
}
245250

251+
#[inline]
252+
fn enable_verity(&mut self) -> Result<()> {
253+
self.inner.enable_verity()
254+
}
255+
256+
#[inline]
257+
fn disable_verity(&mut self) -> Result<()> {
258+
self.inner.disable_verity()
259+
}
260+
246261
#[inline]
247262
fn framebuffer_inner(&mut self) -> Result<image::ImageBuffer<image::Rgba<u8>, Vec<u8>>> {
248263
self.inner.framebuffer_inner()

adb_client/src/device/commands/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ mod install;
33
mod pull;
44
mod push;
55
mod reboot;
6+
mod remount;
67
mod shell;
78
mod stat;
89
mod uninstall;
10+
mod verity;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use crate::{
2+
ADBMessageTransport, RemountInfo, Result, RustADBError,
3+
device::{MessageCommand, adb_message_device::ADBMessageDevice},
4+
};
5+
6+
impl<T: ADBMessageTransport> ADBMessageDevice<T> {
7+
pub(crate) fn remount(&mut self) -> Result<Vec<RemountInfo>> {
8+
let response = self.open_session(format!("remount:\0").as_bytes())?;
9+
10+
if response.header().command() != MessageCommand::Okay {
11+
return Err(RustADBError::ADBRequestFailed(format!(
12+
"wrong command {}",
13+
response.header().command()
14+
)));
15+
}
16+
17+
let mut response_str: Vec<String> = Vec::new();
18+
19+
loop {
20+
let response = self.get_transport_mut().read_message()?;
21+
22+
if response.header().command() != MessageCommand::Write {
23+
break;
24+
}
25+
26+
let payload_str = String::from_utf8_lossy(&response.payload());
27+
let payload_str = payload_str.trim();
28+
29+
response_str.push(payload_str.to_string());
30+
}
31+
32+
RemountInfo::from_str_response(&response_str.join("\n"))
33+
}
34+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use crate::{
2+
ADBMessageTransport, Result,
3+
device::{MessageCommand, adb_message_device::ADBMessageDevice},
4+
};
5+
6+
impl<T: ADBMessageTransport> ADBMessageDevice<T> {
7+
pub(crate) fn enable_verity(&mut self) -> Result<()> {
8+
self.open_session(format!("enable-verity:\0").as_bytes())?;
9+
10+
self.get_transport_mut()
11+
.read_message()
12+
.and_then(|message| message.assert_command(MessageCommand::Okay))
13+
}
14+
15+
pub(crate) fn disable_verity(&mut self) -> Result<()> {
16+
self.open_session(format!("disable-verity:\0").as_bytes())?;
17+
18+
self.get_transport_mut()
19+
.read_message()
20+
.and_then(|message| message.assert_command(MessageCommand::Okay))
21+
}
22+
}

adb_client/src/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ pub enum RustADBError {
5454
/// Indicates that the device must be paired before attempting a connection over WI-FI
5555
#[error("Device not paired before attempting to connect")]
5656
ADBDeviceNotPaired,
57+
/// Indicates that remount operation failed
58+
#[error("Cannot remount filesystem: {0}")]
59+
RemountError(String),
5760
/// An error occurred when getting device's framebuffer image
5861
#[error(transparent)]
5962
FramebufferImageError(#[from] image::error::ImageError),

adb_client/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub use device::{ADBTcpDevice, ADBUSBDevice, is_adb_device, search_adb_devices};
2121
pub use emulator_device::ADBEmulatorDevice;
2222
pub use error::{Result, RustADBError};
2323
pub use mdns::*;
24-
pub use models::{AdbStatResponse, RebootType};
24+
pub use models::{AdbStatResponse, RebootType, RemountInfo};
2525
pub use server::*;
2626
pub use server_device::ADBServerDevice;
2727
pub use transports::*;

adb_client/src/models/adb_server_command.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ pub(crate) enum AdbServerCommand {
3636
Reverse(String, String),
3737
ReverseRemoveAll,
3838
Reconnect,
39+
Remount,
40+
DisableVerity,
41+
EnableVerity,
3942
TcpIp(u16),
4043
Usb,
4144
}
@@ -82,6 +85,9 @@ impl Display for AdbServerCommand {
8285
AdbServerCommand::ServerStatus => write!(f, "host:server-status"),
8386
AdbServerCommand::Reconnect => write!(f, "reconnect"),
8487
AdbServerCommand::ReconnectOffline => write!(f, "host:reconnect-offline"),
88+
AdbServerCommand::Remount => write!(f, "remount:"),
89+
AdbServerCommand::DisableVerity => write!(f, "disable-verity:"),
90+
AdbServerCommand::EnableVerity => write!(f, "enable-verity:"),
8591
AdbServerCommand::TcpIp(port) => {
8692
write!(f, "tcpip:{port}")
8793
}

0 commit comments

Comments
 (0)