rea-reverse

原生二进制概览:ELF、PE 与 Mach-O

打开 ELF、PE 或 Mach-O 文件,查看它的架构和文件头、带熵值的节区与段、导入导出的库和符号、安全加固标志以及可打印字符串。不会运行或反汇编文件。

二进制文件不会离开你的浏览器. 文件在一个禁止联网的 Web Worker 中本地解析,不上传任何内容。 如何自己验证

在单独页面打开工具(无广告、无统计)

把一个原生二进制丢进 Ghidra 或 IDA 之前,最好先弄清楚它是什么:面向哪种 CPU,是库还是可执行文件,链接了哪些库,构建时开了哪些加固选项,有没有哪一部分像是被加了壳。通常这意味着要依次跑 file、readelf、otool、nm、strings 和一个 checksec 脚本,而且还得看你手头是什么操作系统。

这个工具把这些信息集中在一个页面里,支持 ELF(Linux、Android、BSD、固件)、PE(Windows 的 EXE、DLL 和驱动)以及 Mach-O(macOS 和 iOS,包括通用二进制)。文件头和各类表都在浏览器里解析,不会运行、反汇编或上传文件。

使用步骤

  1. 准备好要看的二进制:ELF 可执行文件或 .so,Windows 的 .exe、.dll、.sys,或者 Mach-O 可执行文件、.dylib、通用二进制。文件里的任何代码都不会被运行。
  2. 把它拖到上方的拖放区,或者点“选择文件”。文件头和各类表在浏览器里解析,文件不会上传。
  3. 先看基本信息(格式、架构、位数、文件类型),再看安全特性表,然后是带熵值的节区、导入导出和字符串。

真实输出示例

我们下载了 SQLite 官方的 64 位 Windows DLL,把 sqlite3.dll 拖进本页,再把页面显示的结果复制下来。排版做了压缩(标签和值放在同一行,长表格做了截断),所有值都原样保留。

样本: sqlite-dll-win-x64-3540100.zip 里的 sqlite3.dll(SQLite 3.54.1,公有领域),2026-11-02 从 sqlite.org 下载 (sqlite.org/download.html)

基本信息
格式        PE32+
架构        x64 (0x8664)
位数        64 位
字节序      小端
文件类型    DLL (库)
入口点      RVA 0x3779 (VA 0x180003779)
子系统      WINDOWS_GUI
时间戳      2026-10-16T15:16:21Z (0x6ad23fc5) (可复现构建会在这里存一个哈希值)
链接器版本  14.51
映像基址    0x180000000
文件大小    3.4 MB
SHA-256     4b59d3cded9dc1608544160f3b4b10ac974c6ac0d6ffc23064e5f4c8dbd05aea
imphash     04d6d066d04f6497fcb78013cf2630a0
符号        导入 126 个,导出 379 个

安全特性
ASLR(DYNAMIC_BASE)               是      DYNAMIC_BASE
高熵 ASLR(64 位)                 是      HIGH_ENTROPY_VA
DEP / NX(NX_COMPAT)              是      NX_COMPAT
控制流保护(CFG)                  否      no GUARD_CF
SafeSEH 或无 SEH(32 位)          不适用  table-based exception handling
带 Authenticode 签名(未验证)     否      empty security directory
强制签名校验(FORCE_INTEGRITY)    否      no FORCE_INTEGRITY
.NET 程序集(CLI 头)              否

节区(Section) (9)
名称     地址      文件偏移  文件大小  内存大小  权限  类型   熵
.text    0x1000    0x400     2.8 MB    2.8 MB    r-x   CODE   5.84
.rdata   0x2c7000  0x2c5800  419.0 KB  418.7 KB  r--   IDATA  5.15
.data    0x330000  0x32e400  35.5 KB   44.6 KB   rw-   IDATA  3.06
…
.reloc   0x360000  0x357400  16.0 KB   15.6 KB   r--   IDATA  2.85

链接的库 (1)
KERNEL32.dll  导入

