fn find_all_interfaces<T: VirtualMemory>(
    process: &mut Win32Process<T>,
    module_info: Win32ModuleInfo,
) -> Result<Vec<Interface>> {
    debug!(
        "scanning module {}: 0x{:x} (0x{:x})",
        module_info.name(),
        module_info.base(),
        module_info.size()
    );

    // parse pe image
    let mut image = vec![0u8; module_info.size()];
    process
        .virt_mem
        .virt_read_raw_into(module_info.base, &mut image)
        .data_part()?;
    let pe = PeView::from_bytes(&image).map_err(|_| Error::Other("unable to parse pe image"))?;

    // find export "CreateInterface"
    let create_interface_fn = match pe.get_export("CreateInterface").map_err(Error::PE)? {
        Export::Symbol(s) => module_info.base() + *s as usize,
        Export::Forward(_) => {
            return Err(Error::Other(
                "CreateInterface found but it was a forwarded export",
            ))
        }
    };
    debug!(
        "create_interface_fn={:x}",
        create_interface_fn - module_info.base()
    );

    let virt_mem = &mut process.virt_mem;

    // find internal linked list
    let ci_jmp: u32 = virt_mem.virt_read(create_interface_fn + 0x5)?;
    trace!("ci_jmp={:x}", ci_jmp);

    let ci_followed = Address::from(create_interface_fn.as_u32() + 0x5 + 0x4 + ci_jmp);
    trace!(
        "ci_followed={:x}",
        Address::from(ci_followed) - module_info.base()
    );

    let ci_sig: u16 = virt_mem.virt_read(ci_followed + 0x4)?;
    trace!("ci_sig={:x}", ci_sig);
    if ci_sig != 0x358B {
        return Err(Error::Other("unable to validate CreateInterface signature"));
    }

    let temp: u32 = virt_mem.virt_read(ci_followed + 0x6)?;
    let reg_ptr: Pointer32<InterfaceReg> = virt_mem.virt_read(temp.into())?;
    let mut reg = reg_ptr.deref(virt_mem)?;

    let mut interfaces = Vec::new();
    loop {
        let name = virt_mem.virt_read_cstr(reg.name.into(), 128)?;
        let address: u32 = virt_mem.virt_read(Address::from(reg.create) + 0x1)?;
        if address != 0 {
            info!(
                "interface {} found at {:x} in {}",
                name, address, module_info.name
            );
            interfaces.push(Interface {
                module_info: module_info.clone(),
                name,
                address,
            });
        } else {
            info!("instance pointer of interface {} is invalid", name);
        }

        if reg.next.is_null() {
            break;
        }
        reg.next.deref_into(virt_mem, &mut reg)?;
    }

    Ok(interfaces)
}
/// Returns a list of all Source Engine Interfaces found in a given module
Returns a list of all Source Engine Interfaces found in a given module
Returns a list of all Source Engine Interfaces found in a given module
fn find_all_interfaces<T: VirtualMemory>(
    process: &mut Win32Process<T>,
    module_info: Win32ModuleInfo,
) -> Result<Vec<Interface>> {
    debug!(
        "scanning module {}: 0x{:x} (0x{:x})",
        module_info.name(),
        module_info.base(),
        module_info.size()
    );
    // parse pe image
    let mut image = vec![0u8; module_info.size()];
    process
        .virt_mem
        .virt_read_raw_into(module_info.base, &mut image)
        .data_part()?;
    let pe = PeView::from_bytes(&image).map_err(|_| Error::Other("unable to parse pe image"))?;
    // find export "CreateInterface"
    let create_interface_fn = match pe.get_export("CreateInterface").map_err(Error::PE)? {
        Export::Symbol(s) => module_info.base() + *s as usize,
        Export::Forward(_) => {
            return Err(Error::Other(
                "CreateInterface found but it was a forwarded export",
            ))
        }
    };
    debug!(
        "create_interface_fn={:x}",
        create_interface_fn - module_info.base()
    );
    let virt_mem = &mut process.virt_mem;
    // find internal linked list
    let ci_jmp: u32 = virt_mem.virt_read(create_interface_fn + 0x5)?;
    trace!("ci_jmp={:x}", ci_jmp);
    let ci_followed = Address::from(create_interface_fn.as_u32() + 0x5 + 0x4 + ci_jmp);
    trace!(
        "ci_followed={:x}",
        Address::from(ci_followed) - module_info.base()
    );
    let ci_sig: u16 = virt_mem.virt_read(ci_followed + 0x4)?;
    trace!("ci_sig={:x}", ci_sig);
    if ci_sig != 0x358B {
        return Err(Error::Other("unable to validate CreateInterface signature"));
    }
    let temp: u32 = virt_mem.virt_read(ci_followed + 0x6)?;
    let reg_ptr: Pointer32<InterfaceReg> = virt_mem.virt_read(temp.into())?;
    let mut reg = reg_ptr.deref(virt_mem)?;
    let mut interfaces = Vec::new();
    loop {
        let name = virt_mem.virt_read_cstr(reg.name.into(), 128)?;
        let address: u32 = virt_mem.virt_read(Address::from(reg.create) + 0x1)?;
        if address != 0 {
            info!(
                "interface {} found at {:x} in {}",
                name, address, module_info.name
            );
            interfaces.push(Interface {
                module_info: module_info.clone(),
                name,
                address,
            });
        } else {
            info!("instance pointer of interface {} is invalid", name);
        }
        if reg.next.is_null() {
            break;
        }
        reg.next.deref_into(virt_mem, &mut reg)?;
    }
    Ok(interfaces)
}
fn find_all_interfaces < T : VirtualMemory > ( process : & mut Win32Process < T > , module_info : Win32ModuleInfo , ) -> Result < Vec < Interface > > { debug ! ( " " module_info name ( ) module_info base ( ) module_info size ( ) ) ; // parse pe image let mut image = vec ! [ 0u8 module_info size ( ) ] ; process . virt_mem . virt_read_raw_into ( module_info . base , & mut image ) . data_part ( ) ? ; let pe = PeView :: from_bytes ( & image ) . map_err ( | _ | Error :: Other ( " " ) ) ? ; // find export "CreateInterface" let create_interface_fn = match pe . get_export ( " " ) . map_err ( Error :: PE ) ? { Export :: Symbol ( s ) => module_info . base ( ) + * s as usize , Export :: Forward ( _ ) => { return Err ( Error :: Other ( " " , ) ) } } ; debug ! ( " " create_interface_fn module_info base ( ) ) ; let virt_mem = & mut process . virt_mem ; // find internal linked list let ci_jmp : u32 = virt_mem . virt_read ( create_interface_fn + 0x5 ) ? ; trace ! ( " " ci_jmp ) ; let ci_followed = Address :: from ( create_interface_fn . as_u32 ( ) + 0x5 + 0x4 + ci_jmp ) ; trace ! ( " " Address from ( ci_followed ) module_info base ( ) ) ; let ci_sig : u16 = virt_mem . virt_read ( ci_followed + 0x4 ) ? ; trace ! ( " " ci_sig ) ; if ci_sig != 0x358B { return Err ( Error :: Other ( " " ) ) ; } let temp : u32 = virt_mem . virt_read ( ci_followed + 0x6 ) ? ; let reg_ptr : Pointer32 < InterfaceReg > = virt_mem . virt_read ( temp . into ( ) ) ? ; let mut reg = reg_ptr . deref ( virt_mem ) ? ; let mut interfaces = Vec :: new ( ) ; loop { let name = virt_mem . virt_read_cstr ( reg . name . into ( ) , 128 ) ? ; let address : u32 = virt_mem . virt_read ( Address :: from ( reg . create ) + 0x1 ) ? ; if address != 0 { info ! ( " " name address module_info name ) ; interfaces . push ( Interface { module_info : module_info . clone ( ) , name , address , } ) ; } else { info ! ( " " name ) ; } if reg . next . is_null ( ) { break ; } reg . next . deref_into ( virt_mem , & mut reg ) ? ; } Ok ( interfaces ) }
Returns a list of all Source Engine Interfaces found in a given module
Returns a list of all Source Engine Interfaces found in a given module
process
&mut Win32Process<T>
module_info
Win32ModuleInfo
process
&mut Win32Process<T>
module_info
Win32ModuleInfo