Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/goblin/src/pe/   (Firefox Browser Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 21 kB image not shown  

Quelle  export.rs

  Sprache: Rust
 

use alloc::vec::Vec;
use scroll::{Pread, Pwrite};

use log::debug;

use crate::error;

use crate::pe::data_directories;
use crate::pe::options;
use crate::pe::section_table;
use crate::pe::utils;

#[repr(C)]
#[derive(Debug, PartialEq, Copy, Clone, Default, Pread, Pwrite)]
pub struct ExportDirectoryTable {
    pub export_flags: u32,
    pub time_date_stamp: u32,
    pub major_version: u16,
    pub minor_version: u16,
    pub name_rva: u32,
    pub ordinal_base: u32,
    pub address_table_entries: u32,
    pub number_of_name_pointers: u32,
    pub export_address_table_rva: u32,
    pub name_pointer_rva: u32,
    pub ordinal_table_rva: u32,
}

pub const SIZEOF_EXPORT_DIRECTORY_TABLE: usize = 40;

impl ExportDirectoryTable {
    pub fn parse(bytes: &[u8], offset: usize) -> error::Result<Self> {
        let res = bytes.pread_with(offset, scroll::LE)?;
        Ok(res)
    }
}

#[derive(Debug)]
pub enum ExportAddressTableEntry {
    ExportRVA(u32),
    ForwarderRVA(u32),
}

pub const SIZEOF_EXPORT_ADDRESS_TABLE_ENTRY: usize = 4;

pub type ExportAddressTable = Vec<ExportAddressTableEntry>;

/// Array of rvas into the export name table
///
/// Export name is defined iff pointer table has pointer to the name
pub type ExportNamePointerTable = Vec<u32>;

/// Array of indexes into the export address table.
///
/// Should obey the formula `idx = ordinal - ordinalbase`
pub type ExportOrdinalTable = Vec<u16>;

#[derive(Debug, Default)]
/// Export data contains the `dll` name which other libraries can import symbols by (two-level namespace), as well as other important indexing data allowing symbol lookups
pub struct ExportData<'a> {
    pub name: Option<&'a str>,
    pub export_directory_table: ExportDirectoryTable,
    pub export_name_pointer_table: ExportNamePointerTable,
    pub export_ordinal_table: ExportOrdinalTable,
    pub export_address_table: ExportAddressTable,
}

