A zero-copy parser for the contents of the __unwind_info section of a mach-O binary.

Overview

crates.io page docs.rs page

macho-unwind-info

A zero-copy parser for the contents of the __unwind_info section of a mach-O binary.

Quickly look up the unwinding opcode for an address. Then parse the opcode to find out how to recover the return address and the caller frame's register values.

This crate is intended to be fast enough to be used in a sampling profiler. Re-parsing from scratch is cheap and can be done on every sample.

For the full unwinding experience, both __unwind_info and __eh_frame may need to be consulted. The two sections are complementary: __unwind_info handles the easy cases, and refers to an __eh_frame FDE for the hard cases. Conversely, __eh_frame only includes FDEs for functions whose unwinding info cannot be represented in __unwind_info.

On x86 and x86_64, __unwind_info can represent most functions regardless of whether they were compiled with framepointers or without.

On arm64, compiling without framepointers is strongly discouraged, and __unwind_info can only represent functions which have framepointers or which don't need to restore any registers. As a result, if you have an arm64 binary without framepointers (rare!), then the __unwind_info basically just acts as an index for __eh_frame, similarly to .eh_frame_hdr for ELF.

In clang's default configuration for arm64, non-leaf functions have framepointers and leaf functions without stored registers on the stack don't have framepointers. For leaf functions, the return address is kept in the lr register for the entire duration of the function. And the unwind info lets you discern between these two types of functions ("frame-based" and "frameless").

Example

use macho_unwind_info::UnwindInfo;
use macho_unwind_info::opcodes::OpcodeX86_64;

let unwind_info = UnwindInfo::parse(data)?;

if let Some(function) = unwind_info.lookup(0x1234)? {
    println!("Found function entry covering the address 0x1234:");
    let opcode = OpcodeX86_64::parse(function.opcode);
    println!("0x{:08x}..0x{:08x}: {}", function.start_address, function.end_address, opcode);
}

Command-line usage

This repository also contains two CLI executables. You can install them like so:

% cargo install --examples macho-unwind-info

Acknowledgements

Thanks a ton to @Gankra for documenting this format at https://gankra.github.io/blah/compact-unwinding/.

License

Licensed under either of

at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

You might also like...
Easy c̵̰͠r̵̛̠ö̴̪s̶̩̒s̵̭̀-t̶̲͝h̶̯̚r̵̺͐e̷̖̽ḁ̴̍d̶̖̔ ȓ̵͙ė̶͎ḟ̴͙e̸̖͛r̶̖͗ë̶̱́ṉ̵̒ĉ̷̥e̷͚̍ s̷̹͌h̷̲̉a̵̭͋r̷̫̊ḭ̵̊n̷̬͂g̵̦̃ f̶̻̊ơ̵̜ṟ̸̈́ R̵̞̋ù̵̺s̷̖̅ţ̸͗!̸̼͋

Rust S̵̓i̸̓n̵̉ I̴n̴f̶e̸r̵n̷a̴l mutability! Howdy, friendly Rust developer! Ever had a value get m̵̯̅ð̶͊v̴̮̾ê̴̼͘d away right under your nose just when

A utility written in Rust for dumping binary information out of Mach-O files inspired by objdump

Mach-O Dump (macho-dump) An objdump like tool for exploring and manipulating Mach-O files. Note: This project is in an early stage and most of the fea

A minimal and fast zero-copy parser for the PE32+ file format.

peview A minimal and fast zero-copy parser for the PE32+ file format. Goal This project aims to offer a more light weight and easier to use alternativ

Send Youtube videos as audio podcasts to your personal Pocket Casts files section.

yttopocketcasts Send Youtube videos as audio podcasts to your personal Pocket Casts files section. Quick Start Prerequisites: Docker and Make must be

Safe and ergonomic Rust-Mach bindings.

mach-rs This project aims to provide safe and ergonomic bindings to Mach APIs for the Rust programming language. License Copyright (c) 2021 Umang Ragh

Inspect dynamic dependencies of Mach-O binaries recursively

dylibtree dylibtree is a tool for inspecting the dynamic dependencies of a Mach-O binary recursively. It can be useful to understand what library load

Zero-Copy reading and writing of geospatial data.

GeoZero Zero-Copy reading and writing of geospatial data. GeoZero defines an API for reading geospatial data formats without an intermediate represent

Rust wrapper for Eclipse iceoryx™ - true zero-copy inter-process-communication
Rust wrapper for Eclipse iceoryx™ - true zero-copy inter-process-communication

iceoryx-rs Experimental rust wrapper for the iceoryx IPC middleware. clone and build The iceoryx repo is include as git submodule, therefore keep in m

Membrane is an opinionated crate that generates a Dart package from a Rust library. Extremely fast performance with strict typing and zero copy returns over the FFI boundary via bincode.

Membrane is an opinionated crate that generates a Dart package from a Rust library. Extremely fast performance with strict typing and zero copy returns over the FFI boundary via bincode.

 rkyv (archive) is a zero-copy deserialization framework for Rust
rkyv (archive) is a zero-copy deserialization framework for Rust

rkyv (archive) is a zero-copy deserialization framework for Rust Resources Learning Materials The rkyv book covers the motivation, architecture, and m

lightweight, async and zero-copy KV Store
lightweight, async and zero-copy KV Store

