Struct Module

Source
pub struct Module<'a> {
    pub range: Range<u64>,
    pub checksum: u32,
    pub time_date_stamp: u32,
    pub path: PathBuf,
    pub version_info: FixedFileInfo,
    pub cv_record: &'a [u8],
    pub misc_record: &'a [u8],
}
Expand description

A DLL loaded in the virtual address space.

Fields§

§range: Range<u64>

The range of where the module is loaded in memory at.

§checksum: u32

PE checksum of the module.

§time_date_stamp: u32

Timestamp.

§path: PathBuf

The module path on the file system.

§version_info: FixedFileInfo§cv_record: &'a [u8]§misc_record: &'a [u8]

Implementations§

Source§

impl<'a> Module<'a>

Source

pub fn file_name(&self) -> Option<&str>

Get the file name of the module. This returns None if the file name can’t be converted to a Rust string.

Examples found in repository?
examples/parser.rs (line 204)
152fn main() -> Result<(), String> {
153    // If we don't have any arguments, display the help.
154    if env::args().len() == 1 {
155        help();
156        return Ok(());
157    }
158
159    // Parse the command line arguments.
160    let cli = parse_args()?;
161
162    // Let's try to parse the dump file specified by the user.
163    let dump = UserDumpParser::new(cli.dump_path).map_err(|e| e.to_string())?;
164
165    // Do we want to display modules?
166    if cli.show_mods || cli.show_all {
167        println!("Loaded modules:");
168
169        // Iterate through the module and display their base address and path.
170        for (base, module) in dump.modules() {
171            println!("{:016x}: {}", base, module.path.display());
172        }
173    }
174
175    // Do we want the memory map?
176    if cli.show_memmap || cli.show_all {
177        println!("Memory map:");
178
179        // Iterate over the memory blocks.
180        for block in dump.mem_blocks().values() {
181            // Grab the string representation about its state, type, protection.
182            let state = block.state_as_str();
183            let type_ = block.type_as_str();
184            let protect = block.protect_as_str();
185
186            // Print it all out.
187            print!(
188                "{:016x} {:016x} {:016x} {:11} {:11} {:22}",
189                block.range.start,
190                block.range.end,
191                block.len(),
192                type_,
193                state,
194                protect
195            );
196
197            // Do we have a module that exists at this address?
198            let module = dump.get_module(block.range.start);
199
200            // If we do, then display its name / path.
201            if let Some(module) = module {
202                print!(
203                    " [{}; \"{}\"]",
204                    module.file_name().unwrap(),
205                    module.path.display()
206                );
207            }
208
209            // Do we have data with this block? If so display the first few
210            // bytes.
211            if block.data.len() >= 4 {
212                print!(
213                    " {:02x} {:02x} {:02x} {:02x}...",
214                    block.data[0], block.data[1], block.data[2], block.data[3]
215                );
216            }
217
218            println!();
219        }
220    }
221
222    // Do we want threads?
223    if cli.show_threads || cli.show_all {
224        println!("Threads:");
225
226        // Grab the foreground tid.
227        let foreground_tid = dump.foreground_tid;
228
229        // Iterate through all the threads.
230        for (tid, thread) in dump.threads() {
231            // If the user specified a pid..
232            if let Some(wanted_tid) = cli.thread {
233                // .. skip an threads that don't match what the user wants..
234                if *tid != wanted_tid {
235                    continue;
236                }
237
238                // Otherwise we keep going.
239            }
240
241            // If the user only wants the main thread, and we haven't found it,
242            // skip this thread until we find it.
243            if cli.show_foreground_thread
244                && *tid != foreground_tid.expect("no foreground thread id in dump")
245            {
246                continue;
247            }
248
249            // Print out the thread info.
250            println!("TID {}, TEB {:016x}", tid, thread.teb);
251            println!("Context:");
252            println!("{}", thread.context());
253        }
254    }
255
256    // Do we want to dump memory?
257    if let Some(address) = cli.address {
258        println!("Memory:");
259
260        // Try to find a block that contains `address`.
261        let block = dump.get_mem_block(address);
262
263        // If we have one..
264        if let Some(block) = block {
265            // .. and it has data, dump it..
266            if let Some(data) = block.data_from(address) {
267                println!("{:016x} -> {:016x}", address, block.end_addr());
268                hexdump(address, data.iter().take(0x1_00).copied());
269            }
270            // .. otherwise, inform the user..
271            else {
272                println!(
273                    "The memory at {:016x} (from block {:016x} -> {:016x}) has no backing data",
274                    address, block.range.start, block.range.end
275                );
276            }
277        }
278        // .. otherwise, inform he user.
279        else {
280            println!("No memory block were found for {:016x}", address);
281        }
282    }
283
284    // All right, enough for today.
285    Ok(())
286}
Source

pub fn start_addr(&self) -> u64

Get the address of where the module was loaded at.

Source

pub fn end_addr(&self) -> u64

Get the address of where the last byte of the module was loaded at.

Source

pub fn len(&self) -> u64

Get the length of the range of memory the module was loaded at.

Trait Implementations§

Source§

impl<'a> Debug for Module<'a>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'a> Default for Module<'a>

Source§

fn default() -> Module<'a>

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<'a> Freeze for Module<'a>

§

impl<'a> RefUnwindSafe for Module<'a>

§

impl<'a> Send for Module<'a>

§

impl<'a> Sync for Module<'a>

§

impl<'a> Unpin for Module<'a>

§

impl<'a> UnwindSafe for Module<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.