diff options
| author | Mason Reed <mason@vector35.com> | 2025-07-20 20:38:21 -0400 |
|---|---|---|
| committer | Mason Reed <mason@vector35.com> | 2025-07-21 12:14:44 -0400 |
| commit | 34216a4e6724c80c018b8cfa6f133a270728f095 (patch) | |
| tree | 1d91869de73578e63049ed2bf2d1f18f83b864ce /plugins | |
| parent | de2020a70a7a972a38c2a9eae9e6d2b8f2770af9 (diff) | |
[WARP] Consult segments unconditionally when constructing relocatable regions
This removes more barriers for those working with firmware to use WARP, previously if you had defined any sections (such as a vector interrupt table) then backed segments would
end up being marked non-relocatable. This, combined with the use of ELF intermediate object files created inconsistent GUID's, using the segments backing the real functions fixes this.
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/warp/src/lib.rs | 33 |
1 files changed, 15 insertions, 18 deletions
diff --git a/plugins/warp/src/lib.rs b/plugins/warp/src/lib.rs index bea85cdd..0a4a758c 100644 --- a/plugins/warp/src/lib.rs +++ b/plugins/warp/src/lib.rs @@ -400,30 +400,27 @@ pub fn is_address_relocatable(relocatable_regions: &[Range<u64>], 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<Range<u64>> { - // 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::<Vec<_>>(); - // 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::<Vec<_>>(); - ranges.extend(segment_ranges); } ranges |
