在 macOS 上检查 ELF 文件并获取二进制文件

Kra*_*011 4 binary macos elf otool binutils

我有一个 ELF 文件,我想从中获取我的代码的hex或文件。bin在终端中,如果 a do a file main,这是我的文件,它会显示:

main: ELF 32-bit LSB executable, UCB RISC-V, version 1 (SYSV), statically linked, not stripped
Run Code Online (Sandbox Code Playgroud)

据我所知,objdump在 macOS 上不起作用,并且otool -l main出现以下错误:

llvm-objdump: 'main': Object is not a Mach-O file type.
Run Code Online (Sandbox Code Playgroud)

ELF 文件是使用以下命令创建的:

riscv-none-gcc/8.2.0-2.1-20190425-1021/bin/riscv-none-embed-gcc --specs=nosys.specs main.c -o main
Run Code Online (Sandbox Code Playgroud)

那么有没有办法做到呢?

多谢

Ioa*_*dis 13

为了创建“原始二进制文件”,objcopy 可以使用 该程序,如下所述

objcopy -O binary foo.elf foo.bin
Run Code Online (Sandbox Code Playgroud)

该程序是MacPortsobjcopy的一部分,可以按如下方式使用:x86_64-elf-binutils

/opt/local/bin/x86_64-elf-objcopy -O binary foo.elf foo.bin
Run Code Online (Sandbox Code Playgroud)

其中foo.elf是在 x86_64 Linux 上编译(或交叉编译)的 ELF 文件。MacPorts 软件包x86_64-elf-binutils可以按如下方式安装:

port install x86_64-elf-binutils
Run Code Online (Sandbox Code Playgroud)

该程序objcopy是 的一部分binutils。对于 Mach-O,可以通过MacPortsbinutils安装在 macOS 上,如下:

port install binutils
Run Code Online (Sandbox Code Playgroud)

MacPortsbinutils软件包安装gobjcopy

binutils用于其他目标系统交叉开发的 macOS版本也可 通过 MacPorts获得。

这篇文章也是受到MacOSX 的启发:哪些动态库由二进制链接?,并且也旨在提供信息。

可执行文件可以是:

ldd

ldd是 Linux 中的一个脚本,它包装了ld. 它被描述为

打印共享对象依赖关系

GNUld在 macOS 上不可用。更根本的是,与、 和 等 工具相比,该ldd调用意味着其操作是非静态的。ldreadelfobjdumpnm

从这个意义上说,即使使用 以外的工具可以获得某些信息ldd,结果也不等同,因为其他工具不会尝试加载二进制文件。此外,尝试加载二进制文件需要在 Linux 上,因此ldd它确实是一个 Linux 工具,无法通过 macOS 上的程序精确模拟。相关说明。确实存在一个纯 Python 实现,它近似于ldd 加载二进制文件的方式ldlddcollectlddcollect可以在存在所需库的 Linux 系统上使用。

不使用的原因之一ldd是安全性:检查可执行文件而不执行它们。

ldd“列出动态依赖项”的缩写。

ldd似乎是 bash 脚本的一部分glibc,源代码位于: https://sourceware.org/git/ ?p=glibc.git;a=blob;f=elf/ldd.bash.in;h=ba736464ac5e4a9390b1b6a39595035238250232 ;hb=271ec55d0ae795f03d92e3aa61bff69a31a19e3a

objdump

objdump显示有关目标文件的信息,并可以反汇编它们。它是 的一部分binutils

objdump在 macOS 上调用的程序:

  • /opt/local/bin/gobjdump通过 MacPorts 包binutils
  • /usr/bin/objdump由 macOS(包的一部分com.apple.pkg.Essentials),它被描述为

    llvm 目标文件转储器

的手册ldd建议调用objdump作为替代方案,如下所示:

objdump -p /path/to/program | grep NEEDED
Run Code Online (Sandbox Code Playgroud)

相关:https ://superuser.com/questions/206547/how-can-i-install-objdump-on-mac-os-x

readelf

readelf通过读取 ELF 文件来显示有关它们的信息(静态,而不是加载它们)。它是 的一部分binutils。它不会can那样反汇编文件objdump

macOS 上可用的变体:

  • /opt/local/bin/greadelf来自 MacPorts 包binutils
  • /opt/local/bin/elftc-readelf来自 MacPorts 包elftoolchain

用法示例:

readelf -s elf_file
Run Code Online (Sandbox Code Playgroud)

