String Conversion Revamp
- String/&str to C char logic is revamped
This commit is contained in:
@@ -37,7 +37,7 @@ Basically:
|
|||||||
`cp header/unildd.h /my/amazing/project/`
|
`cp header/unildd.h /my/amazing/project/`
|
||||||
|
|
||||||
### License
|
### License
|
||||||
This library is licensed with [BSD-3 Clause License](https://choosealicense.com/licenses/bsd-3-clause/)
|
This library is licensed under [BSD-3 Clause License](https://choosealicense.com/licenses/bsd-3-clause/)
|
||||||
|
|
||||||
The resources used to make this library are cited as comments in the respective source files which they were used.
|
The resources used to make this library are cited as comments in the respective source files which they were used.
|
||||||
|
|
||||||
|
|||||||
0
media/banner/UniLDD Banner.png
Executable file → Normal file
0
media/banner/UniLDD Banner.png
Executable file → Normal file
|
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 120 KiB |
0
media/emblems/UniLDD-%100.png
Executable file → Normal file
0
media/emblems/UniLDD-%100.png
Executable file → Normal file
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
0
media/emblems/UniLDD-%400.png
Executable file → Normal file
0
media/emblems/UniLDD-%400.png
Executable file → Normal file
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
13
src/archive.rs
Executable file → Normal file
13
src/archive.rs
Executable file → Normal file
@@ -1,9 +1,10 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
debug::{debug_objects, find_error_type, merge_members},
|
debug::{debug_objects, merge_members},
|
||||||
parse_objects,
|
parse_objects,
|
||||||
structs::{CharVec, Debugging, ParsingError, StringPtr, ULDDObj, ULDDObjResult},
|
structs::{CharVec, Debugging, ParsingError, ULDDObj, ULDDObjResult},
|
||||||
};
|
};
|
||||||
use goblin::archive::Archive;
|
use goblin::archive::Archive;
|
||||||
|
use crate::impls::{ErrorToInt, StringToCString};
|
||||||
|
|
||||||
pub(crate) fn parse_archive<'a>(
|
pub(crate) fn parse_archive<'a>(
|
||||||
file_name: &'a str,
|
file_name: &'a str,
|
||||||
@@ -25,13 +26,13 @@ pub(crate) fn parse_archive<'a>(
|
|||||||
error)).print(debugging);
|
error)).print(debugging);
|
||||||
return objects.push(ULDDObjResult {
|
return objects.push(ULDDObjResult {
|
||||||
error: ParsingError {
|
error: ParsingError {
|
||||||
code: find_error_type(&error),
|
code: error.to_int(),
|
||||||
explanation: StringPtr::from(error.to_string()).0,
|
explanation: error.to_c_string(),
|
||||||
},
|
},
|
||||||
obj: ULDDObj {
|
obj: ULDDObj {
|
||||||
file_name: StringPtr::from(file_name).0,
|
file_name: file_name.to_c_string(),
|
||||||
member_name: CharVec::from(member_names),
|
member_name: CharVec::from(member_names),
|
||||||
file_type: StringPtr::from("Archive").0,
|
file_type: "Archive".to_c_string(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
14
src/coff.rs
Executable file → Normal file
14
src/coff.rs
Executable file → Normal file
@@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
debug::debug_objects,
|
debug::debug_objects,
|
||||||
structs::{CharVec, ParsingError, StringPtr, ULDDObj, ULDDObjResult},
|
structs::{CharVec, ParsingError, ULDDObj, ULDDObjResult},
|
||||||
types::PE_ARCH,
|
types::PE_ARCH,
|
||||||
};
|
};
|
||||||
use goblin::pe::{
|
use goblin::pe::{
|
||||||
@@ -8,6 +8,8 @@ use goblin::pe::{
|
|||||||
Coff,
|
Coff,
|
||||||
};
|
};
|
||||||
use std::ptr::null_mut;
|
use std::ptr::null_mut;
|
||||||
|
use crate::debug::option_to_c_string;
|
||||||
|
use crate::impls::StringToCString;
|
||||||
|
|
||||||
pub(crate) fn parse_coff(
|
pub(crate) fn parse_coff(
|
||||||
file_name: &str,
|
file_name: &str,
|
||||||
@@ -19,17 +21,17 @@ pub(crate) fn parse_coff(
|
|||||||
let is_64 = coff.header.characteristics & IMAGE_FILE_32BIT_MACHINE != IMAGE_FILE_32BIT_MACHINE;
|
let is_64 = coff.header.characteristics & IMAGE_FILE_32BIT_MACHINE != IMAGE_FILE_32BIT_MACHINE;
|
||||||
let is_stripped =
|
let is_stripped =
|
||||||
coff.header.characteristics & IMAGE_FILE_DEBUG_STRIPPED == IMAGE_FILE_DEBUG_STRIPPED;
|
coff.header.characteristics & IMAGE_FILE_DEBUG_STRIPPED == IMAGE_FILE_DEBUG_STRIPPED;
|
||||||
let cpu_type = StringPtr::from(PE_ARCH.get(&coff.header.machine)).0;
|
let cpu_type = option_to_c_string(PE_ARCH.get(&coff.header.machine));
|
||||||
debug_objects(file_name, member_names, "a COFF binary", debugging);
|
debug_objects(file_name, member_names, "a COFF binary", debugging);
|
||||||
ULDDObjResult {
|
ULDDObjResult {
|
||||||
error: ParsingError::default(),
|
error: ParsingError::default(),
|
||||||
obj: ULDDObj {
|
obj: ULDDObj {
|
||||||
file_name: StringPtr::from(file_name).0,
|
file_name: file_name.to_c_string(),
|
||||||
member_name: CharVec::from(member_names),
|
member_name: CharVec::from(member_names),
|
||||||
executable_format: StringPtr::from("COFF").0,
|
executable_format: "COFF".to_c_string(),
|
||||||
is_64,
|
is_64,
|
||||||
os_type: StringPtr::from("Windows").0,
|
os_type: "Windows".to_c_string(),
|
||||||
file_type: StringPtr::from("Windows object file").0,
|
file_type: "Windows object file".to_c_string(),
|
||||||
is_stripped,
|
is_stripped,
|
||||||
cpu_type,
|
cpu_type,
|
||||||
cpu_subtype: null_mut(),
|
cpu_subtype: null_mut(),
|
||||||
|
|||||||
17
src/debug.rs
17
src/debug.rs
@@ -1,16 +1,11 @@
|
|||||||
use goblin::error::Error as ObjectError;
|
use std::ffi::c_char;
|
||||||
|
use std::fmt::Display;
|
||||||
|
use std::ptr::null_mut;
|
||||||
|
use crate::impls::StringToCString;
|
||||||
use crate::structs::Debugging;
|
use crate::structs::Debugging;
|
||||||
|
|
||||||
pub(crate) fn find_error_type(error: &ObjectError) -> i64 {
|
pub(crate) fn option_to_c_string<T>(option: Option<T>) -> *mut c_char where T: Display {
|
||||||
match error {
|
option.map(|v| v.to_c_string()).unwrap_or(null_mut())
|
||||||
ObjectError::Malformed(_) => -1,
|
|
||||||
ObjectError::BadMagic(_) => -2,
|
|
||||||
ObjectError::Scroll(_) => -3,
|
|
||||||
ObjectError::BufferTooShort(_, _) => -4,
|
|
||||||
ObjectError::IO(_) => -5,
|
|
||||||
_ => -6,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn merge_members(member_names: &mut [&str]) -> String {
|
pub(crate) fn merge_members(member_names: &mut [&str]) -> String {
|
||||||
|
|||||||
18
src/elf.rs
Executable file → Normal file
18
src/elf.rs
Executable file → Normal file
@@ -2,10 +2,12 @@ use std::ptr::null_mut;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
debug::debug_objects,
|
debug::debug_objects,
|
||||||
structs::{CharVec, ParsingError, StringPtr, ULDDObj, ULDDObjResult},
|
structs::{CharVec, ParsingError, ULDDObj, ULDDObjResult},
|
||||||
types::{ElfFileType, ElfOS, E_MACHINE, E_TYPE},
|
types::{ElfFileType, ElfOS, E_MACHINE, E_TYPE},
|
||||||
};
|
};
|
||||||
use goblin::elf::Elf;
|
use goblin::elf::Elf;
|
||||||
|
use crate::debug::option_to_c_string;
|
||||||
|
use crate::impls::StringToCString;
|
||||||
|
|
||||||
fn find_os_from_strtab_elf(elf: &Elf<'_>, pat: &[&str]) -> bool {
|
fn find_os_from_strtab_elf(elf: &Elf<'_>, pat: &[&str]) -> bool {
|
||||||
[
|
[
|
||||||
@@ -59,7 +61,7 @@ fn find_os_elf(elf: &Elf<'_>, os_abi: u8) -> (ElfOS, *mut i8) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
(os, StringPtr::from(os.to_string()).0)
|
(os, os.to_c_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_linux_vdso(e_machine: u16, bit_type: bool) -> Option<&'static str> {
|
fn find_linux_vdso(e_machine: u16, bit_type: bool) -> Option<&'static str> {
|
||||||
@@ -105,21 +107,21 @@ pub(crate) fn parse_elf(
|
|||||||
debugging: bool,
|
debugging: bool,
|
||||||
) -> ULDDObjResult {
|
) -> ULDDObjResult {
|
||||||
let mut elf = elf;
|
let mut elf = elf;
|
||||||
let cpu_type = StringPtr::from(E_MACHINE.get(&elf.header.e_machine)).0;
|
let cpu_type = option_to_c_string(E_MACHINE.get(&elf.header.e_machine));
|
||||||
let file_type = match E_TYPE.get(&elf.header.e_type) {
|
let file_type = match E_TYPE.get(&elf.header.e_type) {
|
||||||
_ if elf.header.e_type == 0x03 && elf.interpreter.is_some() => {
|
_ if elf.header.e_type == 0x03 && elf.interpreter.is_some() => {
|
||||||
StringPtr::from(ElfFileType::Executable.to_string()).0
|
ElfFileType::Executable.to_c_string()
|
||||||
}
|
}
|
||||||
rest => StringPtr::from(rest).0,
|
rest => option_to_c_string(rest),
|
||||||
};
|
};
|
||||||
let interpreter = StringPtr::from(elf.interpreter).0;
|
let interpreter = option_to_c_string(elf.interpreter);
|
||||||
debug_objects(file_name, member_names, "an ELF binary", debugging);
|
debug_objects(file_name, member_names, "an ELF binary", debugging);
|
||||||
ULDDObjResult {
|
ULDDObjResult {
|
||||||
error: ParsingError::default(),
|
error: ParsingError::default(),
|
||||||
obj: ULDDObj {
|
obj: ULDDObj {
|
||||||
file_name: StringPtr::from(file_name).0,
|
file_name: file_name.to_c_string(),
|
||||||
member_name: CharVec::from(member_names),
|
member_name: CharVec::from(member_names),
|
||||||
executable_format: StringPtr::from("ELF").0,
|
executable_format: "ELF".to_c_string(),
|
||||||
is_64: elf.is_64,
|
is_64: elf.is_64,
|
||||||
os_type: find_os_elf(&elf, os_abi).1,
|
os_type: find_os_elf(&elf, os_abi).1,
|
||||||
file_type,
|
file_type,
|
||||||
|
|||||||
57
src/impls.rs
Executable file → Normal file
57
src/impls.rs
Executable file → Normal file
@@ -1,10 +1,23 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
structs::{CharVec, Debugging, ParsingError, StringPtr, ULDDObj},
|
structs::{CharVec, Debugging, ParsingError, ULDDObj},
|
||||||
ULDDObjResult, ULDDObjResultVec,
|
ULDDObjResult, ULDDObjResultVec,
|
||||||
};
|
};
|
||||||
use anstream::{eprintln as a_eprintln, println as a_println};
|
use anstream::{eprintln as a_eprintln, println as a_println};
|
||||||
use owo_colors::OwoColorize;
|
use owo_colors::OwoColorize;
|
||||||
use std::{fmt::Display, mem::ManuallyDrop, ptr::null_mut, ffi::{c_char, CString}};
|
use std::{
|
||||||
|
ffi::{c_char, CString},
|
||||||
|
fmt::Display,
|
||||||
|
mem::ManuallyDrop,
|
||||||
|
ptr::null_mut,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub trait StringToCString {
|
||||||
|
fn to_c_string(self) -> *mut c_char;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ErrorToInt {
|
||||||
|
fn to_int(&self) -> i64;
|
||||||
|
}
|
||||||
|
|
||||||
impl From<Vec<*mut c_char>> for CharVec {
|
impl From<Vec<*mut c_char>> for CharVec {
|
||||||
fn from(value: Vec<*mut c_char>) -> Self {
|
fn from(value: Vec<*mut c_char>) -> Self {
|
||||||
@@ -52,7 +65,7 @@ impl From<Vec<&str>> for CharVec {
|
|||||||
CString::from_vec_unchecked(item.to_string().into_bytes()).into_raw()
|
CString::from_vec_unchecked(item.to_string().into_bytes()).into_raw()
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
CharVec::from(vector)
|
CharVec::from(vector)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,14 +78,17 @@ impl From<&mut Vec<&str>> for CharVec {
|
|||||||
CString::from_vec_unchecked(item.to_string().into_bytes()).into_raw()
|
CString::from_vec_unchecked(item.to_string().into_bytes()).into_raw()
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
CharVec::from(vector)
|
CharVec::from(vector)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<String> for StringPtr {
|
impl<T> StringToCString for T
|
||||||
fn from(value: String) -> Self {
|
where
|
||||||
let mut value = value;
|
T: Display,
|
||||||
|
{
|
||||||
|
fn to_c_string(self) -> *mut c_char {
|
||||||
|
let mut value = self.to_string();
|
||||||
value.push('\0');
|
value.push('\0');
|
||||||
let c_string = match CString::from_vec_with_nul(value.into_bytes()) {
|
let c_string = match CString::from_vec_with_nul(value.into_bytes()) {
|
||||||
Ok(string) => string,
|
Ok(string) => string,
|
||||||
@@ -81,25 +97,20 @@ impl From<String> for StringPtr {
|
|||||||
panic!("{}", error)
|
panic!("{}", error)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
StringPtr(c_string.into_raw())
|
c_string.into_raw()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&str> for StringPtr {
|
impl ErrorToInt for goblin::error::Error {
|
||||||
fn from(value: &str) -> Self {
|
fn to_int(&self) -> i64 {
|
||||||
StringPtr::from(value.to_owned())
|
match self {
|
||||||
}
|
goblin::error::Error::Malformed(_) => -1,
|
||||||
}
|
goblin::error::Error::BadMagic(_) => -2,
|
||||||
|
goblin::error::Error::Scroll(_) => -3,
|
||||||
impl<T> From<Option<T>> for StringPtr
|
goblin::error::Error::BufferTooShort(_, _) => -4,
|
||||||
where
|
goblin::error::Error::IO(_) => -5,
|
||||||
T: Display,
|
_ => -6,
|
||||||
{
|
}
|
||||||
fn from(value: Option<T>) -> Self {
|
|
||||||
let Some(t) = value else {
|
|
||||||
return StringPtr(null_mut());
|
|
||||||
};
|
|
||||||
StringPtr::from(t.to_string())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
22
src/lib.rs
Executable file → Normal file
22
src/lib.rs
Executable file → Normal file
@@ -30,7 +30,7 @@
|
|||||||
//!
|
//!
|
||||||
use archive::parse_archive;
|
use archive::parse_archive;
|
||||||
use coff::parse_coff;
|
use coff::parse_coff;
|
||||||
use debug::{find_error_type, merge_members};
|
use debug::merge_members;
|
||||||
use elf::parse_elf;
|
use elf::parse_elf;
|
||||||
use goblin::Object;
|
use goblin::Object;
|
||||||
use mach::parse_mach;
|
use mach::parse_mach;
|
||||||
@@ -38,8 +38,10 @@ use owo_colors::OwoColorize;
|
|||||||
use pe::parse_pe;
|
use pe::parse_pe;
|
||||||
use std::ffi::{c_char, CStr, CString};
|
use std::ffi::{c_char, CStr, CString};
|
||||||
use structs::{
|
use structs::{
|
||||||
CharVec, Debugging, ParsingError, StringPtr, ULDDObj, ULDDObjResult, ULDDObjResultVec,
|
CharVec, Debugging, ParsingError, ULDDObj, ULDDObjResult, ULDDObjResultVec,
|
||||||
};
|
};
|
||||||
|
use crate::impls::{ErrorToInt, StringToCString};
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub mod archive;
|
pub mod archive;
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
@@ -101,10 +103,10 @@ fn parse_objects<'a>(
|
|||||||
objects.push(ULDDObjResult {
|
objects.push(ULDDObjResult {
|
||||||
error: ParsingError {
|
error: ParsingError {
|
||||||
code: magic_number as i64,
|
code: magic_number as i64,
|
||||||
explanation: StringPtr::from(msg).0,
|
explanation: msg.to_c_string(),
|
||||||
},
|
},
|
||||||
obj: ULDDObj {
|
obj: ULDDObj {
|
||||||
file_name: StringPtr::from(file_name).0,
|
file_name: file_name.to_c_string(),
|
||||||
member_name: CharVec::from(member_names),
|
member_name: CharVec::from(member_names),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@@ -128,10 +130,10 @@ fn parse_objects<'a>(
|
|||||||
objects.push(ULDDObjResult {
|
objects.push(ULDDObjResult {
|
||||||
error: ParsingError {
|
error: ParsingError {
|
||||||
code: -7,
|
code: -7,
|
||||||
explanation: StringPtr::from(msg).0,
|
explanation: msg.to_c_string(),
|
||||||
},
|
},
|
||||||
obj: ULDDObj {
|
obj: ULDDObj {
|
||||||
file_name: StringPtr::from(file_name).0,
|
file_name: file_name.to_c_string(),
|
||||||
member_name: CharVec::from(member_names),
|
member_name: CharVec::from(member_names),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@@ -149,11 +151,11 @@ fn parse_objects<'a>(
|
|||||||
|
|
||||||
objects.push(ULDDObjResult {
|
objects.push(ULDDObjResult {
|
||||||
error: ParsingError {
|
error: ParsingError {
|
||||||
code: find_error_type(&error),
|
code: error.to_int(),
|
||||||
explanation: StringPtr::from(error.to_string()).0,
|
explanation: error.to_c_string(),
|
||||||
},
|
},
|
||||||
obj: ULDDObj {
|
obj: ULDDObj {
|
||||||
file_name: StringPtr::from(file_name).0,
|
file_name: file_name.to_c_string(),
|
||||||
member_name: CharVec::from(member_names),
|
member_name: CharVec::from(member_names),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@@ -225,7 +227,7 @@ unsafe fn drop_c_string(ptr: *mut i8) {
|
|||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// This function is designed for deallocating [`ULDDObjResultVec`] created by rust. Trying to deallocating [`ULDDObjResultVec`] created by other languages may result with errors.
|
/// This function is designed for deallocating [`ULDDObjResultVec`] created by rust. Trying to deallocate [`ULDDObjResultVec`] created by other languages may result with errors.
|
||||||
///
|
///
|
||||||
/// It is null pointer-safe.
|
/// It is null pointer-safe.
|
||||||
///
|
///
|
||||||
|
|||||||
36
src/mach.rs
Executable file → Normal file
36
src/mach.rs
Executable file → Normal file
@@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
debug::{debug_objects, find_error_type, merge_members},
|
debug::{debug_objects, merge_members},
|
||||||
structs::{CharVec, Debugging, ParsingError, StringPtr, ULDDObj, ULDDObjResult},
|
structs::{CharVec, Debugging, ParsingError, ULDDObj, ULDDObjResult},
|
||||||
types::{
|
types::{
|
||||||
MachOCpuType, MachOOs, MACH_O_ARM_CPU_SUBTYPE, MACH_O_CPUTYPE, MACH_O_FILE_TYPE,
|
MachOCpuType, MachOOs, MACH_O_ARM_CPU_SUBTYPE, MACH_O_CPUTYPE, MACH_O_FILE_TYPE,
|
||||||
MACH_O_X86_CPU_SUBTYPE,
|
MACH_O_X86_CPU_SUBTYPE,
|
||||||
@@ -8,6 +8,8 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use goblin::mach::{load_command::CommandVariant::BuildVersion, Mach, MachO};
|
use goblin::mach::{load_command::CommandVariant::BuildVersion, Mach, MachO};
|
||||||
use std::ptr::null_mut;
|
use std::ptr::null_mut;
|
||||||
|
use crate::debug::option_to_c_string;
|
||||||
|
use crate::impls::{ErrorToInt, StringToCString};
|
||||||
|
|
||||||
fn find_os_mach(mach: &MachO<'_>) -> *mut i8 {
|
fn find_os_mach(mach: &MachO<'_>) -> *mut i8 {
|
||||||
for lc in &mach.load_commands {
|
for lc in &mach.load_commands {
|
||||||
@@ -27,7 +29,7 @@ fn find_os_mach(mach: &MachO<'_>) -> *mut i8 {
|
|||||||
0x0C => MachOOs::AppleVisionProSimulator,
|
0x0C => MachOOs::AppleVisionProSimulator,
|
||||||
_ => return null_mut(),
|
_ => return null_mut(),
|
||||||
};
|
};
|
||||||
return StringPtr::from(os.to_string()).0;
|
return os.to_c_string();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,13 +102,13 @@ pub(crate) fn parse_mach<'a>(
|
|||||||
|
|
||||||
return objects.push(ULDDObjResult {
|
return objects.push(ULDDObjResult {
|
||||||
error: ParsingError {
|
error: ParsingError {
|
||||||
code: find_error_type(&error),
|
code: error.to_int(),
|
||||||
explanation: StringPtr::from(error.to_string()).0,
|
explanation: error.to_c_string(),
|
||||||
},
|
},
|
||||||
obj: ULDDObj {
|
obj: ULDDObj {
|
||||||
file_name: StringPtr::from(file_name).0,
|
file_name: file_name.to_c_string(),
|
||||||
member_name: CharVec::from(member_names),
|
member_name: CharVec::from(member_names),
|
||||||
executable_format: StringPtr::from("Mach-O").0,
|
executable_format: "Mach-O".to_c_string(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -129,13 +131,13 @@ pub(crate) fn parse_mach<'a>(
|
|||||||
error)).print(debugging);
|
error)).print(debugging);
|
||||||
objects.push(ULDDObjResult {
|
objects.push(ULDDObjResult {
|
||||||
error: ParsingError {
|
error: ParsingError {
|
||||||
code: find_error_type(&error),
|
code: error.to_int(),
|
||||||
explanation: StringPtr::from(error.to_string()).0,
|
explanation: error.to_c_string(),
|
||||||
},
|
},
|
||||||
obj: ULDDObj {
|
obj: ULDDObj {
|
||||||
file_name: StringPtr::from(file_name).0,
|
file_name: file_name.to_c_string(),
|
||||||
member_name: CharVec::from(member_names.clone()),
|
member_name: CharVec::from(member_names.clone()),
|
||||||
executable_format: StringPtr::from("Mach-O").0,
|
executable_format: "Mach-O".to_c_string(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@@ -156,22 +158,22 @@ fn parse_mach_o(
|
|||||||
debugging: bool,
|
debugging: bool,
|
||||||
) -> ULDDObjResult {
|
) -> ULDDObjResult {
|
||||||
let mut mach_o = mach_o;
|
let mut mach_o = mach_o;
|
||||||
let file_type = StringPtr::from(MACH_O_FILE_TYPE.get(&mach_o.header.filetype)).0;
|
let file_type = option_to_c_string(MACH_O_FILE_TYPE.get(&mach_o.header.filetype));
|
||||||
let (cpu_type, cpu_subtype) = {
|
let (cpu_type, cpu_subtype) = {
|
||||||
if let Some(mach_o_cpu_type) = MACH_O_CPUTYPE.get(&mach_o.header.cputype) {
|
if let Some(mach_o_cpu_type) = MACH_O_CPUTYPE.get(&mach_o.header.cputype) {
|
||||||
let mach_o_cpu_subtype = {
|
let mach_o_cpu_subtype = {
|
||||||
match mach_o_cpu_type {
|
match mach_o_cpu_type {
|
||||||
MachOCpuType::ARM | MachOCpuType::ARM64 => {
|
MachOCpuType::ARM | MachOCpuType::ARM64 => {
|
||||||
StringPtr::from(MACH_O_ARM_CPU_SUBTYPE.get(&mach_o.header.cpusubtype)).0
|
option_to_c_string(MACH_O_ARM_CPU_SUBTYPE.get(&mach_o.header.cpusubtype))
|
||||||
}
|
}
|
||||||
MachOCpuType::X86 | MachOCpuType::X86_64 => {
|
MachOCpuType::X86 | MachOCpuType::X86_64 => {
|
||||||
StringPtr::from(MACH_O_X86_CPU_SUBTYPE.get(&mach_o.header.cpusubtype)).0
|
option_to_c_string(MACH_O_X86_CPU_SUBTYPE.get(&mach_o.header.cpusubtype))
|
||||||
}
|
}
|
||||||
_ => null_mut(),
|
_ => null_mut(),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
(
|
(
|
||||||
StringPtr::from(mach_o_cpu_type.to_string()).0,
|
mach_o_cpu_type.to_c_string(),
|
||||||
mach_o_cpu_subtype,
|
mach_o_cpu_subtype,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
@@ -190,9 +192,9 @@ fn parse_mach_o(
|
|||||||
ULDDObjResult {
|
ULDDObjResult {
|
||||||
error: ParsingError::default(),
|
error: ParsingError::default(),
|
||||||
obj: ULDDObj {
|
obj: ULDDObj {
|
||||||
file_name: StringPtr::from(file_name).0,
|
file_name: file_name.to_c_string(),
|
||||||
member_name: CharVec::from(member_names),
|
member_name: CharVec::from(member_names),
|
||||||
executable_format: StringPtr::from("Mach-O").0,
|
executable_format: "Mach-O".to_c_string(),
|
||||||
is_64: mach_o.is_64,
|
is_64: mach_o.is_64,
|
||||||
os_type: find_os_mach(&mach_o),
|
os_type: find_os_mach(&mach_o),
|
||||||
file_type,
|
file_type,
|
||||||
|
|||||||
18
src/pe.rs
Executable file → Normal file
18
src/pe.rs
Executable file → Normal file
@@ -1,10 +1,12 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
debug::debug_objects,
|
debug::debug_objects,
|
||||||
structs::{CharVec, ParsingError, StringPtr, ULDDObj, ULDDObjResult},
|
structs::{CharVec, ParsingError, ULDDObj, ULDDObjResult},
|
||||||
types::{PeOS, PeSubsystem, PE_ARCH, PE_SUBSYSTEM},
|
types::{PeOS, PeSubsystem, PE_ARCH, PE_SUBSYSTEM},
|
||||||
};
|
};
|
||||||
use goblin::pe::{characteristic::IMAGE_FILE_DEBUG_STRIPPED, PE};
|
use goblin::pe::{characteristic::IMAGE_FILE_DEBUG_STRIPPED, PE};
|
||||||
use std::ptr::null_mut;
|
use std::ptr::null_mut;
|
||||||
|
use crate::debug::option_to_c_string;
|
||||||
|
use crate::impls::StringToCString;
|
||||||
|
|
||||||
fn find_os_pe(pe: &PE<'_>) -> *mut i8 {
|
fn find_os_pe(pe: &PE<'_>) -> *mut i8 {
|
||||||
let Some(optional_header) = pe
|
let Some(optional_header) = pe
|
||||||
@@ -32,7 +34,7 @@ fn find_os_pe(pe: &PE<'_>) -> *mut i8 {
|
|||||||
PeSubsystem::Unknown => return null_mut(),
|
PeSubsystem::Unknown => return null_mut(),
|
||||||
};
|
};
|
||||||
|
|
||||||
StringPtr::from(os.to_string()).0
|
os.to_c_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn parse_pe(
|
pub(crate) fn parse_pe(
|
||||||
@@ -43,7 +45,7 @@ pub(crate) fn parse_pe(
|
|||||||
) -> ULDDObjResult {
|
) -> ULDDObjResult {
|
||||||
let is_stripped = pe.header.coff_header.characteristics & IMAGE_FILE_DEBUG_STRIPPED
|
let is_stripped = pe.header.coff_header.characteristics & IMAGE_FILE_DEBUG_STRIPPED
|
||||||
== IMAGE_FILE_DEBUG_STRIPPED;
|
== IMAGE_FILE_DEBUG_STRIPPED;
|
||||||
let cpu_type = StringPtr::from(PE_ARCH.get(&pe.header.coff_header.machine)).0;
|
let cpu_type = option_to_c_string(PE_ARCH.get(&pe.header.coff_header.machine));
|
||||||
let file_type = pe
|
let file_type = pe
|
||||||
.header
|
.header
|
||||||
.optional_header
|
.optional_header
|
||||||
@@ -57,27 +59,27 @@ pub(crate) fn parse_pe(
|
|||||||
.windows_fields
|
.windows_fields
|
||||||
.minor_operating_system_version;
|
.minor_operating_system_version;
|
||||||
let linker_version = format!("{}.{}", linker_major_version, linker_minor_version);
|
let linker_version = format!("{}.{}", linker_major_version, linker_minor_version);
|
||||||
StringPtr::from(linker_version).0
|
linker_version.to_c_string()
|
||||||
} else {
|
} else {
|
||||||
null_mut()
|
null_mut()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let executable_format = if pe.is_64 {
|
let executable_format = if pe.is_64 {
|
||||||
debug_objects(file_name, member_names, "a PE32+ binary", debugging);
|
debug_objects(file_name, member_names, "a PE32+ binary", debugging);
|
||||||
StringPtr::from("PE32+").0
|
"PE32+".to_c_string()
|
||||||
} else {
|
} else {
|
||||||
debug_objects(file_name, member_names, "a PE32 binary", debugging);
|
debug_objects(file_name, member_names, "a PE32 binary", debugging);
|
||||||
StringPtr::from("PE32").0
|
"PE32".to_c_string()
|
||||||
};
|
};
|
||||||
ULDDObjResult {
|
ULDDObjResult {
|
||||||
error: ParsingError::default(),
|
error: ParsingError::default(),
|
||||||
obj: ULDDObj {
|
obj: ULDDObj {
|
||||||
file_name: StringPtr::from(file_name).0,
|
file_name: file_name.to_c_string(),
|
||||||
member_name: CharVec::from(member_names),
|
member_name: CharVec::from(member_names),
|
||||||
executable_format,
|
executable_format,
|
||||||
is_64: pe.is_64,
|
is_64: pe.is_64,
|
||||||
os_type: find_os_pe(&pe),
|
os_type: find_os_pe(&pe),
|
||||||
file_type: StringPtr::from(file_type).0,
|
file_type: option_to_c_string(file_type),
|
||||||
is_stripped,
|
is_stripped,
|
||||||
cpu_type,
|
cpu_type,
|
||||||
cpu_subtype: null_mut(),
|
cpu_subtype: null_mut(),
|
||||||
|
|||||||
3
src/structs.rs
Executable file → Normal file
3
src/structs.rs
Executable file → Normal file
@@ -99,9 +99,6 @@ pub struct ULDDObjResultVec {
|
|||||||
pub vec: *mut ULDDObjResult,
|
pub vec: *mut ULDDObjResult,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub struct StringPtr(pub *mut i8);
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub(crate) enum Debugging {
|
pub(crate) enum Debugging {
|
||||||
Info(String),
|
Info(String),
|
||||||
|
|||||||
0
src/types.rs
Executable file → Normal file
0
src/types.rs
Executable file → Normal file
Reference in New Issue
Block a user