mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-12-07 08:12:38 +00:00
Move hexpatch to Rust
This commit is contained in:
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
37
native/src/boot/patch.rs
Normal 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)
|
||||
}
|
||||
Reference in New Issue
Block a user