nm

  • /usr/bin/nm通过 macOS(包的一部分com.apple.pkg.Essentials
  • /opt/local/bin/nm通过 MacPorts 包cctools,这是一个符号链接:/opt/local/bin/nm -> llvm-nm-mp-10
  • /opt/local/bin/nm-classic通过 MacPorts 包cctools
  • /opt/local/bin/elftc-nm通过 MacPorts 包elftoolchain
  • /opt/local/bin/gnm通过 MacPorts 包binutils

显然,/usr/bin/nm/opt/local/bin/nm都是

llvm 符号表转储器并可处理 ELF 文件。

otool(和变体)

otool是 MacOS 的 Mach-O 格式的反汇编程序。

otoolmacOS 上可用的变体:

  • /usr/bin/otool通过 macOS(包的一部分com.apple.pkg.Essentials
  • /opt/local/bin/otool通过 MacPorts 包cctools,它链接到/opt/local/bin/llvm-otool通过 MacPorts 包cctools,其描述为:

    llvm-objdump 的 otool 兼容命令行解析器

  • /opt/local/bin/otool-classic通过 MacPorts 包cctools

更多细节:

> which -a otool
/opt/local/bin/otool
/usr/bin/otool
> ls -lsa /opt/local/bin/otool
... /opt/local/bin/otool -> llvm-otool
> port provides /opt/local/bin/otool
/opt/local/bin/otool is provided by: cctools
> which -a llvm-otool
/opt/local/bin/llvm-otool
> port provides /opt/local/bin/llvm-otool
/opt/local/bin/llvm-otool is provided by: cctools
> ls -lsa /usr/bin/otool
... /usr/bin/otool
> pkgutil --file-info /usr/bin/otool
volume: /
path: /usr/bin/otool

pkgid: com.apple.pkg.Essentials
...
Run Code Online (Sandbox Code Playgroud)

MacPorts 软件包cctools还安装了/opt/local/bin/otool-classic,正如其文档中所述,该软件包已过时。

elfdump

elfdump可通过 MacPorts 包在 macOS 上使用elftoolchain,并作为二进制文件安装/opt/local/bin/elftc-elfdump

strings

该程序strings对于检查 ELF 文件中包含的符号非常有用。它是一个更通用的工具,不是专门为 ELF 文件设计的,但仍然可用。

macOS 上的变体strings

  • /usr/bin/strings通过 macOS(包的一部分com.apple.pkg.Essentials
  • /opt/local/bin/strings来自 MacPorts 包cctools
  • /opt/local/bin/elftc-strings来自 MacPorts 包elftoolchain
  • /opt/local/bin/gstrings来自 MacPorts 包binutils

用法示例(通过管道传输到ag):

strings some_elf_file | ag GLIBC
Run Code Online (Sandbox Code Playgroud)

elftc-strings与其他实现相比,似乎有更少的选项,给出的结果也更少strings(它们彼此不同,但似乎打印相似的结果)。

elftoolchain

可通过 MacPorts 获得elftoolchain BSD 许可的工具库,例如binutils. 该集合中与分析 ELF 文件相关的工具:

  • /opt/local/bin/elftc-elfdump
  • /opt/local/bin/elftc-nm
  • /opt/local/bin/elftc-readelf
  • /opt/local/bin/elftc-strings

也有实施计划objdump

确认二进制文件来自 MacPorts

要查明给定文件是否是 MacPorts 的一部分:

> port provides /opt/local/bin/otool
/opt/local/bin/otool is provided by: cctools
Run Code Online (Sandbox Code Playgroud)

在这个答案中讨论过。

确认二进制文件来自 macOS

对于了解上面讨论的每个工具的安装方式也很有用pkgutil

pkgutil --file-info /usr/bin/objdump
Run Code Online (Sandbox Code Playgroud)

这有助于确认二进制文件是 macOS 本身的一部分,并且不是通过其他方式安装的。

确认可执行文件是 ELF

当我想分析具有以下详细信息的可执行文件时,我萌生了这篇文章的动机:

> file filename
ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=..., for GNU/Linux 3.2.0, not stripped
Run Code Online (Sandbox Code Playgroud)

至于其他工具,filemacOS 上有多种选择:

  • /usr/bin/file通过 macOS(包的一部分com.apple.pkg.Essentials
  • /opt/local/bin/file通过 MacPorts 包file

其他工具

显然,在某些操作系统上也elftools可用。

为了分析特定架构的文件,有 MacPorts 包,例如arm-elf-binutils.

矮人

还有DWARFdwarftool,以及dwarfdump(XCode 的一部分)。

杂项