diff --git a/src/main.rs b/src/main.rs index 5ec68f4..03a89e4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -137,17 +137,25 @@ fn apply_code(patch_file : &str, codes : &Vec<(u32, u32)>) -> Result<(), String> let mut pos = 0usize; let max_code_len = codes.len(); let max_data_len = data.len(); - let mut search_addr : Option = None; - while pos < max_code_len { + let mut search_addr : Option<(bool, u32)> = None; + let mut code_len = 0; + loop { + pos += code_len; + if pos >= max_code_len { + break; + } let line = codes[pos].0; let first_code = codes[pos].1; let op_code = (first_code >> 28) as u8; match op_code { 0x0 => { + code_len = 2; let val = codes[pos + 1].1 as u8; - let addr = if let Some(saddr) = search_addr { - search_addr = None; - (codes[pos].1 & 0xffffff) + saddr + let addr = if let Some(saddr) = search_addr.take() { + if saddr.0 == false { + continue; + } + (codes[pos].1 & 0xffffff) + saddr.1 } else { codes[pos].1 & 0xfffffff } 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)); } data[addr] = val; - pos += 2; } 0x1 => { + code_len = 2; let val = codes[pos + 1].1 as u16; - let addr = if let Some(saddr) = search_addr { - search_addr = None; - (codes[pos].1 & 0xffffff) + saddr + let addr = if let Some(saddr) = search_addr.take() { + if saddr.0 == false { + continue; + } + (codes[pos].1 & 0xffffff) + saddr.1 } else { codes[pos].1 & 0xfffffff } 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 + 1] = ((val >> 8) & 0xff) as u8; - pos += 2; } 0x2 => { + code_len = 2; let val = codes[pos + 1].1; - let addr = if let Some(saddr) = search_addr { - search_addr = None; - (codes[pos].1 & 0xffffff) + saddr + let addr = if let Some(saddr) = search_addr.take() { + if saddr.0 == false { + continue; + } + (codes[pos].1 & 0xffffff) + saddr.1 } else { codes[pos].1 & 0xfffffff } 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 + 2] = ((val >> 16) & 0xff) as u8; data[addr + 3] = ((val >> 24) & 0xff) as u8; - pos += 2; } 0x4 => { + code_len = 4; let mut val = codes[pos + 1].1; - let mut addr = if let Some(saddr) = search_addr { - search_addr = None; - (codes[pos].1 & 0xffffff) + saddr + let mut addr = if let Some(saddr) = search_addr.take() { + if saddr.0 == false { + continue; + } + (codes[pos].1 & 0xffffff) + saddr.1 } else { codes[pos].1 & 0xfffffff } as usize; @@ -225,28 +239,27 @@ fn apply_code(patch_file : &str, codes : &Vec<(u32, u32)>) -> Result<(), String> addr += addr_diff as usize; val += val_diff; } - pos += 4; } 0x5 => { return Err(format!("apply code error at line {}: not supported", line)); } 0x8 => { - let count = (codes[pos].1 & 0xfff0000) >> 16; - let search_bytes = (first_code & 0xffff) as usize; - let code_len = ((search_bytes - 1) / 4 + 1) * 2; - let mut bytes = 0; - let mut search = Vec::with_capacity(search_bytes); - while bytes < search_bytes { - let offset = pos + 1 + (bytes / 4); - let shift = (3 - (bytes % 4)) * 8; - search.push(((codes[offset].1 >> shift) & 0xff) as u8); - bytes += 1; - } - pos += code_len; + // let count = (codes[pos].1 & 0xfff0000) >> 16; + // let search_bytes = (first_code & 0xffff) as usize; + // code_len = ((search_bytes - 1) / 4 + 1) * 2; + // let mut bytes = 0; + // let mut search = Vec::with_capacity(search_bytes); + // while bytes < search_bytes { + // let offset = pos + 1 + (bytes / 4); + // let shift = (3 - (bytes % 4)) * 8; + // search.push(((codes[offset].1 >> shift) & 0xff) as u8); + // bytes += 1; + // } } 0xa => { let mut addr = (codes[pos].1 & 0xfffffff) 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 { 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; bytes += 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)?; Ok(()) }