mirror of
https://github.com/Zenithsiz/dcb.git
synced 2026-02-13 21:23:28 +00:00
Both tables now get the instruction range to limit their search.
This commit is contained in:
@@ -76,7 +76,7 @@ impl Exe {
|
||||
|
||||
/// Returns this executable's instruction range
|
||||
#[must_use]
|
||||
pub fn inst_range(&self) -> Range<Pos> {
|
||||
pub fn insts_range(&self) -> Range<Pos> {
|
||||
let start = self.header.start_pos;
|
||||
let end = self.header.start_pos + self.header.size;
|
||||
start..end
|
||||
@@ -107,6 +107,13 @@ impl Exe {
|
||||
file.read_exact(&mut header_bytes).map_err(DeserializeError::ReadHeader)?;
|
||||
let header = Header::from_bytes(&header_bytes).map_err(DeserializeError::ParseHeader)?;
|
||||
|
||||
// Get the instruction range
|
||||
let insts_range = {
|
||||
let start = header.start_pos;
|
||||
let end = header.start_pos + header.size;
|
||||
start..end
|
||||
};
|
||||
|
||||
// Read all of the bytes
|
||||
let mut bytes = vec![0u8; usize::try_from(header.size).expect("Len didn't fit into `usize`")].into_boxed_slice();
|
||||
file.read_exact(bytes.as_mut()).map_err(DeserializeError::ReadData)?;
|
||||
@@ -119,9 +126,9 @@ impl Exe {
|
||||
let insts = inst::ParseIter::new(&*bytes, header.start_pos);
|
||||
|
||||
// Then parse all heuristic tables
|
||||
let heuristics_data_table = DataTable::search_instructions(insts.clone());
|
||||
let heuristics_data_table = DataTable::search_instructions(insts_range.clone(), insts.clone());
|
||||
let data_table = known_data_table.merge_with(heuristics_data_table);
|
||||
let heuristics_func_table = FuncTable::search_instructions(insts);
|
||||
let heuristics_func_table = FuncTable::search_instructions(insts_range, insts);
|
||||
let func_table = known_func_table.merge_with(heuristics_func_table);
|
||||
|
||||
Ok(Self {
|
||||
|
||||
@@ -23,7 +23,12 @@ use crate::exe::{
|
||||
Pos,
|
||||
};
|
||||
use dcb_util::DiscardingSortedMergeIter;
|
||||
use std::{collections::BTreeSet, fs::File, iter::FromIterator, ops::RangeBounds};
|
||||
use std::{
|
||||
collections::BTreeSet,
|
||||
fs::File,
|
||||
iter::FromIterator,
|
||||
ops::{Range, RangeBounds},
|
||||
};
|
||||
|
||||
/// Data table
|
||||
///
|
||||
@@ -89,7 +94,7 @@ impl DataTable {
|
||||
/// Searches all instructions for references to
|
||||
/// executable data using certain heuristics.
|
||||
#[must_use]
|
||||
pub fn search_instructions<'a>(insts: impl Iterator<Item = (Pos, Inst<'a>)> + Clone) -> Self {
|
||||
pub fn search_instructions<'a>(_insts_range: Range<Pos>, insts: impl Iterator<Item = (Pos, Inst<'a>)> + Clone) -> Self {
|
||||
// Get all possible references to data
|
||||
let references: BTreeSet<Pos> = insts
|
||||
.clone()
|
||||
|
||||
@@ -27,7 +27,7 @@ use std::{
|
||||
collections::{BTreeMap, BTreeSet},
|
||||
fs::File,
|
||||
iter::FromIterator,
|
||||
ops::RangeBounds,
|
||||
ops::{Range, RangeBounds},
|
||||
};
|
||||
|
||||
/// Function table
|
||||
@@ -97,7 +97,7 @@ impl FuncTable {
|
||||
/// Creates a new list of functions from an iterator over insts
|
||||
#[must_use]
|
||||
#[allow(clippy::too_many_lines)] // TODO: Refactor?
|
||||
pub fn search_instructions<'a>(insts: impl Iterator<Item = (Pos, Inst<'a>)> + Clone) -> Self {
|
||||
pub fn search_instructions<'a>(insts_range: Range<Pos>, insts: impl Iterator<Item = (Pos, Inst<'a>)> + Clone) -> Self {
|
||||
// Get all returns
|
||||
let returns: BTreeSet<Pos> = insts
|
||||
.clone()
|
||||
@@ -146,7 +146,7 @@ impl FuncTable {
|
||||
Inst::Basic(basic::Inst::Cond(inst)) => Some(inst.target(pos)),
|
||||
_ => None,
|
||||
})
|
||||
//.filter(|target| Inst::CODE_RANGE.contains(target))
|
||||
.filter(|target| insts_range.contains(target))
|
||||
.collect();
|
||||
|
||||
// Now check every `Jal` and `Dw` for possible function entrances
|
||||
@@ -163,7 +163,7 @@ impl FuncTable {
|
||||
Inst::Directive(Directive::Dw(address)) => Some(Pos(address)),
|
||||
_ => None,
|
||||
})
|
||||
//.filter(|target| Inst::CODE_RANGE.contains(target))
|
||||
.filter(|target| insts_range.contains(target))
|
||||
.collect();
|
||||
|
||||
#[allow(clippy::cognitive_complexity)] // TODO: Fix
|
||||
|
||||
@@ -58,7 +58,7 @@ impl<'a> Iterator for Iter<'a> {
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
// If we're at the end, return `None`
|
||||
let cur_pos = self.cur_pos;
|
||||
if cur_pos >= self.exe.inst_range().end {
|
||||
if cur_pos >= self.exe.insts_range().end {
|
||||
return None;
|
||||
}
|
||||
|
||||
@@ -100,11 +100,11 @@ impl<'a> Iterator for Iter<'a> {
|
||||
},
|
||||
(Some(next_data), None) => next_data.pos,
|
||||
(None, Some(next_func)) => next_func.start_pos,
|
||||
(None, None) => self.exe.inst_range().end,
|
||||
(None, None) => self.exe.insts_range().end,
|
||||
};
|
||||
|
||||
// Make sure to limit the end position
|
||||
let end_pos = end_pos.min(self.exe.inst_range().end);
|
||||
let end_pos = end_pos.min(self.exe.insts_range().end);
|
||||
self.cur_pos = end_pos;
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user