Big update!

- Source code added
- Readme, gitignore, banner and the license are updated
This commit is contained in:
*Nix Fanboy
2024-10-19 19:40:28 +03:00
parent 4f42fe49e2
commit 3336ab8365
32 changed files with 2320 additions and 511 deletions

133
src/elf.rs Executable file
View 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),
},
}
}