Files
unildd/src/pe.rs
*Nix Fanboy 3336ab8365 Big update!
- Source code added
- Readme, gitignore, banner and the license are updated
2024-10-19 19:40:28 +03:00

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