1
Fork 0

split into modules

This commit is contained in:
Jan-Erik Rediger 2023-12-08 16:51:09 +01:00
parent 89f562fa86
commit 3ede0398eb
5 changed files with 292 additions and 277 deletions

View file

@ -0,0 +1,91 @@
use pyo3::prelude::*;
#[derive(Debug, Default, Clone)]
#[pyclass]
enum ExportTyp {
#[default]
Regular,
Reexport,
Stub
}
#[derive(Debug, Default, Clone)]
#[pyclass]
struct ExportInfo {
#[pyo3(get)]
typ: ExportTyp,
#[pyo3(get)]
address: u64,
#[pyo3(get)]
flags: u64,
#[pyo3(get)]
lib: String,
#[pyo3(get)]
lib_symbol_name: Option<String>,
}
impl From<goblin::mach::exports::ExportInfo<'_>> for ExportInfo {
fn from(info: goblin::mach::exports::ExportInfo) -> Self {
use goblin::mach::exports::ExportInfo::*;
match info {
Regular { address, flags } => {
Self {
typ: ExportTyp::Regular,
address,
flags,
.. Default::default()
}
}
Reexport { lib, lib_symbol_name, flags } => {
Self {
typ: ExportTyp::Reexport,
lib: lib.to_string(),
lib_symbol_name: lib_symbol_name.map(|s| s.to_string()),
flags,
.. Default::default()
}
}
Stub {
flags, ..
} => {
Self {
typ: ExportTyp::Stub,
flags,
.. Default::default()
}
}
}
}
}
#[derive(Debug)]
#[pyclass]
pub struct Export {
#[pyo3(get)]
name: String,
#[pyo3(get)]
info: ExportInfo,
#[pyo3(get)]
size: usize,
#[pyo3(get)]
offset: u64,
}
#[pymethods]
impl Export {
fn __repr__(&self) -> String {
format!("{:?}", self)
}
}
impl From<goblin::mach::exports::Export<'_>> for Export {
fn from(export: goblin::mach::exports::Export) -> Self {
Self {
name: export.name,
info: export.info.into(),
size: export.size,
offset: export.offset,
}
}
}

View file

@ -0,0 +1,44 @@
use pyo3::prelude::*;
#[derive(Debug, Clone)]
#[pyclass]
pub struct Header {
#[pyo3(get)]
magic: u32,
#[pyo3(get)]
cputype: u32,
#[pyo3(get)]
cpusubtype: u32,
#[pyo3(get)]
filetype: u32,
#[pyo3(get)]
ncmds: usize,
#[pyo3(get)]
sizeofcmds: u32,
#[pyo3(get)]
flags: u32,
#[pyo3(get)]
reserved: u32,
}
impl From<goblin::mach::header::Header> for Header {
fn from(other: goblin::mach::header::Header) -> Self {
Header {
magic: other.magic,
cputype: other.cputype,
cpusubtype: other.cpusubtype,
filetype: other.filetype,
ncmds: other.ncmds,
sizeofcmds: other.sizeofcmds,
flags: other.flags,
reserved: other.reserved,
}
}
}
#[pymethods]
impl Header {
fn __repr__(&self) -> String {
format!("{:?}", self)
}
}

View file

@ -0,0 +1,47 @@
use pyo3::prelude::*;
#[derive(Debug)]
#[pyclass]
pub struct Import {
#[pyo3(get)]
name: String,
#[pyo3(get)]
dylib: String,
#[pyo3(get)]
is_lazy: bool,
#[pyo3(get)]
offset: u64,
#[pyo3(get)]
size: usize,
#[pyo3(get)]
address: u64,
#[pyo3(get)]
addend: i64,
#[pyo3(get)]
is_weak: bool,
#[pyo3(get)]
start_of_sequence_offset: u64,
}
#[pymethods]
impl Import {
fn __repr__(&self) -> String {
format!("{:?}", self)
}
}
impl From<goblin::mach::imports::Import<'_>> for Import {
fn from(import: goblin::mach::imports::Import<'_>) -> Self {
Self {
name: import.name.to_string(),
dylib: import.dylib.to_string(),
is_lazy: import.is_lazy,
offset: import.offset,
size: import.size,
address: import.address,
addend: import.addend,
is_weak: import.is_weak,
start_of_sequence_offset: import.start_of_sequence_offset,
}
}
}

