Skip to content

Commit d0c0dc1

Browse files
committed
[WARP] Fix relocatable region selection failing to fallback to section collection
Previously we only selected relocatable regions from the list of sections, now that we use the segment list we need a way to fallback to the section list of the segment information is problematic (e.g. based at zero), that fallback has not been triggering as there is a segment for the synthetic sections. Now when a user opens a firmware with only a single zero based segment it should fallback to the sections _and_ alert the user that they should fill out the section map (since that job is left to the user)
1 parent a697651 commit d0c0dc1

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

plugins/warp/src/lib.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ use warp::signature::basic_block::BasicBlockGUID;
2525
use warp::signature::function::{Function, FunctionGUID};
2626
use warp::signature::variable::FunctionVariable;
2727

28+
use binaryninja::section::Semantics;
29+
use binaryninja::segment::Segment;
2830
/// Re-export the warp crate that is used, this is useful for consumers of this crate.
2931
pub use warp;
3032

@@ -418,6 +420,15 @@ pub fn is_address_relocatable(relocatable_regions: &[Range<u64>], address: u64)
418420
/// Currently, segments are used by default, however, if the only segment is based at 0, then we fall
419421
/// back to using sections.
420422
pub fn relocatable_regions(view: &BinaryView) -> Vec<Range<u64>> {
423+
// We need to filter out the segment for the synthetic builtins, otherwise we can't get to
424+
// the path where we look at sections for relocatable regions, this segment is always created
425+
// for now we just filter, but in the future I would like to have something less jank.
426+
let is_synthetic_segment = |segment: &Segment| {
427+
view.sections_at(segment.address_range().start)
428+
.iter()
429+
.any(|sec| sec.auto_defined() && sec.semantics() == Semantics::External)
430+
};
431+
421432
// NOTE: We used to use sections because the image base for some object files would start
422433
// at zero, masking non-relocatable instructions, since then we have started adjusting the
423434
// image base to 0x10000 or higher so we can use segments directly, which improves the accuracy
@@ -426,13 +437,14 @@ pub fn relocatable_regions(view: &BinaryView) -> Vec<Range<u64>> {
426437
.segments()
427438
.iter()
428439
.filter(|s| s.address_range().start != 0)
440+
.filter(|s| !is_synthetic_segment(s))
429441
.map(|s| s.address_range())
430442
.collect::<Vec<_>>();
431443

432444
if ranges.is_empty() {
433445
// Realistically only happens if the only defined segment was based at 0, in which case
434-
// we hope the user has set up correct sections. If not we are going to be masking off too many
435-
// or too little instructions.
446+
// we hope the user has set up correct sections. If not, we are going to be masking off too
447+
// many or too little instructions.
436448
ranges = view
437449
.sections()
438450
.iter()

0 commit comments

Comments
 (0)