Big update!
- Source code added - Readme, gitignore, banner and the license are updated
This commit is contained in:
133
src/elf.rs
Executable file
133
src/elf.rs
Executable file
@@ -0,0 +1,133 @@
|
||||
use std::ptr::null_mut;
|
||||
|
||||
use crate::{
|
||||
debug::debug_objects,
|
||||
structs::{CharVec, ParsingError, StringPtr, ULDDObj, ULDDObjResult},
|
||||
types::{ElfFileType, ElfOS, E_MACHINE, E_TYPE},
|
||||
};
|
||||
use goblin::elf::Elf;
|
||||
|
||||
fn find_os_from_strtab_elf(elf: &Elf<'_>, pat: &[&str]) -> bool {
|
||||
[
|
||||
elf.strtab.to_vec().unwrap_or(vec![""]),
|
||||
elf.shdr_strtab.to_vec().unwrap_or(vec![""]),
|
||||
elf.dynstrtab.to_vec().unwrap_or(vec![""]),
|
||||
]
|
||||
.iter()
|
||||
.flatten()
|
||||
.any(|s| pat.iter().any(|i| s.to_lowercase().contains(i)))
|
||||
}
|
||||
|
||||
fn find_os_elf(elf: &Elf<'_>, os_abi: u8) -> (ElfOS, *mut i8) {
|
||||
let os = {
|
||||
match os_abi {
|
||||
0x00 => match true {
|
||||
_ if find_os_from_strtab_elf(elf, &["fbsd"]) => ElfOS::FreeBSD,
|
||||
_ if find_os_from_strtab_elf(elf, &["openbsd"]) => ElfOS::OpenBSD,
|
||||
_ if find_os_from_strtab_elf(elf, &["musl", "glibc", "linux"]) => ElfOS::Linux,
|
||||
_ if find_os_from_strtab_elf(elf, &["android"]) => ElfOS::Android,
|
||||
_ if find_os_from_strtab_elf(elf, &["netbsd"]) => ElfOS::NetBSD,
|
||||
_ if find_os_from_strtab_elf(elf, &["solaris"]) => ElfOS::Solaris,
|
||||
_ if find_os_from_strtab_elf(elf, &["illumos"]) => ElfOS::Illumos,
|
||||
_ if elf.interpreter.is_some_and(|v| v.contains("Loader.so")) => ElfOS::SerenityOS,
|
||||
_ => return (ElfOS::Undefined, null_mut()),
|
||||
},
|
||||
0x01 => ElfOS::HPUX,
|
||||
0x02 => ElfOS::NetBSD,
|
||||
0x03 => ElfOS::Linux,
|
||||
0x04 => ElfOS::GNUHurd,
|
||||
0x06 => {
|
||||
if find_os_from_strtab_elf(elf, &["illumos"]) {
|
||||
ElfOS::Illumos
|
||||
} else {
|
||||
ElfOS::Solaris
|
||||
}
|
||||
}
|
||||
0x07 => ElfOS::AIXMonterey,
|
||||
0x08 => ElfOS::IRIX,
|
||||
0x09 => ElfOS::FreeBSD,
|
||||
0x10 => ElfOS::FenixOS,
|
||||
0x11 => ElfOS::CloudABI,
|
||||
0x12 => ElfOS::OpenVOS,
|
||||
0x0A => ElfOS::Tru64,
|
||||
0x0B => ElfOS::NovellModesto,
|
||||
0x0C => ElfOS::OpenBSD,
|
||||
0x0D => ElfOS::OpenVMS,
|
||||
0x0E => ElfOS::NonStopKernel,
|
||||
0x0F => ElfOS::AROS,
|
||||
_ => return (ElfOS::Undefined, null_mut()),
|
||||
}
|
||||
};
|
||||
|
||||
(os, StringPtr::from(os.to_string()).0)
|
||||
}
|
||||
|
||||
fn find_linux_vdso(e_machine: u16, bit_type: bool) -> Option<&'static str> {
|
||||
match e_machine {
|
||||
0x3E => Some("linux-vdso.so.1"),
|
||||
0x03 => Some("linux-vdso.so.1"),
|
||||
0x2A => Some("linux-gate.so.1"),
|
||||
0x16 => {
|
||||
if bit_type {
|
||||
Some("linux-vdso64.so.1")
|
||||
} else {
|
||||
Some("linux-vdso32.so.1")
|
||||
}
|
||||
}
|
||||
0xF3 => Some("linux-vdso.so.1"),
|
||||
0x15 => Some("linux-vdso64.so.1"),
|
||||
0x14 => Some("linux-vdso32.so.1"),
|
||||
0x08 => Some("linux-vdso.so.1"),
|
||||
0x32 => Some("linux-gate.so.1"),
|
||||
0x28 => Some("linux-vdso.so.1"),
|
||||
0xB7 => Some("linux-vdso.so.1"),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_libraries_into_char_vec(elf: &mut Elf, os_abi: u8) -> CharVec {
|
||||
let mut vector = std::mem::take(&mut elf.libraries);
|
||||
if let (Some(vdso), ElfOS::Linux) = (
|
||||
find_linux_vdso(elf.header.e_machine, elf.is_64),
|
||||
find_os_elf(elf, os_abi).0,
|
||||
) {
|
||||
vector.push(vdso)
|
||||
}
|
||||
|
||||
CharVec::from(vector)
|
||||
}
|
||||
|
||||
pub(crate) fn parse_elf(
|
||||
file_name: &str,
|
||||
elf: Elf,
|
||||
os_abi: u8,
|
||||
member_names: &mut Vec<&str>,
|
||||
debugging: bool,
|
||||
) -> ULDDObjResult {
|
||||
let mut elf = elf;
|
||||
let cpu_type = StringPtr::from(E_MACHINE.get(&elf.header.e_machine)).0;
|
||||
let file_type = match E_TYPE.get(&elf.header.e_type) {
|
||||
_ if elf.header.e_type == 0x03 && elf.interpreter.is_some() => {
|
||||
StringPtr::from(ElfFileType::Executable.to_string()).0
|
||||
}
|
||||
rest => StringPtr::from(rest).0,
|
||||
};
|
||||
let interpreter = StringPtr::from(elf.interpreter).0;
|
||||
debug_objects(file_name, member_names, "an ELF binary", debugging);
|
||||
ULDDObjResult {
|
||||
error: ParsingError::default(),
|
||||
obj: ULDDObj {
|
||||
file_name: StringPtr::from(file_name).0,
|
||||
member_name: CharVec::from(member_names),
|
||||
executable_format: StringPtr::from("ELF").0,
|
||||
is_64: elf.is_64,
|
||||
os_type: find_os_elf(&elf, os_abi).1,
|
||||
file_type,
|
||||
is_stripped: elf.syms.is_empty(),
|
||||
cpu_type,
|
||||
cpu_subtype: null_mut(),
|
||||
interpreter,
|
||||
libraries: convert_libraries_into_char_vec(&mut elf, os_abi),
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user