Schnauzer is both library and tool for parsing mach-o files
match
blocks for any type of load commandshell
cargo install schnauzer
Call to schnauzer
should have the next pattern:
shell
schnauzer [CMD] path_to_binary
Where CMD
is optional. See Supported commands section
Specify -h
or --help
with or without specify subcommand to see description and supported arguments of the subcommand.
You also can specify path with -p
or --path
(But this not required)
```shell
schnauzer pathtobinary
Fat arch:
|cputype: 16777223
|cpusubtype: 3
|offset: 16384
|size: 70080
|align: 14
|Mach header:
|magic: 0xcffaedfe
|cputype: 16777223
|cpusubtype: 3
|filetype: Exec
|ncmds: 17
|sizeofcmds: 1544
|flags: 0x00200085
|reserved: 0x00000000
|Load commands:
[0] cmd: LC_SEGMENT_64 cmdsize: 72
|segname: __PAGEZERO
|vmaddr: 0x0000000000000000
|vmsize: 0x0000000100000000
|fileoff: 0
|filesize: 0
|maxprot: 0x00000000
|initprot: 0x00000000
|nsects: 0
|flags: 0x00000000
...
```
```shell
schnauzer syms pathtobinary
Arch #1 (Arch: x8664, File type: Exec, Flags: 0x00200085):
[0] Stab(Nopt) radr://5614542
[1] External mhexecuteheader
Section: 1, ndesc: 16, Address: 0x0000000100000000
[2] External _DefaultRuneLocale
ndesc: 256, nvalue: 0
[3] External _error
ndesc: 256, nvalue: 0
[4] External maskrune
ndesc: 256, nvalue: 0
[5] External stackchkfail
ndesc: 256, nvalue: 0
[6] External _stackchk_guard
...
```
```shell
schnauzer rpaths pathtobinary
Arch #0 (Arch: arm64, File type: Exec, Flags: 0x04a18085):
[0] /usr/lib/swift
[1] @loaderpath/Frameworks
[2] @loaderpath/Frameworks
[3] @executablepath/Frameworks
[4] /usr/lib/swift
[5] @executablepath/Frameworks
[6] @loader_path/Frameworks
```
```shell
schnauzer dylibs pathtobinary
Arch #1 (Arch: x86_64, File type: Exec, Flags: 0x00200085):
[0] /usr/lib/libSystem.B.dylib (Timestamp: 2, Current version: 1311.0.0, Compatibility version: 1.0.0)
Arch #2 (Arch: arm64e, File type: Exec, Flags: 0x00200085): [0] /usr/lib/libSystem.B.dylib (Timestamp: 2, Current version: 1311.0.0, Compatibility version: 1.0.0) ```
```shell
schnauzer segs pathtobinary ```
``` Usage:
schnauzer segs path_to_binary [--segs] [--sects] [--short] [--noidx]
--segs - Print only segments
--sects - Print only sections
--short - Print only values and only identifying fields
--noidx - Disable printing indices
```
...
[1] Segment (segname: __TEXT, vmaddr: 0x0000000100000000, vmsize: 0x0000000000004000, fileoff: 0, filesize: 16384, maxprot: 0x00000005, initprot: 0x00000005, nsects: 6, flags: 0x00000000):
Section #1 __text Segment __TEXT:
|*addr: 0x000000010000335c
|*size: 0x000000000000094f
|*offset: 13148
|*align: 2
|*reloff: 0
|*nreloc: 0
|*flags: 0x80000400
|*reserved1: 0
|*reserved2: 0
|*reserved3: 0
...
```shell
schnauzer fat pathtobinary
[0] Arch: x86_64, Offset: 16384, Size: 70080, Align: 14
[1] Arch: arm64e, Offset: 98304, Size: 53488, Align: 14
```
```shell
schnauzer headers pathtobinary
[0] Magic: cffaedfe, Arch: x8664, Capabilities: 0x00, File type: Exec, Commands: 17, Size of commands: 1544, Flags: 0x00200085
Flags(detailed):
MHNOUNDEFS
MHDYLDLINK
MHTWOLEVEL
MHPIE
[1] Magic: cffaedfe, Arch: arm64e, Capabilities: 0x80, File type: Exec, Commands: 18, Size of commands: 1368, Flags: 0x00200085
Flags(detailed):
MHNOUNDEFS
MHDYLDLINK
MHTWOLEVEL
MH_PIE
```
toml
[dependencies]
schnauzer = "0.2.8"
Simple debug print
```rust use schnauzer::ObjectType; use schnauzer::Parser; use std::path::Path;
fn main() { let mut args = std::env::args(); let execname = args.next();
let path = match args.next() {
Some(s) => s,
None => {
eprintln!("Not enough arguments. Provide a valid path to binary");
std::process::exit(1);
}
};
let path = Path::new(&path);
let parser = match Parser::build(path) {
Ok(b) => b,
Err(e) => {
eprintln!("Could not create parser at '{:?}': {e}", path);
std::process::exit(1);
}
};
let object = match parser.parse() {
Ok(o) => o,
Err(e) => {
eprintln!("Error while parsing: {:#?}", e);
std::process::exit(1);
}
};
handle_object(object);
}
fn handle_object(obj: ObjectType) { println!("Object"); println!("{:#?}", obj); } ```
Using AutoEnumFields
derive (code taken from src/main.rs
)
rust
let h = macho.header();
for field in h.all_fields() {
out_dashed_field(field.name, field.value, level);
}
You may email me: arsynthdev@gmail.com