1
Fork 0

Check for macho in constructor

This commit is contained in:
Jan-Erik Rediger 2023-12-09 01:11:33 +01:00
parent 387fc40053
commit e7822eae43
2 changed files with 42 additions and 57 deletions

View file

@ -24,16 +24,22 @@ struct Object {
ptr: *mut u8,
#[pyo3(get)]
path: String,
inner: Option<goblin::Object<'static>>,
inner: Option<goblin::mach::MachO<'static>>,
}
// SAFETY: We only use `ptr` in `drop` to reconstruct a `Vec`
unsafe impl Send for Object {}
impl Object {
fn macho(&self) -> &goblin::mach::MachO {
self.inner.as_ref().unwrap()
}
}
#[pymethods]
impl Object {
#[new]
fn new(path: String) -> Self {
fn new(path: String) -> PyResult<Self> {
let path = fs::canonicalize(path).unwrap();
let mut file = File::open(&path).unwrap();
let size = file.metadata().map(|m| m.len() as usize).ok();
@ -49,40 +55,35 @@ impl Object {
let obj = vec.leak();
let object = goblin::Object::parse(obj).unwrap();
Self {
let macho = match object {
goblin::Object::Mach(Mach::Binary(macho)) => macho,
_ => return Err(PyErr::new::<PyTypeError, _>("not a macho file")),
};
Ok(Self {
len,
ptr,
path: path.display().to_string(),
inner: Some(object),
}
inner: Some(macho),
})
}
#[getter]
fn header(&self) -> Header {
match self.inner.as_ref().unwrap() {
goblin::Object::Mach(Mach::Binary(macho)) => Header::from(macho.header),
_ => unimplemented!(),
}
self.macho().header.into()
}
#[getter]
fn name(&self) -> Option<&str> {
match self.inner.as_ref().unwrap() {
goblin::Object::Mach(Mach::Binary(macho)) => macho.name,
_ => unimplemented!(),
}
self.macho().name
}
fn symbols(&self) -> Symbols {
match self.inner.as_ref().unwrap() {
goblin::Object::Mach(Mach::Binary(macho)) => Symbols::from(macho.symbols()),
_ => unimplemented!(),
}
Symbols::from(self.macho().symbols())
}
fn sections(&self) -> Sections {
match self.inner.as_ref().unwrap() {
goblin::Object::Mach(Mach::Binary(macho)) => {
let macho = self.macho();
let mut sections = vec![];
for sect_iter in macho.segments.sections() {
sections.extend(sect_iter.map(|section| {
@ -92,49 +93,32 @@ impl Object {
}
Sections { sections }
}
_ => unimplemented!(),
}
}
#[getter]
fn libs(&self) -> Vec<&str> {
match self.inner.as_ref().unwrap() {
goblin::Object::Mach(Mach::Binary(macho)) => macho.libs.clone(),
_ => unimplemented!(),
}
self.macho().libs.clone()
}
#[getter]
fn rpaths(&self) -> Vec<&str> {
match self.inner.as_ref().unwrap() {
goblin::Object::Mach(Mach::Binary(macho)) => macho.rpaths.clone(),
_ => unimplemented!(),
}
self.macho().rpaths.clone()
}
fn exports(&self) -> Result<Vec<Export>, PyErr> {
match self.inner.as_ref().unwrap() {
goblin::Object::Mach(Mach::Binary(macho)) => {
let macho = self.macho();
let exports = macho
.exports()
.map_err(|_| PyErr::new::<PyTypeError, _>("failed"))?;
Ok(exports.into_iter().map(|exp| exp.into()).collect())
}
_ => unimplemented!(),
}
}
fn imports(&self) -> Result<Vec<Import>, PyErr> {
match self.inner.as_ref().unwrap() {
goblin::Object::Mach(Mach::Binary(macho)) => {
let macho = self.macho();
let imports = macho
.imports()
.map_err(|_| PyErr::new::<PyTypeError, _>("failed"))?;
Ok(imports.into_iter().map(|exp| exp.into()).collect())
}
_ => unimplemented!(),
}
}
}
impl Drop for Object {

View file

@ -1,6 +1,7 @@
import goblin
import oelf
g = goblin.Object("mylib.dylib")
g = oelf.Object("test.py")
g = oelf.Object("mylib.dylib")
print(g.header)
print(g.name)