导入与导出 (导入 126 个,导出 379 个)
FlushFileBuffers  导入  KERNEL32.dll
GetDriveTypeW     导入  KERNEL32.dll
…
sqlite3_open      导出  #150  0x37dd
…

能做什么

输入。 拖入或选择一个文件,最大 512 MiB。格式根据文件开头的字节判断,而不是看文件名:

  • ELF:32 位和 64 位,小端和大端(ET_EXEC、ET_DYN、ET_REL、ET_CORE)。
  • PE:PE32 和 PE32+(EXE、DLL、SYS 驱动、EFI 映像)。带 CLI 头的文件会标注为 .NET 程序集,并附上 .NET 元数据与 IL 查看器的链接,用来查看它的类型和 IL。
  • Mach-O:32 位和 64 位,任意字节序(可执行文件、dylib、bundle、目标文件、内核扩展)。通用(fat)二进制会列出每个切片的架构、偏移和大小;选中一个切片,报告就切换到它。

报告内容。

  • 基本信息:格式、架构、位数、字节序、文件类型和角色、入口点、文件大小和 SHA-256。不同格式还有:
    • ELF:OS/ABI、PT_INTERP 里的解释器(例如 /lib64/ld-linux-x86-64.so.2 或 /system/bin/linker64)、DT_SONAME 和 GNU build-id。
    • PE:子系统、COFF 时间戳、链接器和系统版本、映像基址,以及 imphash。
    • Mach-O:LC_BUILD_VERSION 或 LC_VERSION_MIN_* 里的平台、最低系统版本和 SDK,LC_UUID,dylib 的安装名,以及代码签名里的签名标识符和 Team ID。
  • 段与节区:名称、地址、文件偏移、文件大小和内存大小、权限(r-x、rw-)、类型,以及每个区域字节的香农熵。高于每字节 7.2 比特(且不小于 1 KiB)的区域会标上“高熵”,表示压缩或加密的数据,例如加壳代码、内嵌压缩包或图片。这很常见,也完全正当,只说明反汇编器在那里看不到代码。
  • 链接的库:ELF 的 DT_NEEDED;PE 的导入 DLL 和延迟加载 DLL;Mach-O 的 LC_LOAD_DYLIB 以及弱链接、再导出、懒加载和 upward dylib。
  • 导入与导出:ELF 的动态符号(.dynsym,目标文件和静态链接程序用 .symtab;没有节区头的二进制则读 PT_DYNAMIC 指向的符号表)及其类型;PE 按 DLL 分组的导入,包括只有序号的导入和延迟加载导入,以及带序号和转发项的导出表;Mach-O 符号表里的外部符号,以及每个导入绑定到哪个 dylib。表格可以按名称或库筛选,也可以按方向筛选,每次渲染 500 行。
  • 安全特性:根据文件头、标志位和导入符号名得出的检查清单:
    • ELF:栈不可执行(PT_GNU_STACK)、PIE、RELRO(部分,或加上 BIND_NOW 的完整 RELRO)、栈保护 canary 和 FORTIFY 线索(是否导入 __stack_chk_fail 和 __*_chk)、符号表是否被剥离。
    • PE:ASLR(DYNAMIC_BASE)、高熵 ASLR、DEP(NX_COMPAT)、控制流保护(CFG)、32 位映像的 SafeSEH 或 NO_SEH、是否带 Authenticode 签名、FORCE_INTEGRITY、.NET。
    • Mach-O:PIE、栈不可执行、栈保护线索、是否带代码签名(CodeDirectory 版本和标志,ad hoc 还是带 CMS 签名)、Hardened Runtime、LC_ENCRYPTION_INFO 的 cryptid、__RESTRICT 段。
  • Go 构建信息:Go 可执行文件会显示 go version -m 输出的内容:Go 版本、主包和主模块、每个依赖模块的版本、校验和以及 => 替换,还有构建设置(-buildmode、-compiler、-trimpath、-ldflags、CGO_ENABLED、GOOS、GOARCH、GOAMD64 或 GOARM64、vcs、vcs.revision、vcs.time、vcs.modified 等)。还可以按 go version -m 的原样格式查看和下载。这条记录在 -ldflags="-s -w" 和 strip 之后依然存在;文件看起来是 Go 程序但记录已经没了时,报告会直接说明。
  • 字符串:至少 6 个字符(可设为 2 到 64)的可打印 ASCII 和 UTF-16LE 字符串,并标出各自所在的节区。按偏移列出前 20,000 个并可筛选;点击“全部下载为 .txt”会按“偏移、编码、节区、文本”的格式导出全部字符串(最多 2,000,000 个)。
  • 导出:整份报告可以下载为 JSON。

