Git Product home page Git Product logo

elfx86exts's Introduction

elfx86exts

Disassemble a binary and print out which instruction set extensions it uses. Despite the utterly misleading name, this tool supports ELF and MachO binaries, and perhaps other formats as well, and has preliminary support for ARM64 as well as X86/64. It used to be a lot more limited!

I have no idea what I'm doing here, but it seems to work. There are several Rust crates that make this pretty easy to do.

Change Log

See the CHANGELOG on the release branch for news about what has changed between releases.

Installation

Prepackaged

This tool is installable through a few package managers:

If you are interested in packaging elfx86exts in a new packaging system, or have already done so, please submit a PR to add it to this list.

Compiling the Latest Release

If a package is not available, in most cases it will be straightforward to build elfx86exts yourself. Dependencies are:

Both of these dependencies are available through a wide variety of package managers. Once they’re set up, you don’t even need to check out this repository to install the latest release. Simply run:

cargo install elfx86exts

… and the tool will be installed in your Cargo binary directory, usually ~/.cargo/bin/. When using this method, you need to add the --force flag to upgrade from one version to the next.

Compiling the Code From Git

This is hardly any more difficult than the above. Check out this repository, then run:

cargo install --path .

To develop the program, use the cargo build and cargo run commands. For more information, see The Cargo Book.

Contributions

Contributions are welcome! Please submit PRs against this repository, or file issues for discussion. The only important rule is that all participants are expected to abide by the spirit of a standard Contributor Covenant code of conduct. All contributions will be assumed to be licensed under the terms described below unless you explicitly state otherwise.

Licensing

Licensed under the MIT License.

elfx86exts's People

Contributors

apjanke avatar bjmoran avatar dargor avatar dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar hanabishirecca avatar jasonmccampbell avatar pkgw avatar reuben avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

elfx86exts's Issues

Excessive memory consumption

As reported in the discussion of #66, it seems that this program sometimes eats up an amount of memory that is totally out of line with what it should be doing. E.g., "Analyzing a 123MB binary OOMs my 24GB RAM machine."

I don't use this tool myself anymore and unfortunately I'm not in a position to spend time on it, but maybe the proposal in #47 would help with addressing this. The approach taken by the code for this program is about as straightforward as it can get, so I feel like there must be a problem with one of the underlying libraries (or their Rust bindings).

CC @rowanworth @Ristovski @oldherl

Proposal: use iced-x86 for your x86 decoding

Hey there! A coworker of mine shared this with me, and I thought it was very cool.

I noticed that you're using Capstone for your instruction decoding, and then mapping Capstone's internal "group" enum back to human-readable identifiers. I wanted to propose that you give iced-x86 a spin (no affiliation!); I think it has several features that you'll find advantageous:

  1. It has direct support for CPUID/feature-level extraction, via cpuid_features
  2. It's written in pure Rust, which means that your users won't need to install libcapstone
  3. It's much more correct than Capstone (from fuzzing), about on par with Intel's reference decoder (XED)

I'm happy to help with the work that would be involved in replacing Capstone, if you're interested! Feel free to close otherwise 🙂

elfx86exts 0.4.3 / capstone 0.7.0 overlooks instructions in some circumstances

Basically I have two builds of elfx86exts, both of which I'm running against the same large binary (126M). Both builds were created via cargo install elfx86exts with rust-1.48.0. The first build is stock elfx86exts-0.4.3 and the second build is one I patched manually to update the capstone dependency to ^0.10 (previous build was against the capstone-0.7.0 crate).

The two behave very differently. Here's the stock version:

$ time elfx86exts test_binary
MODE64 (call)
SSE1 (stmxcsr)
AVX (vzeroupper)
AVX2 (vpcmpeqd)
NOVLX (vpcmpeqd)
CPU Generation: Unknown

real	0m0.044s
user	0m0.007s
sys	0m0.015s

And here's my manually patched version:

$ time elfx86exts test_binary
MODE64 (call)
SSE1 (stmxcsr)
AVX (vzeroupper)
AVX2 (vpcmpeqd)
NOVLX (vpcmpeqd)
AVX512 (vmovdqu32)
SSE2 (pcmpeqd)
CMOV (cmovne)
VLX (vpbroadcastd)
BWI (vpcmpeqb)
BMI (andn)
CDI (vptestnmd)
DQI (kmovb)
BMI2 (shlx)
SSE3 (movddup)
SSE41 (roundss)
MMX (emms)
SSE42 (pcmpistri)
SSSE3 (phaddd)
NOT64BITMODE (xchg)
CPU Generation: Unknown

