Rust-Bingrep: bingrep — Greps through binaries from various OSs and architectures, and colors them.

bingrep Build Status

Greps through binaries from various OSs and architectures, and colors them. Current backends:

  • ELF 32/64, arm, x86, openrisc - all others will parse and color, but relocations won't show properly
  • Mach 32/64, arm, x86
  • Unix and BSD archive printer
  • PE (debug only)

NOTE: Building requires rustc version 1.20 or greater. If you're using a distro's rust compiler, consider using https://rustup.rs to install your rustc compiler and associated binaries.

elf_table2

elf_table1

mach

archive

Install

bingrep is available through cargo, via cargo install bingrep, or you can build, and install the resulting binary wherever you like.

Build

Tested with stable rustc 1.38.0.

cargo build --release

Now copy the resulting binary in <path_to_bingrep>/target/release/bingrep wherever you like.

Run

Example:

bingrep /bin/ls

To dump internal debug representation of the parsed binary:

bingrep -d /bin/ls

To demangle symbols, use -D or --demangle:

bingrep -D /bin/ls

Meta Analysis (Experimental)

You can print a hextable (WIP) via --hex or an overview of file offset ranges via --ranges.

ranges

Searching

Search functionality is being added.

You can try it out using bingrep --search "string" or bingrep -s "string". Currently only works for ELF targets.

Please chime in on https://github.com/m4b/bingrep/issues/13 for how this functionality will:

  1. Be presented,
  2. What API will be exposed
  3. What usecases are most important (e.g., how do you like to search binaries)
  4. How it will be implemented

FAQ

Why is this repo called bingrep, it's nothing like grep at all

That's a good question; I was using this as a personal development tool for some time, and I was conferring with someone from the internet about some binary stuff, when I decided I should just upload this to a proper repo instead of sending pictures. So I quickly created a repo, I felt like I had been greppin' through binaries, so that was the name I uploaded. Even worse, I named it bg as the produced executable at the time of the upload, and this of course immediately conflicted with the unix command bg. There's an issue for a better name, you can chime in too!

Why do you/should I use this instead of X ?

For some of my projects or workflows I need to very quickly see the load address, offset, or size of a symbol/program header/section header/export/import. I got tired of using objdump/nm/X because really, I just needed to colorize addresses, sizes etc., so I can quickly identify them and move on. So I wrote this, very quickly, and named it a bad name (sorry!). Then I went totally overboard and started coloring everything, everywhere. You love it, don't worry. Also you're free to use anything you want, whatever makes you happy and productive!

Is there anything to work on?

Yes, there are several open issues. I think I'd actually like to port the symbol map functionality (which enables printing every binary that exports a symbol) from https://github.com/m4b/rdr, as well as implement a "reverse symbol map", which finds every binary that calls/imports a symbol.

If you also like hacking on binary stuff, the backend this uses, https://github.com/m4b/goblin, is responsible for the actual loading, parsing, etc., and there are several open issues on that repo as well if you feel like contributing.

