diff --git a/plugins/warp/src/lib.rs b/plugins/warp/src/lib.rs index bea85cddd..be6f8bc39 100644 --- a/plugins/warp/src/lib.rs +++ b/plugins/warp/src/lib.rs @@ -248,7 +248,7 @@ pub fn filtered_instructions_at( LowLevelILInstructionKind::NoRet(_) | LowLevelILInstructionKind::Ret(_) => false, // Stop collecting instruction if we are probably the end function jump in lifted IL. This // is emitted at the end of the function and will mess with our GUID. - LowLevelILInstructionKind::Jump(_) => *i != 0, + LowLevelILInstructionKind::Jump(_) => *i == 0, _ => true, }) .map(|(_, instr)| instr) @@ -400,30 +400,29 @@ pub fn is_address_relocatable(relocatable_regions: &[Range], address: u64) // TODO: This might need to be configurable, in that case we better remove this function. /// Get the relocatable regions of the view. /// -/// Currently, this is all the sections, however, this might be refined later. +/// Currently, segments are used by default, however, if the only segment is based at 0, then we fall +/// back to using sections. pub fn relocatable_regions(view: &BinaryView) -> Vec> { - // NOTE: We cannot use segments here as there will be a zero-based segment. - let mut ranges: Vec<_> = view - .sections() + // NOTE: We used to use sections because the image base for some object files would start + // at zero, masking non-relocatable instructions, since then we have started adjusting the + // image base to 0x10000 or higher so we can use segments directly, which improves the accuracy + // of function GUIDs for binaries which have no or bad section definitions, common of firmware. + let mut ranges = view + .segments() .iter() - .map(|s| Range { - start: s.start(), - end: s.end(), - }) - .collect(); + .filter(|s| s.address_range().start != 0) + .map(|s| s.address_range()) + .collect::>(); - // If the only section available is the synthetic one, fallback to using the segments. - // NOTE: This should only happen for firmware, and it should be _fine_ considering that we - // do not use segments for the case where we are based at some zero offset. The user should have - // based the image somewhere reasonably. - // TODO: Restrict this to only when image base is above some value? - if ranges.len() <= 1 { - let segment_ranges = view - .segments() + if ranges.is_empty() { + // Realistically only happens if the only defined segment was based at 0, in which case + // we hope the user has set up correct sections. If not we are going to be masking off too many + // or too little instructions. + ranges = view + .sections() .iter() .map(|s| s.address_range()) .collect::>(); - ranges.extend(segment_ranges); } ranges diff --git a/plugins/warp/src/plugin/workflow.rs b/plugins/warp/src/plugin/workflow.rs index 04e14a160..878f8e947 100644 --- a/plugins/warp/src/plugin/workflow.rs +++ b/plugins/warp/src/plugin/workflow.rs @@ -105,6 +105,15 @@ pub fn run_matcher(view: &BinaryView) { }) .into_group_map(); + if functions_by_target_and_guid.is_empty() && !view.functions().is_empty() { + // The user is likely trying to run the matcher on a database before guids were automatically + // generated, we should alert them and ask if they would like to reanalyze. + // TODO: Call reanalyze for them? + log::error!("Trying to match with an older database, please reanalyze the database."); + background_task.finish(); + return; + } + // TODO: Par iter this? Using dashmap let guids_by_target: HashMap> = functions_by_target_and_guid .keys() diff --git a/plugins/warp/ui/matched.cpp b/plugins/warp/ui/matched.cpp index 475e0cdd8..618c1b4c0 100644 --- a/plugins/warp/ui/matched.cpp +++ b/plugins/warp/ui/matched.cpp @@ -70,6 +70,10 @@ void WarpMatchedWidget::Update() { m_tableWidget->GetTableView()->setSortingEnabled(false); m_tableWidget->GetTableView()->setEnabled(false); + m_tableWidget->GetProxyModel()->setDynamicSortFilter(false); + m_tableWidget->GetTableView()->setUpdatesEnabled(false); + m_tableWidget->GetTableView()->setModel(nullptr); + m_tableWidget->GetProxyModel()->setSourceModel(nullptr); for (const auto &analysisFunction: m_current->GetAnalysisFunctionList()) { if (const auto &matchedFunction = Warp::Function::GetMatched(*analysisFunction)) @@ -78,6 +82,10 @@ void WarpMatchedWidget::Update() m_tableWidget->InsertFunction(startAddress, new WarpFunctionItem(matchedFunction, analysisFunction)); } } + m_tableWidget->GetTableView()->setModel(m_tableWidget->GetProxyModel()); + m_tableWidget->GetProxyModel()->setSourceModel(m_tableWidget->GetModel()); + m_tableWidget->GetProxyModel()->setDynamicSortFilter(true); m_tableWidget->GetTableView()->setEnabled(true); m_tableWidget->GetTableView()->setSortingEnabled(true); + m_tableWidget->GetTableView()->setUpdatesEnabled(true); } diff --git a/plugins/warp/ui/plugin.cpp b/plugins/warp/ui/plugin.cpp index 923a79b36..dccea1f1b 100644 --- a/plugins/warp/ui/plugin.cpp +++ b/plugins/warp/ui/plugin.cpp @@ -134,8 +134,7 @@ void WarpSidebarWidget::focus() void WarpSidebarWidget::Update() { m_matchedWidget->Update(); - if (!GetMatcherTask()) - setMatcherActionIcon(false); + setMatcherActionIcon(false); } void WarpSidebarWidget::setMatcherActionIcon(bool running)