View file

@ -3,11 +3,19 @@ use std::{
io::Read, io::Read,
}; };
use goblin::{ use goblin::mach::Mach;
mach::{symbols::Nlist, Mach},
};
use pyo3::{prelude::*, exceptions::PyTypeError}; use pyo3::{prelude::*, exceptions::PyTypeError};
mod exports;
mod header;
mod imports;
mod symbols;
use exports::Export;
use header::Header;
use imports::Import;
use symbols::Symbols;
#[pyclass] #[pyclass]
struct Object { struct Object {
len: usize, len: usize,
@ -118,280 +126,6 @@ impl Drop for Object {
} }
} }
} }
#[derive(Debug, Clone)]
#[pyclass]
struct Header {
#[pyo3(get)]
magic: u32,
#[pyo3(get)]
cputype: u32,
#[pyo3(get)]
cpusubtype: u32,
#[pyo3(get)]
filetype: u32,
#[pyo3(get)]
ncmds: usize,
#[pyo3(get)]
sizeofcmds: u32,
#[pyo3(get)]
flags: u32,
#[pyo3(get)]
reserved: u32,
}
impl From<goblin::mach::header::Header> for Header {
fn from(other: goblin::mach::header::Header) -> Self {
Header {
magic: other.magic,
cputype: other.cputype,
cpusubtype: other.cpusubtype,
filetype: other.filetype,
ncmds: other.ncmds,
sizeofcmds: other.sizeofcmds,
flags: other.flags,
reserved: other.reserved,
}
}
}
#[pymethods]
impl Header {
fn __repr__(&self) -> String {
format!("{:?}", self)
}
}
#[derive(Debug, Clone)]
#[pyclass]
struct Symbol {
#[pyo3(get)]
name: String,
meta: Nlist,
}
#[pymethods]
impl Symbol {
#[getter]
fn typ(&self) -> &'static str {
self.meta.type_str()
}
#[getter]
fn global(&self) -> bool {
self.meta.is_global()
}
#[getter]
fn weak(&self) -> bool {
self.meta.is_weak()
}
#[getter]
fn undefined(&self) -> bool {
self.meta.is_undefined()
}
#[getter]
fn stab(&self) -> bool {
self.meta.is_stab()
}
fn __repr__(&self) -> String {
format!(
"Symbol {{ name: {}, global: {}, weak: {}, undefined: {}, stab: {} }}",
self.name,
self.global(),
self.weak(),
self.undefined(),
self.stab()
)
}
}
#[pyclass]
struct Symbols {
symbols: Vec<Symbol>,
}
#[pymethods]
impl Symbols {
fn __iter__(slf: PyRef<'_, Self>) -> PyResult<Py<SymbolIter>> {
let iter = SymbolIter {
inner: slf.symbols.clone().into_iter(),
};
Py::new(slf.py(), iter)
}
}
impl From<goblin::mach::symbols::SymbolIterator<'_>> for Symbols {
fn from(other: goblin::mach::symbols::SymbolIterator) -> Self {
let symbols = other
.map(|sym| {
let (symname, meta) = sym.unwrap();
Symbol {
name: symname.to_string(),
meta,
}
})
.collect();
Symbols { symbols }
}
}
#[pyclass]
struct SymbolIter {
inner: std::vec::IntoIter<Symbol>,
}
#[pymethods]
impl SymbolIter {
fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> {
slf
}
fn __next__(mut slf: PyRefMut<'_, Self>) -> Option<Symbol> {
slf.inner.next()
}
}
#[derive(Debug, Default, Clone)]
#[pyclass]
enum ExportTyp {
#[default]
Regular,
Reexport,
Stub
}
#[derive(Debug, Default, Clone)]
#[pyclass]
pub struct ExportInfo {
#[pyo3(get)]
typ: ExportTyp,
#[pyo3(get)]
address: u64,
#[pyo3(get)]
flags: u64,
#[pyo3(get)]
lib: String,
#[pyo3(get)]
lib_symbol_name: Option<String>,
}
impl From<goblin::mach::exports::ExportInfo<'_>> for ExportInfo {
fn from(info: goblin::mach::exports::ExportInfo) -> Self {
use goblin::mach::exports::ExportInfo::*;
match info {
Regular { address, flags } => {
Self {
typ: ExportTyp::Regular,
address,
flags,
.. Default::default()
}
}
Reexport { lib, lib_symbol_name, flags } => {
Self {
typ: ExportTyp::Reexport,
lib: lib.to_string(),
lib_symbol_name: lib_symbol_name.map(|s| s.to_string()),
flags,
.. Default::default()
}
}
Stub {
flags, ..
} => {
Self {
typ: ExportTyp::Stub,
flags,
.. Default::default()
}
}
}
}
}
#[derive(Debug)]
#[pyclass]
struct Export {
#[pyo3(get)]
name: String,
#[pyo3(get)]
info: ExportInfo,
#[pyo3(get)]
size: usize,
#[pyo3(get)]
offset: u64,
}
#[pymethods]
impl Export {
fn __repr__(&self) -> String {
format!("{:?}", self)
}
}
impl From<goblin::mach::exports::Export<'_>> for Export {
fn from(export: goblin::mach::exports::Export) -> Self {
Self {
name: export.name,
info: export.info.into(),
size: export.size,
offset: export.offset,
}
}
}
#[derive(Debug)]
#[pyclass]
struct Import {
#[pyo3(get)]
name: String,
#[pyo3(get)]
dylib: String,
#[pyo3(get)]
is_lazy: bool,
#[pyo3(get)]
offset: u64,
#[pyo3(get)]
size: usize,
#[pyo3(get)]
address: u64,
#[pyo3(get)]
addend: i64,
#[pyo3(get)]
is_weak: bool,
#[pyo3(get)]
start_of_sequence_offset: u64,
}
#[pymethods]
impl Import {
fn __repr__(&self) -> String {
format!("{:?}", self)
}
}
impl From<goblin::mach::imports::Import<'_>> for Import {
fn from(import: goblin::mach::imports::Import<'_>) -> Self {
Self {
name: import.name.to_string(),
dylib: import.dylib.to_string(),
is_lazy: import.is_lazy,
offset: import.offset,
size: import.size,
address: import.address,
addend: import.addend,
is_weak: import.is_weak,
start_of_sequence_offset: import.start_of_sequence_offset,
}
}
}
#[pymodule] #[pymodule]
#[pyo3(name = "goblin")] #[pyo3(name = "goblin")]
fn py_goblin(_py: Python<'_>, m: &PyModule) -> PyResult<()> { fn py_goblin(_py: Python<'_>, m: &PyModule) -> PyResult<()> {

View file

@ -0,0 +1,99 @@
use goblin::mach::symbols::Nlist;
use pyo3::prelude::*;
#[derive(Debug, Clone)]
#[pyclass]
struct Symbol {
#[pyo3(get)]
name: String,
meta: Nlist,
}
#[pymethods]
impl Symbol {
#[getter]
fn typ(&self) -> &'static str {
self.meta.type_str()
}
#[getter]
fn global(&self) -> bool {
self.meta.is_global()
}
#[getter]
fn weak(&self) -> bool {
self.meta.is_weak()
}
#[getter]
fn undefined(&self) -> bool {
self.meta.is_undefined()
}
#[getter]
fn stab(&self) -> bool {
self.meta.is_stab()
}
fn __repr__(&self) -> String {
format!(
"Symbol {{ name: {}, global: {}, weak: {}, undefined: {}, stab: {} }}",
self.name,
self.global(),
self.weak(),
self.undefined(),
self.stab()
)
}
}
#[pyclass]
pub struct Symbols {
symbols: Vec<Symbol>,
}
#[pymethods]
impl Symbols {
fn __iter__(slf: PyRef<'_, Self>) -> PyResult<Py<SymbolIter>> {
let iter = SymbolIter {
inner: slf.symbols.clone().into_iter(),
};
Py::new(slf.py(), iter)
}
}
impl From<goblin::mach::symbols::SymbolIterator<'_>> for Symbols {
fn from(other: goblin::mach::symbols::SymbolIterator) -> Self {
let symbols = other
.map(|sym| {
let (symname, meta) = sym.unwrap();
Symbol {
name: symname.to_string(),
meta,
}
})
.collect();
Symbols { symbols }
}
}
#[pyclass]
struct SymbolIter {
inner: std::vec::IntoIter<Symbol>,
}
#[pymethods]
impl SymbolIter {
fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> {
slf
}
fn __next__(mut slf: PyRefMut<'_, Self>) -> Option<Symbol> {
slf.inner.next()
}
}