Move hexpatch to Rust

This commit is contained in:
topjohnwu
2023-06-20 18:17:26 -07:00
parent 5805573625
commit 399b9e5eba
13 changed files with 78 additions and 39 deletions

View File

@@ -1,28 +0,0 @@
#include "magiskboot.hpp"
using namespace std;
static void hex2byte(string_view hex, uint8_t *buf) {
char high, low;
for (int i = 0, length = hex.length(); i < length; i += 2) {
high = toupper(hex[i]) - '0';
low = toupper(hex[i + 1]) - '0';
buf[i / 2] = ((high > 9 ? high - 7 : high) << 4) + (low > 9 ? low - 7 : low);
}
}
int hexpatch(const char *file, string_view from, string_view to) {
mmap_data m(file, true);
vector<uint8_t> pattern(from.length() / 2);
vector<uint8_t> patch(to.length() / 2);
hex2byte(from, pattern.data());
hex2byte(to, patch.data());
auto v = m.patch(pattern, patch);
for (size_t off : v) {
fprintf(stderr, "Patch @ %08zX [%s] -> [%s]\n", off, from.data(), to.data());
}
return v.empty() ? 1 : 0;
}

View File

@@ -3,9 +3,11 @@
pub use base;
use cpio::*;
use patch::*;
use payload::*;
mod cpio;
mod patch;
mod payload;
// Suppress warnings in generated code
#[allow(warnings)]
@@ -31,5 +33,6 @@ pub mod ffi {
) -> bool;
unsafe fn cpio_commands(argc: i32, argv: *const *const c_char) -> bool;
fn hexpatch(file: &[u8], from: &[u8], to: &[u8]) -> bool;
}
}

View File

@@ -17,7 +17,6 @@
int unpack(const char *image, bool skip_decomp = false, bool hdr = false);
void repack(const char *src_img, const char *out_img, bool skip_comp = false);
int split_image_dtb(const char *filename);
int hexpatch(const char *file, std::string_view from, std::string_view to);
int dtb_commands(int argc, char *argv[]);
size_t patch_verity(rust::Slice<uint8_t> data);

View File

@@ -200,7 +200,7 @@ int main(int argc, char *argv[]) {
} else if (argc > 2 && str_starts(action, "compress")) {
compress(action[8] == '=' ? &action[9] : "gzip", argv[2], argv[3]);
} else if (argc > 4 && action == "hexpatch") {
return hexpatch(argv[2], argv[3], argv[4]);
return rust::hexpatch(byte_view(argv[2]), byte_view(argv[3]), byte_view(argv[4])) ? 0 : 1;
} else if (argc > 2 && action == "cpio"sv) {
if (!rust::cpio_commands(argc - 2, argv + 2))
usage(argv[0]);

37
native/src/boot/patch.rs Normal file
View File

@@ -0,0 +1,37 @@
use base::{MappedFile, MutBytesExt, ResultExt, Utf8CStr};
fn hex2byte(hex: &[u8]) -> Vec<u8> {
let mut v = Vec::new();
v.reserve(hex.len() / 2);
for bytes in hex.chunks(2) {
if bytes.len() != 2 {
break;
}
let high = bytes[0].to_ascii_uppercase() - b'0';
let low = bytes[1].to_ascii_uppercase() - b'0';
let h = if high > 9 { high - 7 } else { high };
let l = if low > 9 { low - 7 } else { low };
v.push(h << 4 | l);
}
v
}
pub fn hexpatch(file: &[u8], from: &[u8], to: &[u8]) -> bool {
fn inner(file: &[u8], from: &[u8], to: &[u8]) -> anyhow::Result<bool> {
let file = Utf8CStr::from_bytes(file)?;
let from = Utf8CStr::from_bytes(from)?;
let to = Utf8CStr::from_bytes(to)?;
let mut map = MappedFile::open_rw(file)?;
let pattern = hex2byte(from.as_bytes());
let patch = hex2byte(to.as_bytes());
let v = map.patch(pattern.as_slice(), patch.as_slice());
for off in &v {
eprintln!("Patch @ {:#010X} [{}] -> [{}]", off, from, to);
}
Ok(!v.is_empty())
}
inner(file, from, to).log().unwrap_or(false)
}