mirror of
https://github.com/topjohnwu/Magisk.git
synced 2026-01-04 16:58:35 -08:00
Move pattern matching to Rust
This commit is contained in:
@@ -1,5 +1,90 @@
|
||||
use base::{MappedFile, MutBytesExt, ResultExt, Utf8CStr};
|
||||
|
||||
// SAFETY: assert(buf.len() >= 1) && assert(len <= buf.len())
|
||||
macro_rules! match_patterns {
|
||||
($buf:ident, $($str:literal), *) => {{
|
||||
let mut len = if *$buf.get_unchecked(0) == b',' { 1 } else { 0 };
|
||||
let b = $buf.get_unchecked(len..);
|
||||
let found = if b.is_empty() {
|
||||
false
|
||||
}
|
||||
$(
|
||||
else if b.starts_with($str) {
|
||||
len += $str.len();
|
||||
true
|
||||
}
|
||||
)*
|
||||
else {
|
||||
false
|
||||
};
|
||||
if found {
|
||||
let b = $buf.get_unchecked(len..);
|
||||
if !b.is_empty() && b[0] == b'=' {
|
||||
for c in b.iter() {
|
||||
if b" \n\0".contains(c) {
|
||||
break;
|
||||
}
|
||||
len += 1;
|
||||
}
|
||||
}
|
||||
Some(len)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
fn remove_pattern(buf: &mut [u8], pattern_matcher: unsafe fn(&[u8]) -> Option<usize>) -> usize {
|
||||
let mut write = 0_usize;
|
||||
let mut read = 0_usize;
|
||||
let mut sz = buf.len();
|
||||
// SAFETY: assert(write <= read) && assert(read <= buf.len())
|
||||
unsafe {
|
||||
while read < buf.len() {
|
||||
if let Some(len) = pattern_matcher(buf.get_unchecked(read..)) {
|
||||
let skipped = buf.get_unchecked(read..(read + len));
|
||||
// SAFETY: all matching patterns are ASCII bytes
|
||||
let skipped = std::str::from_utf8_unchecked(skipped);
|
||||
eprintln!("Remove pattern [{}]", skipped);
|
||||
sz -= len;
|
||||
read += len;
|
||||
} else {
|
||||
*buf.get_unchecked_mut(write) = *buf.get_unchecked(read);
|
||||
write += 1;
|
||||
read += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(buf) = buf.get_mut(write..) {
|
||||
buf.fill(0);
|
||||
}
|
||||
sz
|
||||
}
|
||||
|
||||
pub fn patch_verity(buf: &mut [u8]) -> usize {
|
||||
unsafe fn match_verity_pattern(buf: &[u8]) -> Option<usize> {
|
||||
match_patterns!(
|
||||
buf,
|
||||
b"verifyatboot",
|
||||
b"verify",
|
||||
b"avb_keys",
|
||||
b"avb",
|
||||
b"support_scfs",
|
||||
b"fsverity"
|
||||
)
|
||||
}
|
||||
|
||||
remove_pattern(buf, match_verity_pattern)
|
||||
}
|
||||
|
||||
pub fn patch_encryption(buf: &mut [u8]) -> usize {
|
||||
unsafe fn match_encryption_pattern(buf: &[u8]) -> Option<usize> {
|
||||
match_patterns!(buf, b"forceencrypt", b"forcefdeorfbe", b"fileencryption")
|
||||
}
|
||||
|
||||
remove_pattern(buf, match_encryption_pattern)
|
||||
}
|
||||
|
||||
fn hex2byte(hex: &[u8]) -> Vec<u8> {
|
||||
let mut v = Vec::new();
|
||||
v.reserve(hex.len() / 2);
|
||||
|
||||
Reference in New Issue
Block a user