impl<'a> ExportData<'a> {
    pub fn parse(
        bytes: &'a [u8],
        dd: data_directories::DataDirectory,
        sections: &[section_table::SectionTable],
        file_alignment: u32,
    ) -> error::Result<ExportData<'a>> {
        Self::parse_with_opts(
            bytes,
            dd,
            sections,
            file_alignment,
            &options::ParseOptions::default(),
        )
    }

    pub fn parse_with_opts(
        bytes: &'a [u8],
        dd: data_directories::DataDirectory,
        sections: &[section_table::SectionTable],
        file_alignment: u32,
        opts: &options::ParseOptions,
    ) -> error::Result<ExportData<'a>> {
        let export_rva = dd.virtual_address as usize;
        let size = dd.size as usize;
        debug!("export_rva {:#x} size {:#}", export_rva, size);
        let export_offset = utils::find_offset_or(
            export_rva,
            sections,
            file_alignment,
            opts,
            &format!("cannot map export_rva ({:#x}) into offset", export_rva),
        )?;
        let export_directory_table =
            ExportDirectoryTable::parse(bytes, export_offset).map_err(|_| {
                error::Error::Malformed(format!(
                    "cannot parse export_directory_table (offset {:#x})",
                    export_offset
                ))
            })?;
        let number_of_name_pointers = export_directory_table.number_of_name_pointers as usize;
        let address_table_entries = export_directory_table.address_table_entries as usize;

        if number_of_name_pointers > bytes.len() {
            return Err(error::Error::BufferTooShort(
                number_of_name_pointers,
                "name pointers",
            ));
        }
        if address_table_entries > bytes.len() {
            return Err(error::Error::BufferTooShort(
                address_table_entries,
                "address table entries",
            ));
        }

        let export_name_pointer_table = utils::find_offset(
            export_directory_table.name_pointer_rva as usize,
            sections,
            file_alignment,
            opts,
        )
        .map_or(vec![], |table_offset| {
            let mut offset = table_offset;
            let mut table: ExportNamePointerTable = Vec::with_capacity(number_of_name_pointers);

            for _ in 0..number_of_name_pointers {
                if let Ok(name_rva) = bytes.gread_with(&mut offset, scroll::LE) {
                    table.push(name_rva);
                } else {
                    break;
                }
            }

            table
        });

        let export_ordinal_table = utils::find_offset(
            export_directory_table.ordinal_table_rva as usize,
            sections,
            file_alignment,
            opts,
        )
        .map_or(vec![], |table_offset| {
            let mut offset = table_offset;
            let mut table: ExportOrdinalTable = Vec::with_capacity(number_of_name_pointers);

            for _ in 0..number_of_name_pointers {
                if let Ok(name_ordinal) = bytes.gread_with(&mut offset, scroll::LE) {
                    table.push(name_ordinal);
                } else {
                    break;
                }
            }

            table
        });

        let export_address_table = utils::find_offset(
            export_directory_table.export_address_table_rva as usize,
            sections,
            file_alignment,
            opts,
        )
        .map_or(vec![], |table_offset| {
            let mut offset = table_offset;
            let mut table: ExportAddressTable = Vec::with_capacity(address_table_entries);
            let export_end = export_rva + size;

            for _ in 0..address_table_entries {
                if let Ok(func_rva) = bytes.gread_with::<u32>(&mut offset, scroll::LE) {
                    if utils::is_in_range(func_rva as usize, export_rva, export_end) {
                        table.push(ExportAddressTableEntry::ForwarderRVA(func_rva));
                    } else {
                        table.push(ExportAddressTableEntry::ExportRVA(func_rva));
                    }
                } else {
                    break;
                }
            }

            table
        });

        let name = utils::find_offset(
            export_directory_table.name_rva as usize,
            sections,
            file_alignment,
            opts,
        )
        .and_then(|offset| bytes.pread(offset).ok());

        Ok(ExportData {
            name,
            export_directory_table,
            export_name_pointer_table,
            export_ordinal_table,
            export_address_table,
        })
    }
}

#[derive(Debug)]
/// PE binaries have two kinds of reexports, either specifying the dll's name, or the ordinal value of the dll
pub enum Reexport<'a> {
    DLLName { export: &'a str, lib: &'a str },
    DLLOrdinal { ordinal: usize, lib: &'a str },
}

impl<'a> scroll::ctx::TryFromCtx<'a, scroll::Endian> for Reexport<'a> {
    type Error = crate::error::Error;
    #[inline]
    fn try_from_ctx(bytes: &'a [u8], _ctx: scroll::Endian) -> Result<(Self, usize), Self::Error> {
        let reexport = bytes.pread::<&str>(0)?;
        let reexport_len = reexport.len();
        debug!("reexport: {}", &reexport);
        for o in 0..reexport_len {
            let c: u8 = bytes.pread(o)?;
            debug!("reexport offset: {:#x} char: {:#x}", o, c);
            if c == b'.' {
                let dll: &'a str = bytes.pread_with(0, scroll::ctx::StrCtx::Length(o))?;
                debug!("dll: {:?}", &dll);
                if o + 1 == reexport_len {
                    break;
                }
                let len = reexport_len - o - 1;
                let rest: &'a [u8] = bytes.pread_with(o + 1, len)?;
                debug!("rest: {:?}", &rest);
                if rest[0] == b'#' {
                    let ordinal =
                        rest.pread_with::<&str>(1, scroll::ctx::StrCtx::Length(len - 1))?;
                    let ordinal = ordinal.parse::<u32>().map_err(|_e| {
                        error::Error::Malformed(format!(
                            "Cannot parse reexport ordinal from {} bytes",
                            bytes.len()
                        ))
                    })?;
                    return Ok((
                        Reexport::DLLOrdinal {
                            ordinal: ordinal as usize,
                            lib: dll,
                        },
                        reexport_len + 1,
                    ));
                } else {
                    let export = rest.pread_with::<&str>(0, scroll::ctx::StrCtx::Length(len))?;
                    return Ok((Reexport::DLLName { export, lib: dll }, reexport_len + 1));
                }
            }
        }
        Err(error::Error::Malformed(format!(
            "Reexport {:#} is malformed",
            reexport
        )))
    }
}

