This commit is contained in:
Argon 2022-09-23 18:58:51 +08:00
parent 3fabc589a6
commit 178f600ecb
1 changed files with 46 additions and 34 deletions

View File

@ -137,17 +137,25 @@ fn apply_code(patch_file : &str, codes : &Vec<(u32, u32)>) -> Result<(), String>
let mut pos = 0usize; let mut pos = 0usize;
let max_code_len = codes.len(); let max_code_len = codes.len();
let max_data_len = data.len(); let max_data_len = data.len();
let mut search_addr : Option<u32> = None; let mut search_addr : Option<(bool, u32)> = None;
while pos < max_code_len { let mut code_len = 0;
loop {
pos += code_len;
if pos >= max_code_len {
break;
}
let line = codes[pos].0; let line = codes[pos].0;
let first_code = codes[pos].1; let first_code = codes[pos].1;
let op_code = (first_code >> 28) as u8; let op_code = (first_code >> 28) as u8;
match op_code { match op_code {
0x0 => { 0x0 => {
code_len = 2;
let val = codes[pos + 1].1 as u8; let val = codes[pos + 1].1 as u8;
let addr = if let Some(saddr) = search_addr { let addr = if let Some(saddr) = search_addr.take() {
search_addr = None; if saddr.0 == false {
(codes[pos].1 & 0xffffff) + saddr continue;
}
(codes[pos].1 & 0xffffff) + saddr.1
} else { } else {
codes[pos].1 & 0xfffffff codes[pos].1 & 0xfffffff
} as usize; } as usize;
@ -155,13 +163,15 @@ fn apply_code(patch_file : &str, codes : &Vec<(u32, u32)>) -> Result<(), String>
return Err(format!("apply code error at line {}: address overflow", line)); return Err(format!("apply code error at line {}: address overflow", line));
} }
data[addr] = val; data[addr] = val;
pos += 2;
} }
0x1 => { 0x1 => {
code_len = 2;
let val = codes[pos + 1].1 as u16; let val = codes[pos + 1].1 as u16;
let addr = if let Some(saddr) = search_addr { let addr = if let Some(saddr) = search_addr.take() {
search_addr = None; if saddr.0 == false {
(codes[pos].1 & 0xffffff) + saddr continue;
}
(codes[pos].1 & 0xffffff) + saddr.1
} else { } else {
codes[pos].1 & 0xfffffff codes[pos].1 & 0xfffffff
} as usize; } as usize;
@ -170,13 +180,15 @@ fn apply_code(patch_file : &str, codes : &Vec<(u32, u32)>) -> Result<(), String>
} }
data[addr] = (val & 0xff) as u8; data[addr] = (val & 0xff) as u8;
data[addr + 1] = ((val >> 8) & 0xff) as u8; data[addr + 1] = ((val >> 8) & 0xff) as u8;
pos += 2;
} }
0x2 => { 0x2 => {
code_len = 2;
let val = codes[pos + 1].1; let val = codes[pos + 1].1;
let addr = if let Some(saddr) = search_addr { let addr = if let Some(saddr) = search_addr.take() {
search_addr = None; if saddr.0 == false {
(codes[pos].1 & 0xffffff) + saddr continue;
}
(codes[pos].1 & 0xffffff) + saddr.1
} else { } else {
codes[pos].1 & 0xfffffff codes[pos].1 & 0xfffffff
} as usize; } as usize;
@ -187,13 +199,15 @@ fn apply_code(patch_file : &str, codes : &Vec<(u32, u32)>) -> Result<(), String>
data[addr + 1] = ((val >> 8) & 0xff) as u8; data[addr + 1] = ((val >> 8) & 0xff) as u8;
data[addr + 2] = ((val >> 16) & 0xff) as u8; data[addr + 2] = ((val >> 16) & 0xff) as u8;
data[addr + 3] = ((val >> 24) & 0xff) as u8; data[addr + 3] = ((val >> 24) & 0xff) as u8;
pos += 2;
} }
0x4 => { 0x4 => {
code_len = 4;
let mut val = codes[pos + 1].1; let mut val = codes[pos + 1].1;
let mut addr = if let Some(saddr) = search_addr { let mut addr = if let Some(saddr) = search_addr.take() {
search_addr = None; if saddr.0 == false {
(codes[pos].1 & 0xffffff) + saddr continue;
}
(codes[pos].1 & 0xffffff) + saddr.1
} else { } else {
codes[pos].1 & 0xfffffff codes[pos].1 & 0xfffffff
} as usize; } as usize;
@ -225,28 +239,27 @@ fn apply_code(patch_file : &str, codes : &Vec<(u32, u32)>) -> Result<(), String>
addr += addr_diff as usize; addr += addr_diff as usize;
val += val_diff; val += val_diff;
} }
pos += 4;
} }
0x5 => { 0x5 => {
return Err(format!("apply code error at line {}: not supported", line)); return Err(format!("apply code error at line {}: not supported", line));
} }
0x8 => { 0x8 => {
let count = (codes[pos].1 & 0xfff0000) >> 16; // let count = (codes[pos].1 & 0xfff0000) >> 16;
let search_bytes = (first_code & 0xffff) as usize; // let search_bytes = (first_code & 0xffff) as usize;
let code_len = ((search_bytes - 1) / 4 + 1) * 2; // code_len = ((search_bytes - 1) / 4 + 1) * 2;
let mut bytes = 0; // let mut bytes = 0;
let mut search = Vec::with_capacity(search_bytes); // let mut search = Vec::with_capacity(search_bytes);
while bytes < search_bytes { // while bytes < search_bytes {
let offset = pos + 1 + (bytes / 4); // let offset = pos + 1 + (bytes / 4);
let shift = (3 - (bytes % 4)) * 8; // let shift = (3 - (bytes % 4)) * 8;
search.push(((codes[offset].1 >> shift) & 0xff) as u8); // search.push(((codes[offset].1 >> shift) & 0xff) as u8);
bytes += 1; // bytes += 1;
} // }
pos += code_len;
} }
0xa => { 0xa => {
let mut addr = (codes[pos].1 & 0xfffffff) as usize; let mut addr = (codes[pos].1 & 0xfffffff) as usize;
let write_bytes = codes[pos + 1].1 as usize; let write_bytes = codes[pos + 1].1 as usize;
code_len = ((write_bytes - 1) / 8 + 1) * 2 + 2;
if addr + write_bytes>= max_data_len { if addr + write_bytes>= max_data_len {
return Err(format!("apply code error at line {}: address overflow", line)); return Err(format!("apply code error at line {}: address overflow", line));
} }
@ -257,14 +270,13 @@ fn apply_code(patch_file : &str, codes : &Vec<(u32, u32)>) -> Result<(), String>
data[addr] = ((codes[offset].1 >> shift) & 0xff) as u8; data[addr] = ((codes[offset].1 >> shift) & 0xff) as u8;
bytes += 1; bytes += 1;
addr += 1; addr += 1;
} }
let code_len = ((write_bytes - 1) / 8 + 1) * 2 + 2;
pos += code_len;
} }
_ => () _ => ()
} }
} }
let mut write_file = fs::OpenOptions::new().write(true).truncate(true).open(patch_file).map_err(fn_map_err)?; let patched_file = patch_file.to_string() + ".patched";
let mut write_file = fs::OpenOptions::new().create(true).write(true).truncate(true).open(patched_file.as_str()).map_err(fn_map_err)?;
write_file.write(data.as_slice()).map_err(fn_map_err)?; write_file.write(data.as_slice()).map_err(fn_map_err)?;
Ok(()) Ok(())
} }