Comments

  • pager issue
    pager issue

    Dec 15, 2017

    When using pager like less or more, bingrep works. However sometimes when it quits, it will panic. Here is a result when using bingrep with rustc with pager more.

    Observations:

    1. This seems to happen for some binaries, e.g., there is no such a panic for /bin/ls on my machine.
    2. Other pager, e.g., view (from nvim) works fine when used like bingrep /path/to/target | view - however will hang forever when using wrongly, e.g., bingrep /path/to/target | view.
    ~ > RUST_BACKTRACE=1 bingrep ~/.cargo/bin/rustc  | more
    thread 'main' panicked at 'Cannot print table to standard output : Broken pipe (os error 32)', /home/hongxu/.cargo/registry/src/github.com-1ecc6299db9ec823/prettytable-rs-0.6.7/src/lib.rs:188:12
    stack backtrace:
       0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
                 at /checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
       1: std::sys_common::backtrace::print
                 at /checkout/src/libstd/sys_common/backtrace.rs:68
                 at /checkout/src/libstd/sys_common/backtrace.rs:57
       2: std::panicking::default_hook::{{closure}}
                 at /checkout/src/libstd/panicking.rs:381
       3: std::panicking::default_hook
                 at /checkout/src/libstd/panicking.rs:397
       4: std::panicking::rust_panic_with_hook
                 at /checkout/src/libstd/panicking.rs:577
       5: std::panicking::begin_panic
                 at /checkout/src/libstd/panicking.rs:538
       6: std::panicking::begin_panic_fmt
                 at /checkout/src/libstd/panicking.rs:522
       7: prettytable::TableSlice::print_tty
       8: bingrep::format_elf::Elf::print::{{closure}}
       9: bingrep::format_elf::Elf::print
      10: bingrep::run
      11: bingrep::main
      12: __rust_maybe_catch_panic
                 at /checkout/src/libpanic_unwind/lib.rs:101
      13: std::rt::lang_start
                 at /checkout/src/libstd/panicking.rs:459
                 at /checkout/src/libstd/rt.rs:58
      14: __libc_start_main
      15: _start
    ~ > file ~/.cargo/bin/rustc
    /home/hongxu/.cargo/bin/rustc: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.9, not stripped
    ~ > /home/hongxu/.cargo/bin/rustc --version                                                                                                                                                               
    rustc 1.24.0-nightly (2d4df9584 2017-12-10)
    
    Reply
  • Linking memrange (via metagoblin) causes GPL license violation
    Linking memrange (via metagoblin) causes GPL license violation

    Sep 15, 2019

    Disclaimer: IANAL. I'm trying my best to be correct but I may be wrong.

    FWICS this package depends on metagoblin and theban_interval_tree, both of which in turn depend on memrange. Since memrange is GPL-3, it effectively requires any derivative work to be licensed GPL-3 as well. theban_interval_tree seems to try to do that. However, both metagoblin and bingrep specify only the MIT license.

    if you wish to continue depending on memrange, I believe you need to redistribute both packages as GPL-3. I think you can still license the source files specific to those packages under the MIT license but the combined work must be licensed GPL-3.

    Reply
  • Disassemble support
    Disassemble support

    Oct 9, 2019

    For example capstone could be used.

    Reply
  • How to correctly page bingrep output with color?
    How to correctly page bingrep output with color?

    Feb 6, 2020

    I just recently discovered bingrep and think it's quite cool. But, in my haste, I decided to try and bingrep ~/.cargo/bin/rg and found it spit out 35000 lines of very nice colorful output. So then tried bingrep ~/.cargo/bin/rg | less and...aww, no color.

    But bingrep -h tells me about the --color option and, yay, color...but also a lot of ^O characters everywhere.

    So, I'm just wondering: is there a way to page bingrep output and make it look like the non-paged output?

    Reply
  • Fix issue where filesz was used instead of memsz
    Fix issue where filesz was used instead of memsz

    Apr 6, 2020

    In the ProgramHeaders summary, file size used for the mem size column.

    Reply
  • memory allocation of 18446744073709551610 bytes failed[1]
    memory allocation of 18446744073709551610 bytes failed[1]

    Aug 9, 2021

    HI ! I found a memory allocation of 18446744073709551610 bytes failed in the current master e232665 POC : poc.zip

    $ ./bingrep out/default/crashes/poc 
    ELF EXEC EM_UNKNOWN-little-endian @ 0x8049080:
    
    e_phoff: 0x80 e_shoff: 0xc e_flags: 0x10000 e_ehsize: 0 e_phentsize: 3 e_phnum: 0 e_shentsize: 36992 e_shnum: 2 e_shstrndx: 0
    
    ProgramHeaders(0):
      
    
    SectionHeaders(2):
    memory allocation of 18446744073709551610 bytes failed[1]    552937 abort      ./bingrep out/default/crashes/poc
    
    Reply
  • Outdated Cargo.lock file?
    Outdated Cargo.lock file?

    Jan 10, 2021

    bingrep is currently failing to build for Homebrew with Rust 1.49 on Apple Silicon: https://github.com/Homebrew/homebrew-core/pull/68089

    It appears this is due to a stale lock file, causing cargo install --locked to pull in dependencies that do not work for bingrep on Apple Silicon. Is it possible for the Cargo.lock file to be updated? If this could be done with a new release, that would be especially helpful.

    Related: https://github.com/Homebrew/homebrew-core/issues/68301

    Reply
  • Skip zero-sized ranges
    Skip zero-sized ranges

    Dec 17, 2019

    Thanks for this awesome tool!

    I ran into a panic when trying bingrep against /bin/ls and the problem was that it was trying to represent the .bss section as a range in the binary, but as you know that section takes no space in the binary.

    Reply
  • bingrep is reported as a lib
    bingrep is reported as a lib

    Jun 12, 2017

    Running bingrep on bingrep, says that it is a lib:

    is_lib: true
    

    While unrelated to this issue, I would also like to note that Soname prints Some("lib") when it is a lib. Maybe it would be better to match on that value and present the name of the lib directly.

    Reply
  • Create git tag for releases
    Create git tag for releases

    Nov 11, 2019

    I'd like to package this tool in Homebrew. However, like many other package managers, a tag release is required. As such, the source code for each versions can be downloaded through some url.

    I noticed there are version bumps in Cargo.toml, so all you need to do is to create git tag (or even better creating Github Release).

    Thanks.

    Reply
  • Error on running command
    Error on running command

    Jun 11, 2017

    Hi,

    I see below error. Didnt find any solution useful on google to resolve this..

    [email protected]:~/Desktop/bingrep-master$ cargo build --release --verbose Updating registry https://github.com/rust-lang/crates.io-index Updating git repository https://github.com/m4b/goblin failed to parse registry's information for: colored

    Caused by: the given version requirement is invalid

    Reply
  • crashes running on itself
    crashes running on itself

    Aug 12, 2018

    rustc 1.30.0-nightly (73c78734b 2018-08-05)
    binary: rustc
    commit-hash: 73c78734bae8f2947a4bfdeabebeeb84ccf0b0e1
    commit-date: 2018-08-05
    host: x86_64-unknown-linux-gnu
    release: 1.30.0-nightly
    LLVM version: 7.0
    

    repo is at 41a73a85920aa0c37846c6d7e5c391c292de1731

    cargo build
    RUST_BACKTRACE=1 ./target/debug/bingrep target/debug/bingrep
    

    crashes:

    [...]
                                                                         0x0                                0x0
                781870    GLOBAL     FUNC        _ZN4core3fmt3num52_$LT$impl$u20$core..fmt..LowerHex$u20$for$u20$i8$GT$3fmt17h4c27396496188f2dE
                                                                         0x91       .text(16)               0x0
                781910    GLOBAL     FUNC        _ZN4core3fmt3num52_$LT$impl$u20$core..fmt..UpperHex$u20$for$u20$i8$GT$3fmt17h62566deaeb3faf4cE
                                                                         0x91       .text(16)               0x0
                7819b0    GLOBAL     FUNC        _ZN4core3fmt3num53_$LT$impl$u20$core..fmt..LowerHex$u20$for$u20$i16$GT$3fmt17hf381e43bda4c6951E
                                                                         0x92       .text(16)               0x0
                781a50    GLOBAL     FUNC        _ZN4core3fmt3num53_$LT$impl$u20$core..fmt..UpperHex$u20$for$u20$i16$GT$3fmt17h93eac570e2e7c86eE
                                                                         0x92       .text(16)               0x0
                785bc0    GLOBAL     FUNC        _ZN4core3fmt9Formatter12pad_integral17h0a1e2b34e19c7ddcE
                                                                         0x3d7      .text(16)               0x0
                782cc0    GLOBAL     FUNC        _ZN49_$LT$i8$u20$as$u20$core..slice..SliceContains$GT$14slice_contains17h417b7695ed3578c1E
                                                                         0x12       .text(16)               0x0
                 853b0    GLOBAL     OBJECT      _ZN4core3str15UTF8_CHAR_WIDTH17h727782c8fa92515fE
                                                                         0x100      .rodata(5)              0x0
                785290    GLOBAL     FUNC        _ZN4core3num21_$LT$impl$u20$u64$GT$25checked_next_power_of_two17h9ebcca98f19e8d85E
                                                                         0x29       .text(16)               0x0
                787d30    GLOBAL     FUNC        _ZN82_$LT$core..fmt..builders..PadAdapter$LT$$u27$a$GT$$u20$as$u20$core..fmt..Write$GT$9write_str17h2ae040e1ef527b3cE
                                                                         0x24e      .text(16)               0x0
                7884f0    GLOBAL     FUNC        _ZN4core3fmt8builders8DebugSet5entry17h69411f4b5bb034afE
                                                                         0xe        .text(16)               0x0
                7897e0    GLOBAL     FUNC        _ZN62_$LT$core..num..bignum..Big32x40$u20$as$u20$core..cmp..Ord$GT$3cmp17hfee4d6134a187f3dE
                                                                         0x55       .text(16)               0x0
                     0    GLOBAL     FUNC        __register_atfork
                                                                         0x0                                0x0
                     0    GLOBAL     FUNC        __cxa_atexit
                                                                         0x0                                0x0
                     0    GLOBAL     FUNC        __xstat64
                                                                         0x0                                0x0
    thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: BadOffset(131072)', libcore/result.rs:983:5
    stack backtrace:
       0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
                 at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
       1: std::sys_common::backtrace::print
                 at libstd/sys_common/backtrace.rs:71
                 at libstd/sys_common/backtrace.rs:59
       2: std::panicking::default_hook::{{closure}}
                 at libstd/panicking.rs:211
       3: std::panicking::default_hook
                 at libstd/panicking.rs:227
       4: std::panicking::rust_panic_with_hook
                 at libstd/panicking.rs:475
       5: std::panicking::continue_panic_fmt
                 at libstd/panicking.rs:390
       6: rust_begin_unwind
                 at libstd/panicking.rs:325
       7: core::panicking::panic_fmt
                 at libcore/panicking.rs:77
       8: core::result::unwrap_failed
                 at /checkout/src/libcore/macros.rs:26
       9: <core::result::Result<T, E>>::unwrap
                 at /checkout/src/libcore/result.rs:782
      10: bingrep::format_elf::Elf::print::{{closure}}
                 at /home/matthias/.cargo/registry/src/github.com-1ecc6299db9ec823/goblin-0.0.14/src/strtab.rs:99
                 at src/format_elf.rs:284
      11: bingrep::format_elf::Elf::print
                 at src/format_elf.rs:300
      12: bingrep::run
                 at src/main.rs:103
      13: bingrep::main
                 at src/main.rs:166
      14: std::rt::lang_start::{{closure}}
                 at /checkout/src/libstd/rt.rs:74
      15: std::panicking::try::do_call
                 at libstd/rt.rs:59
                 at libstd/panicking.rs:310
      16: __rust_maybe_catch_panic
                 at libpanic_unwind/lib.rs:105
      17: std::rt::lang_start_internal
                 at libstd/panicking.rs:289
                 at libstd/panic.rs:392
                 at libstd/rt.rs:58
      18: std::rt::lang_start
                 at /checkout/src/libstd/rt.rs:74
      19: main
      20: __libc_start_main
      21: _start
    
    bug 
    Reply