impl<'a> Reexport<'a> {
    pub fn parse(bytes: &'a [u8], offset: usize) -> crate::error::Result<Reexport<'a>> {
        bytes.pread(offset)
    }
}

#[derive(Debug, Default)]
/// An exported symbol in this binary, contains synthetic data (name offset, etc., are computed)
pub struct Export<'a> {
    pub name: Option<&'a str>,
    pub offset: Option<usize>,
    pub rva: usize,
    pub size: usize,
    pub reexport: Option<Reexport<'a>>,
}

#[derive(Debug, Copy, Clone)]
struct ExportCtx<'a> {
    pub ptr: u32,
    pub idx: usize,
    pub sections: &'a [section_table::SectionTable],
    pub file_alignment: u32,
    pub addresses: &'a ExportAddressTable,
    pub ordinals: &'a ExportOrdinalTable,
    pub opts: options::ParseOptions,
}

impl<'a, 'b> scroll::ctx::TryFromCtx<'a, ExportCtx<'b>> for Export<'a> {
    type Error = error::Error;
    #[inline]
    fn try_from_ctx(
        bytes: &'a [u8],
        ExportCtx {
            ptr,
            idx,
            sections,
            file_alignment,
            addresses,
            ordinals,
            opts,
        }: ExportCtx<'b>,
    ) -> Result<(Self, usize), Self::Error> {
        use self::ExportAddressTableEntry::*;

        let name = utils::find_offset(ptr as usize, sections, file_alignment, &opts)
            .and_then(|offset| bytes.pread::<&str>(offset).ok());

        if let Some(ordinal) = ordinals.get(idx) {
            if let Some(rva) = addresses.get(*ordinal as usize) {
                match *rva {
                    ExportRVA(rva) => {
                        let rva = rva as usize;
                        let offset = utils::find_offset(rva, sections, file_alignment, &opts);
                        Ok((
                            Export {
                                name,
                                offset,
                                rva,
                                reexport: None,
                                size: 0,
                            },
                            0,
                        ))
                    }

                    ForwarderRVA(rva) => {
                        let rva = rva as usize;
                        let offset = utils::find_offset_or(
                            rva,
                            sections,
                            file_alignment,
                            &opts,
                            &format!(
                                "cannot map RVA ({:#x}) of export ordinal {} into offset",
                                rva, ordinal
                            ),
                        )?;
                        let reexport = Reexport::parse(bytes, offset)?;
                        Ok((
                            Export {
                                name,
                                offset: Some(offset),
                                rva,
                                reexport: Some(reexport),
                                size: 0,
                            },
                            0,
                        ))
                    }
                }
            } else {
                Err(error::Error::Malformed(format!(
                    "cannot get RVA of export ordinal {}",
                    ordinal
                )))
            }
        } else {
            Err(error::Error::Malformed(format!(
                "cannot get ordinal of export name entry {}",
                idx
            )))
        }
    }
}