原理

页面用 Blob.slice 读取文件,文件头、节区表、符号表和名称都是按需从文件里读出来的。ELF 先读 ELF 头和程序头,再读节区头及其名称表、PT_INTERP、note、动态段(字符串经由 DT_STRTAB,通过 PT_LOAD 段换算成文件偏移)和符号表。PE 读 DOS 头和 COFF 头、可选头及其数据目录、节区表,再顺着 RVA 读导入表、延迟导入表、导出表和 load config。Mach-O 逐条遍历加载命令、nlist 符号表和代码签名的 SuperBlob。Go 构建信息按 Go 自带的 debug/buildinfo 读取:在 .go.buildinfo(ELF)、__go_buildinfo(Mach-O)或第一个可写数据节(PE)里找 16 字节对齐的 \xff Go buildinf: 头,然后解码 Go 1.18 起的格式(头后面紧跟带长度前缀的版本和模块信息字符串)或 Go 1.13 至 1.17 的格式(指向 Go 字符串的指针,按头里给出的指针宽度和字节序、经段映射读出)。每个字符串上限 4 MiB。

每次读取都做边界检查,文件里声明的每个数量在使用前都有上限:节区、段、加载命令和库各 4,096 个,符号 100,000 个,单个表 64 MiB。某个表损坏或被截断时,只跳过这一部分并记在“说明”里,报告的其余部分照常显示。worker 运行超过两分钟会被终止。

SHA-256 用 WebCrypto 计算。WebCrypto 不支持流式哈希,所以会把文件读进内存一次,熵和字符串扫描也复用这份数据。PE 的 imphash 采用 pefile 的算法(get_imphash):按表中顺序取标准导入,DLL 名转小写并去掉 .dll、.ocx 或 .sys,拼成 dll.function,再算 MD5。Go 构建信息在 Go 1.27 和 Go 1.17 为 Linux(amd64、arm64、386、大端 ppc64)、Windows 和 macOS 编译的程序上与 go version -m 逐行核对过。各项结果都在为本工具编译的测试二进制上和 pefile、llvm-readelf、llvm-readobj、otool、nm、codesign、llvm-strings 的输出核对过。

文件如何保持私密

文件不会上传:

  • 工具运行在一个单独的框架(iframe)里,来源是 tools.rea-reverse.com。下面说的处理都在这个框架里、在你的设备上完成。
  • 这个页面在正文之后展示一个广告。广告脚本运行在 rea-reverse.com 上,而框架属于另一个源(origin),浏览器不允许广告脚本或本页的任何其他脚本读取你拖入的文件或结果。
  • 框架的内容安全策略拦截它的脚本能发起的所有请求(connect-src 'none',也不加载任何第三方资源)。框架不能自行打开窗口或让本页跳转;只有你点击报告里的链接时才会打开页面。它传给本页的只有自身高度和下面这些统计事件。
  • 解析、哈希、熵计算和字符串扫描都在你设备上的 Web Worker 里完成。
  • 节区、符号、库和字符串都以纯文本显示,文件里的任何内容都不会被当作 HTML 解析或执行。
  • 统计事件只有粗粒度信息:成功或错误码、格式(elf、pe、macho 或 fat)、粗略的架构(如 x86-64、arm64)、大小区间和耗时区间。不会包含文件名、哈希、符号名、字符串或文件的任何其他内容。框架把事件交给本页,由本页发送。完整列表见隐私页。
  • 不想要任何广告和统计?在单独页面打开工具。