KipDB 介绍 网络异步交互、零拷贝的轻量级KV数据库 基于PingCAP课程talent-plan 课程地址:https://github.com/pingcap/talent-plan/tree/master/courses/rust 内置多种持久化内核 HashStore: 基于哈希 Sle

Pure rust library for reading / writing DNG files providing access to the raw data in a zero-copy friendly way.

DNG-rs   A pure rust library for reading / writing DNG files providing access to the raw data in a zero-copy friendly way. Also containing code for re

Zero-copy, no-std proquint encoding and decoding

proqnt A pronounceable quintuplet, or proquint, is a pronounceable 5-letter string encoding a unique 16-bit integer. Proquints may be used to encode b

Rust library for concurrent data access, using memory-mapped files, zero-copy deserialization, and wait-free synchronization.

mmap-sync mmap-sync is a Rust crate designed to manage high-performance, concurrent data access between a single writer process and multiple reader pr

Provably optimal zero-copy parsers using nondeterministic finite automata.
Provably optimal zero-copy parsers using nondeterministic finite automata.

inator: an evil parsing library You supply the evil plan; we supply the -inator! or, Provably Optimal Zero-Copy Parsers with Nondeterministic Finite A

Elkodon - true zero-copy inter-process-communication in rust
Elkodon - true zero-copy inter-process-communication in rust

elkodon - Zero-Copy Lock-Free IPC Purely Written In Rust Introduction Performance Getting Started Publish Subscribe Events Custom Configuration Suppor

Eclipse iceoryx2™ - true zero-copy inter-process-communication in pure Rust
Eclipse iceoryx2™ - true zero-copy inter-process-communication in pure Rust

iceoryx2 - Zero-Copy Lock-Free IPC Purely Written In Rust Introduction Performance Getting Started Publish Subscribe Events Custom Configuration Suppo

secmem-proc is a crate designed to harden a process against low-privileged attackers running on the same system trying to obtain secret memory contents of the current process.

secmem-proc is a crate designed to harden a process against low-privileged attackers running on the same system trying to obtain secret memory contents of the current process. More specifically, the crate disables core dumps and tries to disable tracing on unix-like OSes.

Clipboard Capture for Linux, it can capture the contents of clipboard (or primary selection)
Clipboard Capture for Linux, it can capture the contents of clipboard (or primary selection)

Clipboard Capture for Linux, it can capture the contents of clipboard (or primary selection), as it changes when the program is running and print it to stdout. You can also choose to run some command on each capture.

Comments
  • Remove PageIter

    Remove PageIter

    For the "convenience API", the only reason not to use lookup is for consumers who just want to see all functions. Those consumers are probably not interested in pages, only in the full list of functions. So we should just have an UnwindInfo::functions() method which iterates all pages and functions at the same time.

    opened by mstange 0
Owner
Markus Stange
Markus Stange
secmem-proc is a crate designed to harden a process against low-privileged attackers running on the same system trying to obtain secret memory contents of the current process.

secmem-proc is a crate designed to harden a process against low-privileged attackers running on the same system trying to obtain secret memory contents of the current process. More specifically, the crate disables core dumps and tries to disable tracing on unix-like OSes.

null 3 Dec 19, 2022
The most primitive and the fastest implementation of a fixed-size last-in-first-out stack on stack in Rust, for Copy-implementing types

This is the simplest and the fastest (faster than Vec!) implementation of a last-in-first-out stack data structure, on stack, when stack elements are

Yegor Bugayenko 10 Jun 18, 2023
A following of the book: Zero to Production In Rust

A following of the book: Zero to Production In Rust

Zack Penn 2 Mar 19, 2022
Click-once - A small tiny little binary to fix undesired mouse double clicks in Windows, written in Rust.

click-once A small tiny little binary to fix malfunctioning mouse double clicks in Windows, written in Rust. Minimal executable with little to no over

null 23 Dec 29, 2022
NSE is a rust cli binary and library for extracting real-time data from National Stock Exchange (India)

NSE Check out the sister projects NsePython and SaveKiteEnctoken which are Python & Javascript libraries to use the NSE and Zerodha APIs respectively

Techfane Technologies 4 Nov 28, 2022
Very simple Rust binary that can turn on/off a TP-Link L920 led light strip in your local network

TP-Link L920 on/off script This is a (very) simple Rust binary that can turn on/off a TP-Link L920 led light strip in your local network. Installation

Luciano Mammino 3 Aug 21, 2023
An `abilists` parser crate for Rust

An `abilists` parser crate for Rust

Erich Gubler 24 Aug 28, 2022
lightweight and customizable rust s-expression (s-expr) parser and printer

s-expr Rust library for S-expression like parsing and printing parser keeps track of spans, and representation (e.g. number base) number and decimal d

Vincent Hanquez 5 Oct 26, 2022
A cross platform forensic parser written in Rust!

artemis artemis is a powerful command line digital forensic and incident response (DFIR) tool that collects forensic data from Windows and macOS endpo

null 12 Jun 4, 2023
mach-dump can parse Mach-O core dumps taken with lldb from macOS and iOS devices.

mach-dump mach-dump can parse Mach-O core dumps taken with lldb from macOS and iOS devices. It has no external dependencies. Example use std::path::Pa

Tobi 8 Sep 16, 2022