impl<'a> Export<'a> {
    pub fn parse(
        bytes: &'a [u8],
        export_data: &ExportData,
        sections: &[section_table::SectionTable],
        file_alignment: u32,
    ) -> error::Result<Vec<Export<'a>>> {
        Self::parse_with_opts(
            bytes,
            export_data,
            sections,
            file_alignment,
            &options::ParseOptions::default(),
        )
    }

    pub fn parse_with_opts(
        bytes: &'a [u8],
        export_data: &ExportData,
        sections: &[section_table::SectionTable],
        file_alignment: u32,
        opts: &options::ParseOptions,
    ) -> error::Result<Vec<Export<'a>>> {
        let pointers = &export_data.export_name_pointer_table;
        let addresses = &export_data.export_address_table;
        let ordinals = &export_data.export_ordinal_table;

        let mut exports = Vec::with_capacity(pointers.len());
        for (idx, &ptr) in pointers.iter().enumerate() {
            if let Ok(export) = bytes.pread_with(
                0,
                ExportCtx {
                    ptr,
                    idx,
                    sections,
                    file_alignment,
                    addresses,
                    ordinals,
                    opts: *opts,
                },
            ) {
                exports.push(export);
            }
        }

        // TODO: sort + compute size
        Ok(exports)
    }
}

#[cfg(test)]
mod tests {
    use self::data_directories::*;
    use super::*;

    static CORKAMI_POCS_PE_EXPORTSDATA_EXE: [u8; 0x400] = [
        0x4d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x40, 0x00, 0x00, 0x00, 0x50, 0x45, 0x00, 0x00, 0x4c, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x02, 0x01, 0x0b, 0x01,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
        0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x60, 0x01,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x10, 0x00, 0x00, 0x00, 0xb0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x10, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02,
        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x80, 0x03,
        0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x20, 0x2a, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20,
        0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x66, 0x61, 0x6b, 0x65, 0x20,
        0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x0a, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84,
        0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0x10, 0x00, 0x00,
        0x40, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c,
        0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66,
        0x00, 0x6d, 0x73, 0x76, 0x63, 0x72, 0x74, 0x2e, 0x64, 0x6c, 0x6c, 0x00, 0x65, 0x78, 0x70,
        0x6f, 0x72, 0x74, 0x73, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x65, 0x78, 0x65, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x10, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x68, 0x14, 0x10, 0xf0, 0x10, 0xff, 0x15, 0x30, 0x10, 0x00, 0x10, 0x73, 0xc4, 0x04,
        0xc3, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00,
    ];

    #[test]
    fn size_export_directory_table() {
        assert_eq!(
            ::std::mem::size_of::<ExportDirectoryTable>(),
            SIZEOF_EXPORT_DIRECTORY_TABLE
        );
    }

    #[test]
    fn parse_export_table() {
        let data_dirs =
            DataDirectories::parse(&CORKAMI_POCS_PE_EXPORTSDATA_EXE[..], 16, &mut 0xb8).unwrap();
        let export_table = data_dirs.get_export_table().unwrap();

        assert_eq!(export_table.virtual_address, 0x10b0);
        assert_eq!(export_table.size, 0x0);
    }

    #[test]
    fn parse_export_directory() {
        let data_dir = ExportDirectoryTable::parse(&CORKAMI_POCS_PE_EXPORTSDATA_EXE[..], 0x2b0);
        assert!(data_dir.is_ok());

        let data_dir = data_dir.unwrap();
        assert_eq!(data_dir.export_flags, 0x0);
        assert_eq!(data_dir.time_date_stamp, 0x0);
        assert_eq!(data_dir.major_version, 0x0);
        assert_eq!(data_dir.minor_version, 0x0);
        assert_eq!(data_dir.name_rva, 0x0);
        assert_eq!(data_dir.ordinal_base, 0x0);
        assert_eq!(data_dir.address_table_entries, 0x4);
        assert_eq!(data_dir.number_of_name_pointers, 0x0);
        assert_eq!(data_dir.export_address_table_rva, 0x10e0);
        assert_eq!(data_dir.name_pointer_rva, 0x0);
        assert_eq!(data_dir.ordinal_table_rva, 0x1100);
    }
}

Messung V0.5 in Prozent
C=78 H=93 G=85

¤ Dauer der Verarbeitung: 0.19 Sekunden  (vorverarbeitet am  2026-06-19) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.