如何自己验证

  1. 打开浏览器开发者工具的 Network(网络) 面板,加载本页。发往 tools.rea-reverse.com 的请求就是框架:它的 HTML、样式、字体和脚本,以及 Worker 脚本 /_astro/binary-worker-*.js。发往 Google 域名的请求是本页的广告。
  2. 清空日志,然后分析一个二进制,切换一次切片,再下载字符串。在过滤框里输入 domain:tools.rea-reverse.com:最多只会再出现一次 Worker 脚本 /_astro/binary-worker-*.js(为下一次运行准备的新 Worker),没有任何请求带着你的数据。广告请求可能还会继续,但它们来自本页,不带框架里的任何内容。
  3. 点开来自 tools.rea-reverse.com 的 binary-overview/ 文档,查看 Headers:它的 Content-Security-Policy 里有 connect-src 'none' 和 frame-ancestors https://rea-reverse.com。在 Chrome 里,Application(应用)> Frames 也能看到框架的源和策略。Worker 运行在 default-src 'none'; script-src 'self'; connect-src 'none' 这条策略下,浏览器不允许它发出任何网络请求。
  4. 检查隔离:在 Console(控制台) 里,上下文选 top,运行 document.getElementById('tool-frame').contentDocument,结果是 null;frames[0].document 会抛出 SecurityError。广告脚本拿到的也是这个结果。
  5. 或者先打开页面再断网(关掉 Wi-Fi,或在 Network 面板勾选 Offline),然后分析文件,照样能用。

局限

  • 不分析代码。 没有反汇编、反编译、控制流或模拟执行。这些请用 REA + Ghidra。
  • 安全特性是线索,不是结论。 canary 和 FORTIFY 只看是否导入了相应的辅助函数,所以静态链接的程序即使开了这些选项也可能显示“否”。缺少 PT_GNU_STACK 时显示为“未知”,因为默认行为取决于平台。
  • 签名只检测,不验证。 Authenticode 和 Mach-O 代码签名只报告是否存在及其基本字段,不检查证书、哈希或公证。
  • imphash。 导入表不完整时不计算;导入表里有 ws2_32.dll、wsock32.dll 或 oleaut32.dll 的纯序号导入时也不计算,因为 pefile 用内置的名称表解析这些序号,而本工具没有附带这些表。和 pefile 一样,延迟加载导入不计入 imphash。
  • Mach-O 导出来自符号表。导出 trie(LC_DYLD_INFO、LC_DYLD_EXPORTS_TRIE)和 chained fixups 不解码,所以去掉了外部符号的二进制显示的导出会比 dyld_info 少。入口点只显示 LC_MAIN 的;LC_UNIXTHREAD 只标出名称,不解码其中的寄存器状态。
  • ELF 不显示符号版本(@GLIBC_2.2.5)。二进制没有节区头时(固件里很常见,sstrip 之后就是这样),动态符号从 PT_DYNAMIC 恢复:DT_SYMTAB 和 DT_STRTAB 经 PT_LOAD 段换算成文件偏移,符号数取自 DT_HASH,没有的话取自 DT_GNU_HASH 的哈希链。两种哈希表都没有时,表的结尾只能估计(到 DT_STRTAB 或 DT_VERSYM 为止),报告里会注明。这种文件的 .symtab 已经没了,所以只列动态符号。处理器专用的段类型和节区类型(0x70000000 起)按文件的 e_machine 命名(MIPS_ABIFLAGS、ARM_EXIDX、RISCV_ATTRIBUTES 等),不认识的显示为 LOPROC+0x…。程序头必须位于文件前 64 KiB 内,超过 2^53 的 64 位偏移(内核映像)会被拒绝。
  • Go 构建信息来自 Go 链接器写入的记录。不用模块(GOPATH 模式)构建的程序只有 Go 版本;Go 1.12 及更早版本构建的程序不读取。混淆器和加壳工具可能删掉或加密它,这时如果 Go 专用节区或 Go build ID 还在,报告会说明没找到记录(加壳后的文件可能根本不显示 Go 部分),本工具不会再从符号或 runtime.buildVersion 推断 Go 版本。特别大的记录最多保留 10,000 个模块和 1,000 项构建设置。
  • 字符串只找可打印 ASCII(0x20–0x7e),单字节或 UTF-16LE 编码单元。其他编码、压缩数据里的字符串以及运行时拼出来的字符串都找不到。
  • 其他格式(没有 MZ 头的 COFF 目标文件、静态库、Java class 文件、WebAssembly)不解析。.wasm 请用 WASM 分析工具。

