winapi-hash 0.1.3

Windows API hashing implementation
use crate::{to_va, winapi::um::winnt::LPCSTR};
use winapi::{
    shared::{
        basetsd::ULONG_PTR,
        minwindef::{HMODULE, PDWORD, PWORD},
    },
    um::winnt::IMAGE_EXPORT_DIRECTORY,
};

pub struct ExportDirectoryList {
    handle: HMODULE,
    exp_dir: IMAGE_EXPORT_DIRECTORY,
    index: u32,
}

impl ExportDirectoryList {
    pub fn new(handle: HMODULE, exp_dir: IMAGE_EXPORT_DIRECTORY) -> Self {
        Self {
            handle,
            exp_dir,
            index: 0,
        }
    }
}

impl Iterator for ExportDirectoryList {
    type Item = (ULONG_PTR, String);

    fn next(&mut self) -> Option<Self::Item> {
        if self.index > self.exp_dir.NumberOfNames {
            return None;
        }

        unsafe {
            let exp_addrs = to_va!(self.handle, self.exp_dir.AddressOfFunctions) as PDWORD;
            let exp_names = to_va!(self.handle, self.exp_dir.AddressOfNames) as PDWORD;
            let exp_ords = to_va!(self.handle, self.exp_dir.AddressOfNameOrdinals) as PWORD;

            let fn_name = std::ffi::CStr::from_ptr(to_va!(
                self.handle,
                *exp_names.add(self.index as usize)
            ) as LPCSTR)
            .to_str()
            .unwrap();

            let fn_ptr = to_va!(
                self.handle,
                *(exp_addrs.add(*(exp_ords.add(self.index as usize)) as usize))
            ) as ULONG_PTR;

            self.index += 1;

            Some((fn_ptr, fn_name.to_string()))
        }
    }
}