【问题标题】:Inspect and get binary from ELF file on MAC检查并从 MAC 上的 ELF 文件中获取二进制文件
【发布时间】:2020-01-15 09:27:19
【问题描述】:

我有一个 ELF 文件,我想从中获取我的代码的 hexbin 文件。在终端中,如果执行file main,这是我的文件,它会显示:

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

据我所知,MAC 上的objdump 无法正常工作,而使用otool -l main 我收到以下错误:

llvm-objdump: 'main': Object is not a Mach-O file type.

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

riscv-none-gcc/8.2.0-2.1-20190425-1021/bin/riscv-none-embed-gcc --specs=nosys.specs main.c -o main

那么有什么办法吗?

非常感谢

【问题讨论】:

  • 代替 otool try 语法兼容 jtool 由 Jonathan Levin 编写,它支持 ELF 并在 macOS 上运行。
  • @Kamil.S 谢谢,我试过jtool/jtool -l main 但这让我很失望Unable to recognize this file - 464C457F

标签: macos binary elf binutils otool


【解决方案1】:

用于创建"raw binary files" 程序objcopy 可以使用,如here所述:

objcopy -O binary foo.elf foo.bin

程序objcopyMacPorts 的一部分 包x86_64-elf-binutils, 并且可以如下使用:

/opt/local/bin/x86_64-elf-objcopy -O binary foo.elf foo.bin

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

port install x86_64-elf-binutils

程序objcopybinutils 的一部分。 对于 Mach-O,它可以通过package binutils 安装在 macOS 上 MacPorts,如下:

port install binutils

MacPorts binutils 包安装gobjcopy

macOS 上的binutils 版本,用于与其他目标系统进行交叉开发, 也是available 通过 MacPorts。

这篇文章的动机也是MacOSX: which dynamic libraries linked by binary?, 并且旨在提供信息。

可执行文件可以是:

ldd

ldd 是 Linux 中的脚本 包裹ld。它被描述为

打印共享对象依赖项

GNU ld 在 macOS 上不可用。更根本的是,ldd 调用 ld 意味着它的操作是非静态的,与readelf 等工具相比, objdumpnm

从这个意义上说,即使某些信息可以使用其他工具获得 比ldd,结果不等价,因为其他工具没有 尝试加载二进制文件。此外,尝试加载二进制文件需要 在 Linux 上,所以 ldd 是 真正的 Linux 工具,不能被 macOS 上的程序完全模拟。 一个relevant description。 确实存在一个纯 Python 实现,它近似于 ldd 没有ld 的方式加载二进制文件:lddcollect。 在 Linux 系统上使用 lddcollect 是可能的,其中所需的库 存在。

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

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

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

objdump

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

在 macOS 上调用 objdump 的程序:

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

    llvm 目标文件转储器

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

objdump -p /path/to/program | grep NEEDED

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

readelf

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

macOS 上可用的变体:

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

示例用法:

readelf -s elf_file

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 格式的反汇编器。

otool 的变体可在 macOS 上使用:

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

    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
...

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

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

还有plans为 实现objdump

确认二进制文件来自 MacPorts

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

> port provides /opt/local/bin/otool
/opt/local/bin/otool is provided by: cctools

this answer讨论。

确认二进制文件来自 macOS

还有useful 用于了解每个 上面讨论的工具中安装了pkgutil

pkgutil --file-info /usr/bin/objdump

这有助于确认二进制文件是 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

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

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

其他工具

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

为了分析特定架构的文件,有 MacPorts 包 喜欢arm-elf-binutils

矮人

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

杂项

【讨论】:

    猜你喜欢
    • 2016-07-06
    • 1970-01-01
    • 1970-01-01
    • 2013-04-17
    • 2016-11-07
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多