Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  export.rs   Sprache: unbekannt

 
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);
    }
}

[ Dauer der Verarbeitung: 0.4 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge