25 个版本
0.3.5 | 2023 年 9 月 13 日 |
---|---|
0.3.4 | 2023 年 6 月 13 日 |
0.2.9 | 2023 年 6 月 2 日 |
0.2.8 | 2023 年 5 月 30 日 |
0.1.5 | 2023 年 4 月 28 日 |
390 在 解析实现 中
每月 130 次下载
在 brew-moonshine 中使用
1.5MB
5.5K SLoC
雪纳瑞
schnauzer
是解析 mach-o 文件的库和工具,打印符号表、使用的动态库、相对路径、重定位条目等。 查看命令列表。
库功能
- 零拷贝。不会将整个二进制文件加载到内存中。使用迭代器列出可能大量项目
- 端序感知
- 实现了 derive 宏来自动字段枚举,例如,打印任意加载命令非常方便。甚至不需要为任何类型的加载命令编写大的
match
块 - 以彩色打印文件结构,提高用户体验
安装
cargo install schnauzer
参数
调用 schnauzer
应具有以下模式
schnauzer [CMD] path_to_binary
其中 CMD
是可选的。请参阅 支持的命令 部分
使用 -h
或 --help
指定子命令或未指定子命令以查看子命令的描述和受支持的参数。
您还可以使用 -p
或 --path
指定路径(但这不是必需的)
支持的命令
schnauzer lcFILE [--路径<FILE>] [--帮助] [--架构<名称>] [--短名称] [--无索引]
schnauzer symsFILE [--路径<FILE>] [--帮助] [--架构<名称>] [--短名称] [--无索引]
schnauzer rpathsFILE [--路径<FILE>] [--帮助] [--架构<名称>] [--短名称] [--无索引]
schnauzer dylibsFILE [--路径<FILE>] [--帮助] [--架构<名称>] [--短名称] [--无索引]
schnauzer segsFILE [--路径<FILE>] [--帮助] [--架构<名称>] [--segs] [--sects] [--短名称] [--无索引]
schnauzer fatFILE [--路径<FILE>] [--帮助] [--架构<名称>]
schnauzer headersFILE [--路径<FILE>] [--帮助] [--架构<名称>] [--短名称] [--无索引]
schnauzer relFILE [--路径<FILE>] [--帮助] [--架构<名称>]
schnauzer dataFILE [--路径-p<FILE>] [--帮助-h] [--架构-a<名称>] --sect-s<segname sectname>
默认
# Prints almost all binary info
schnauzer path_to_binary
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
...
lc
# Prints load commands
schnauzer lc path_to_binary
Arch #0 (Arch: x86_64, File type: Exec, Flags: 0x00200085):
cmd: LC_SEGMENT_64 cmdsize: 72
segname: __PAGEZERO
vmaddr: 0x0000000000000000
vmsize: 0x0000000100000000
fileoff: 0
filesize: 0
maxprot: 0x00000000
initprot: 0x00000000
nsects: 0
flags: 0x00000000
cmd: LC_SEGMENT_64 cmdsize: 552
segname: __TEXT
vmaddr: 0x0000000100000000
vmsize: 0x0000000000004000
fileoff: 0
syms
# Prints symtab
schnauzer syms path_to_binary
Arch #1 (Arch: x86_64, File type: Exec, Flags: 0x00200085):
[0] Stab(Nopt) radr://5614542
[1] External __mh_execute_header
Section: 1, n_desc: 16, Address: 0x0000000100000000
[2] External __DefaultRuneLocale
n_desc: 256, n_value: 0
[3] External ___error
n_desc: 256, n_value: 0
[4] External ___maskrune
n_desc: 256, n_value: 0
[5] External ___stack_chk_fail
n_desc: 256, n_value: 0
[6] External ___stack_chk_guard
...
rpaths
# Prints relative paths
schnauzer rpaths path_to_binary
Arch #0 (Arch: arm64, File type: Exec, Flags: 0x04a18085):
[0] /usr/lib/swift
[1] @loader_path/Frameworks
[2] @loader_path/Frameworks
[3] @executable_path/Frameworks
[4] /usr/lib/swift
[5] @executable_path/Frameworks
[6] @loader_path/Frameworks
dylibs
# Prints used dynamic libraries
schnauzer dylibs path_to_binary
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)
segs
# Prints all the segments with sections
schnauzer segs path_to_binary
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
...
fat
# Prints the fat archs
schnauzer fat path_to_binary
[0] Arch: x86_64, Offset: 16384, Size: 70080, Align: 14
[1] Arch: arm64e, Offset: 98304, Size: 53488, Align: 14
headers
# Prints headers
schnauzer headers path_to_binary
[0] Magic: cffaedfe, Arch: x86_64, Capabilities: 0x00, File type: Exec, Commands: 17, Size of commands: 1544, Flags: 0x00200085
Flags(detailed):
MH_NOUNDEFS
MH_DYLDLINK
MH_TWOLEVEL
MH_PIE
[1] Magic: cffaedfe, Arch: arm64e, Capabilities: 0x80, File type: Exec, Commands: 18, Size of commands: 1368, Flags: 0x00200085
Flags(detailed):
MH_NOUNDEFS
MH_DYLDLINK
MH_TWOLEVEL
MH_PIE
rel
# Prints relocation entries
schnauzer rel path_to_binary
__TEXT __text (5 entries)
address pcrel length extern type scattered symbolnum/value
000000b0 1 2 1 2 false 10
000000ac 0 2 1 4 false 2
000000a8 1 2 1 3 false 2
0000009c 0 2 1 4 false 1
00000098 1 2 1 3 false 1
__DATA __const (1 entries)
address pcrel length extern type scattered symbolnum/value
00000000 0 3 1 0 false 4
__DWARF __debug_info (16 entries)
address pcrel length extern type scattered symbolnum/value
000004c2 0 3 0 0 false 1
000004ba 0 3 0 0 false 1
00000499 0 3 0 0 false 1
00000491 0 3 0 0 false 1
00000477 0 3 0 0 false 1
data
# Prints hex dump
schnauzer data path_to_binary -s __TEXT __cstring
Arch #0 (Arch: x86_64, File type: Exec, Flags: 0x00200085):
__TEXT __cstring
0000000100003f2a 0062656c 6e737475 76007374 646f7574 |.belnstuv.stdout|
0000000100003f3a 00757361 67653a20 63617420 5b2d6265 |.usage: cat [-be|
0000000100003f4a 6c6e7374 75765d20 5b66696c 65202e2e |lnstuv] [file ..|
0000000100003f5a 2e5d0a00 2d007374 64696e00 25730072 |.]..-.stdin.%s.r|
用法
[dependencies]
schnauzer = "0.3.5"
示例
简单的调试打印
use schnauzer::ObjectType;
use schnauzer::Parser;
use std::path::Path;
fn main() {
let mut args = std::env::args();
let _exec_name = 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);
}
使用 AutoEnumFields
derive(从 src/main.rs
中获取的代码)
let h = macho.header();
for field in h.all_fields() {
out_dashed_field(field.name, field.value, level);
}
联系方式
您可以通过电子邮件联系我: [email protected]
依赖项
~1–12MB
~83K SLoC