mod test { use memmap2::Mmap; use pe_parse::header::ProcName; #[test] fn test_header() { println!("This is a test for the header"); } /// 测试导出表的解析 #[test] #[cfg(feature = "memmap2_impl")] fn test_export_table() { use core::ffi; // 1. 创建映射 use pe_parse::file_pe::ReadOnlyPE; let file = std::fs::OpenOptions::new() .read(true) .open("tests/test_dll.dll") .unwrap(); let mmap = unsafe { Mmap::map(&file).unwrap() }; // 2. 解析导出表 let export_table_dir = mmap .get_data_directory(pe_parse::header::ImageDirectoryEntry::Export) .unwrap(); let export_table_rva = export_table_dir.virtual_address; let export_table = mmap.parse_export_table(export_table_rva).unwrap(); println!("{:?}", export_table); // 3. 遍历导出表,打印导出函数 let number_of_fun = export_table.number_of_functions; let functions_table_foa = mmap.rva_to_foa(export_table.address_of_functions).unwrap(); for i in 0..number_of_fun { let functions_item_foa = functions_table_foa + i * std::mem::size_of::() as u32; let rva = mmap .get_ref::(functions_item_foa as usize) .unwrap() .clone(); // 如果rva在[export_table_dir.virtual_address, export_table_dir.virtual_address + export_table_dir.size]之间,则是一个内部导出 if rva >= export_table_dir.virtual_address && rva < export_table_dir.virtual_address + export_table_dir.size { // 这是一个转发 let forward_str_foa = mmap.rva_to_foa(rva).unwrap(); let forward_str = unsafe { ffi::CStr::from_ptr( mmap.get_ref::(forward_str_foa as usize).unwrap() as *const i8 ) .to_str() .unwrap() }; println!("i: {i}, Forward: {}", forward_str); } else { // 这是一个内部导出 打印函数名 println!("i: {i}, Function RVA: {:#x}", rva); } } } #[test] fn test_find_export_function() { let find_function_str = ProcName::Named("test_def_add".to_string()); // let find_function_str = ProcName::Ordinal("div"); // 1. 还是先映射 use pe_parse::file_pe::ReadOnlyPE; let file = std::fs::OpenOptions::new() .read(true) .open("tests/test_dll.dll") .unwrap(); let mmap = unsafe { Mmap::map(&file).unwrap() }; let result_rva = mmap.get_export_function_rva(find_function_str).unwrap(); match result_rva { None => { println!("Can't find the function"); return; } Some(rva) => match rva { pe_parse::header::ExportFunEnum::ExportFunctionRVA(rva) => { println!("Find the function at: {:#x}", rva); } pe_parse::header::ExportFunEnum::ForwarderString(forward_str) => { println!("转发函数,转发到: {}", forward_str); } }, } } }