real	0m47.405s
user	0m29.692s
sys	0m17.684s

Wildly different runtimes and detected instruction sets. It seems like the stock version is exiting early but it does so silently and without raising any error (exit code is 0).

I had to change two lines to get here; the first was in Cargo.tml:

 [dependencies.capstone]
-version = "^0.7"
+version = "^0.10"

And the second in src/main.rs:

             for group_code in detail.groups() {
-                if seen_groups.insert(group_code) {
+                if seen_groups.insert(group_code.clone()) {
                     // If insert returned true, we hadn't seen this code before.
                     if let Some(desc) = describe_group(group_code.0) {

To satisfy the borrow checker -- I guess the return type of detail.groups() has changed upstream but I didn't investigate in detail, just picked up the biggest hammer from my rust beginner's toolkit :)

Add Arm64 support

Hi,

This utility has turned out to be quite useful in quickly figuring out why a given binary doesn't run on a particular processor. However, we've also run into the same issue with Arm processors. I saw that it's based on capstone so there wasn't a particular limitation to only x86, so I added PR #166. Is this of interest? If so, I'll clean up the PR for a true submission.

Jason

UnknownCapstoneError (src/libcore/result.rs:997:5)

I get the following output with every binary I tried.

$ env RUST_BACKTRACE=1 elfx86exts /usr/bin/ping
thread 'main' panicked at 'couldn't disassemble section: UnknownCapstoneError', src/libcore/result.rs:997:5
stack backtrace:
   0: <unknown>
   1: <unknown>
   2: <unknown>
   3: <unknown>
   4: <unknown>
   5: <unknown>
   6: <unknown>
   7: <unknown>
   8: <unknown>
   9: <unknown>
  10: <unknown>
  11: <unknown>
  12: <unknown>
  13: <unknown>
  14: <unknown>
  15: __libc_start_main
  16: <unknown>

Problems reading binaries linked with `mold`

elfx86exts has problems reading binaries linked with mold.

Somehow it is unable to detect all or almost all instruction sets. This happens with all compilers and languages, but has some correlation with compiler flags used.


E.g. lets examine elfx86exts itself linked with the default Rust linker outputs:

$ elfx86exts ./elfx86exts
File format and CPU architecture: Elf, X86_64
MODE64 (call)
CMOV (cmova)
SSE2 (movdqa)
BMI (tzcnt)
SSE1 (movups)
AVX (vmovdqa)
AVX2 (vpcmpeqb)
NOVLX (vpcmpeqb)
Instruction set extensions used: AVX, AVX2, BMI, CMOV, MODE64, NOVLX, SSE1, SSE2
CPU Generation: Unknown

Seems legit and indeed I can find say vpcmpeqb in objdump:

0000000000203500 <_ZN6memchr4arch6x86_644avx26memchr3One13find_raw_avx217he5d0877342d03fe8E>:
  203500:	48 89 d1             	mov    %rdx,%rcx
  203503:	48 89 f2             	mov    %rsi,%rdx
  203506:	c5 fd 6f 07          	vmovdqa (%rdi),%ymm0
  20350a:	c5 fd 74 0e          	vpcmpeqb (%rsi),%ymm0,%ymm1
  20350e:	c5 fd d7 f1          	vpmovmskb %ymm1,%esi
  203512:	85 f6                	test   %esi,%esi
  203514:	74 16                	je     20352c

But when linked with mold (i.e. RUSTFLAGS='-C link-arg=-fuse-ld=mold' cargo build --release):

$ elfx86exts ./elfx86exts
File format and CPU architecture: Elf, X86_64
MODE64 (push)
CMOV (cmova)
SSE2 (movdqa)
BMI (tzcnt)
SSE1 (movups)
Instruction set extensions used: BMI, CMOV, MODE64, SSE1, SSE2
CPU Generation: Haswell

AVX is not detected, despite I still can find the same piece of code in objdump:

0000000000636db0 <_ZN6memchr4arch6x86_644avx26memchr3One13find_raw_avx217he5d0877342d03fe8E>:
  636db0:	48 89 d1             	mov    %rdx,%rcx
  636db3:	48 89 f2             	mov    %rsi,%rdx
  636db6:	c5 fd 6f 07          	vmovdqa (%rdi),%ymm0
  636dba:	c5 fd 74 0e          	vpcmpeqb (%rsi),%ymm0,%ymm1
  636dbe:	c5 fd d7 f1          	vpmovmskb %ymm1,%esi
  636dc2:	85 f6                	test   %esi,%esi
  636dc4:	74 16                	je     636ddc

I guess mold does something unusual, which somehow confuses elfx86exts.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.