From af3765b437157ea44248c13abe856a59f3edafe2 Mon Sep 17 00:00:00 2001 From: unknowntrojan <14975032+unknowntrojan@users.noreply.github.com> Date: Wed, 19 Apr 2023 20:25:33 +0200 Subject: basically ready for pub release --- Cargo.toml | 9 +++------ src/lib.rs | 54 +++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 17131e5..036841c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,11 +8,8 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] +log = "0.4.17" +clipboard = "0.5.0" binaryninja = { git = "https://github.com/Vector35/binaryninja-api.git", branch = "dev" } -iced-x86 = "1.17.0" - -log = "0.4.17" - findpattern = { git = "https://github.com/unknowntrojan/findpattern", features = ["parallel"] } - -clipboard = "0.5.0" +iced-x86 = "1.17.0" diff --git a/src/lib.rs b/src/lib.rs index 06b7f7a..267ba9d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -111,11 +111,8 @@ fn get_relocation_ranges(bv: &BinaryView) -> Vec> { ret } -fn find_patterns(bv: &BinaryView, pattern: Pattern) -> Vec { - if pattern.len() == 0 { - return Vec::new(); - } +fn get_code(bv: &BinaryView) -> Vec<(usize, Vec)> { bv.segments() .into_iter() .filter(|segment| segment.contains_code()) @@ -124,21 +121,34 @@ fn find_patterns(bv: &BinaryView, pattern: Pattern) -> Vec { let len = range.end.checked_sub(range.start); let Some(len) = len else { - return Vec::new(); + return (range.start as usize, Vec::new()); }; if len == 0 { - return Vec::new(); + return (range.start as usize, Vec::new()); } let mut data = vec![0u8; len as usize]; bv.read(&mut data, range.start); - findpattern::find_patterns_par(&data, &pattern) + (range.start as usize, data) + }) + .collect() +} + +fn find_patterns(code_segments: &[(usize, Vec)], pattern: Pattern) -> Vec { + if pattern.len() == 0 { + return Vec::new(); + } + + code_segments + .into_iter() + .map(|segment| { + findpattern::find_patterns(&segment.1, &pattern) .into_iter() - .map(|x| x + range.start as usize) - .collect() + .map(|x| x + segment.0 as usize) + .collect::>() }) .flatten() .collect() @@ -241,13 +251,14 @@ fn get_instruction_pattern( Some(pattern) } -fn is_pattern_unique(bv: &BinaryView, pattern: Pattern) -> bool { - find_patterns(bv, pattern).len() == 1 +fn is_pattern_unique(code_segments: &[(usize, Vec)], pattern: Pattern) -> bool { + find_patterns(code_segments, pattern).len() == 1 } fn create_pattern_internal( bv: &BinaryView, addr: usize, + data: &[(usize, Vec)], include_operands: bool, ) -> Option { log::info!("creating pattern for address {:#04X}", addr); @@ -295,8 +306,14 @@ fn create_pattern_internal( return None; } - current_buffer.copy_from_slice(&[0u8; MAX_INSTRUCTION_LENGTH]); - bv.read(&mut current_buffer, (addr + current_offset) as u64); + current_buffer.copy_from_slice( + &data + .iter() + .find(|segment| segment.0 == start_segment.address_range().start as usize)? + .1[addr + current_offset - start_segment.address_range().start as usize + ..addr + current_offset + MAX_INSTRUCTION_LENGTH + - start_segment.address_range().start as usize], + ); let mut decoder = iced_x86::Decoder::new( if let Some(arch) = bv.default_arch() { @@ -327,7 +344,7 @@ fn create_pattern_internal( current_pattern.extend(&instr_pattern); current_offset += instr.len(); - pattern_unique = is_pattern_unique(bv, ¤t_pattern); + pattern_unique = is_pattern_unique(&data, ¤t_pattern); } while let Some(x) = current_pattern.last() && x.is_none() { @@ -344,11 +361,12 @@ fn create_pattern_internal( fn create_pattern(bv: &BinaryView, addr: usize) -> Option { let include_operands = get_include_operands(bv); - let pattern = create_pattern_internal(bv, addr, include_operands); + let data = get_code(bv); + let pattern = create_pattern_internal(bv, addr, &data, include_operands); if !include_operands && pattern.is_none() { log::warn!("unable to find a unique pattern that didn't include operands. trying again with operands!"); - create_pattern_internal(bv, addr, true) + create_pattern_internal(bv, addr, &data, true) } else { pattern } @@ -555,6 +573,8 @@ impl Command for SigFinderCommand { return; }; + let data = get_code(bv); + sig = sig.replace("\n", ""); sig = sig.replace("\r", ""); sig = sig.replace("\t", ""); @@ -621,7 +641,7 @@ impl Command for SigFinderCommand { } } - for occurrence in find_patterns(bv, &pattern) { + for occurrence in find_patterns(&data, &pattern) { log::info!("found signature at {:#04X}", occurrence); } -- cgit v1.3.1