合规

请只分析你自己编译的程序、开源软件、CTF 题目或你获得授权评估的文件。尊重所分析软件的许可证(包括其中限制逆向工程的条款)以及适用的法律。参见免责声明。

对应的命令行

file 给出格式和 CPU(macOS 自带的 file 5.41):

$ file sqlite3.dll
sqlite3.dll: PE32+ executable (DLL) (GUI) x86-64, for MS Windows

LLVM 的 objdump -p 打印 PE 头(这里是 macOS 自带的 /usr/bin/objdump,Apple LLVM 21.0.0;Linux 上用 llvm-objdump -p)。DllCharacteristics 里是 ASLR 和 DEP 标志,安全目录为空说明没有 Authenticode 签名:

$ objdump -p sqlite3.dll
…
Characteristics 0x2022
        executable
        large address aware
        DLL
…
Magic                   020b    (PE32+)
…
Subsystem               00000002        (Windows GUI)
DllCharacteristics      00000160
                                        HIGH_ENTROPY_VA
                                        DYNAMIC_BASE
                                        NX_COMPAT
…
Entry 4 0000000000000000 00000000 Security Directory
…
Entry e 0000000000000000 00000000 CLR Runtime Header
…
$ objdump -h sqlite3.dll
…
Sections:
Idx Name          Size     VMA              Type
  0 .text         002c53cf 0000000180001000 TEXT
  1 .rdata        00068aa8 00000001802c7000 DATA
  2 .data         00008e00 0000000180330000 DATA
…
  8 .reloc        00003e8c 0000000180360000 DATA
$ shasum -a 256 sqlite3.dll
4b59d3cded9dc1608544160f3b4b10ac974c6ac0d6ffc23064e5f4c8dbd05aea  sqlite3.dll

常见问题

怎么判断一个 DLL 是 32 位还是 64 位?

把它拖进来,看基本信息里的“格式”和“架构”:PE32+ 是 64 位映像,PE32 是 32 位映像,架构一栏给出 CPU,比如上面的 SQLite DLL 是 PE32+、x64 (0x8664)。file 和 objdump -p 打印的是同样的 Magic 和机器类型字段。

能当作在线 checksec 用吗?

可以,用来先看一眼没问题。安全特性表依据的东西和 checksec 是同一类(文件头、标志位和导入的符号名),对 ELF、PE、Mach-O 用的是同一套方式,也不用安装任何东西。措辞有意保持中性:缺少某个特性只是构建方式的事实,不代表存在漏洞。

在这里打开二进制,文件会被上传吗?

不会。文件在你的浏览器里解析,不会发到任何服务器,文件里的代码也不会被执行或反汇编。

为什么某个节区的熵接近 8?

压缩或加密过的数据看起来是随机的,而随机字节的熵接近每字节 8 比特。UPX 之类的壳、内嵌的 .zip 或图片资源、加密的载荷都会这样。代码和文本通常在 4.5 到 6.5 之间,比如上面 SQLite 的 .text 节区是 5.84。

共享库显示“PIE:不适用”,是有问题吗?

没有问题。共享库本身就是位置无关的,PIE 这个问题只针对可执行文件。同理,NX、PIE 和 RELRO 对目标文件也不适用,因为目标文件不会被单独加载。

为什么 fat 二进制里的偏移都很小?

通用二进制里 Mach-O 的偏移是相对每个切片开头的,和 otool 的输出一致。切片列表里写着每个切片在文件中的起始位置。

更新于

相关教程