89 lines
2.9 KiB
Rust
Executable File
89 lines
2.9 KiB
Rust
Executable File
use crate::{
|
|
debug::debug_objects,
|
|
structs::{CharVec, ParsingError, StringPtr, ULDDObj, ULDDObjResult},
|
|
types::{PeOS, PeSubsystem, PE_ARCH, PE_SUBSYSTEM},
|
|
};
|
|
use goblin::pe::{characteristic::IMAGE_FILE_DEBUG_STRIPPED, PE};
|
|
use std::ptr::null_mut;
|
|
|
|
fn find_os_pe(pe: &PE<'_>) -> *mut i8 {
|
|
let Some(optional_header) = pe
|
|
.header
|
|
.optional_header
|
|
.and_then(|h| PE_SUBSYSTEM.get(&h.windows_fields.subsystem))
|
|
else {
|
|
return null_mut();
|
|
};
|
|
|
|
let os = match optional_header {
|
|
PeSubsystem::Xbox => PeOS::Xbox,
|
|
PeSubsystem::EFIApplication
|
|
| PeSubsystem::EFIBootServiceDriver
|
|
| PeSubsystem::EFIRom
|
|
| PeSubsystem::EFIRuntimeDriver => PeOS::UEFI,
|
|
PeSubsystem::WindowsCUI
|
|
| PeSubsystem::WindowsGUI
|
|
| PeSubsystem::Native
|
|
| PeSubsystem::OS2CUI
|
|
| PeSubsystem::PosixCUI
|
|
| PeSubsystem::NativeWindows
|
|
| PeSubsystem::WindowsCEGUI
|
|
| PeSubsystem::WindowsBootApplication => PeOS::Windows,
|
|
PeSubsystem::Unknown => return null_mut(),
|
|
};
|
|
|
|
StringPtr::from(os.to_string()).0
|
|
}
|
|
|
|
pub(crate) fn parse_pe(
|
|
file_name: &str,
|
|
pe: PE,
|
|
member_names: &mut Vec<&str>,
|
|
debugging: bool,
|
|
) -> ULDDObjResult {
|
|
let is_stripped = pe.header.coff_header.characteristics & IMAGE_FILE_DEBUG_STRIPPED
|
|
== IMAGE_FILE_DEBUG_STRIPPED;
|
|
let cpu_type = StringPtr::from(PE_ARCH.get(&pe.header.coff_header.machine)).0;
|
|
let file_type = pe
|
|
.header
|
|
.optional_header
|
|
.and_then(|h| PE_SUBSYSTEM.get(&h.windows_fields.subsystem));
|
|
let interpreter = {
|
|
if let Some(optional_header) = pe.header.optional_header {
|
|
let linker_major_version = optional_header
|
|
.windows_fields
|
|
.major_operating_system_version;
|
|
let linker_minor_version = optional_header
|
|
.windows_fields
|
|
.minor_operating_system_version;
|
|
let linker_version = format!("{}.{}", linker_major_version, linker_minor_version);
|
|
StringPtr::from(linker_version).0
|
|
} else {
|
|
null_mut()
|
|
}
|
|
};
|
|
let executable_format = if pe.is_64 {
|
|
debug_objects(file_name, member_names, "a PE32+ binary", debugging);
|
|
StringPtr::from("PE32+").0
|
|
} else {
|
|
debug_objects(file_name, member_names, "a PE32 binary", debugging);
|
|
StringPtr::from("PE32").0
|
|
};
|
|
ULDDObjResult {
|
|
error: ParsingError::default(),
|
|
obj: ULDDObj {
|
|
file_name: StringPtr::from(file_name).0,
|
|
member_name: CharVec::from(member_names),
|
|
executable_format,
|
|
is_64: pe.is_64,
|
|
os_type: find_os_pe(&pe),
|
|
file_type: StringPtr::from(file_type).0,
|
|
is_stripped,
|
|
cpu_type,
|
|
cpu_subtype: null_mut(),
|
|
interpreter,
|
|
libraries: CharVec::from(pe.libraries),
|
|
},
|
|
}
|
|
}
|