radare2 macOS 深度指南:代码签名、调试授权与安装打包全解析
【免费下载链接】radare2UNIX-like reverse engineering framework and command-line toolset项目地址: https://gitcode.com/gh_mirrors/ra/radare2
导读
macOS 的代码签名(Code Signing)与系统完整性保护(SIP)机制,让 radare2 在调试其他进程时面临额外门槛:未经正确签名的二进制无法获得调试权限,也无法直接以非 root 身份附加到目标进程。本文以 doc/macos.md 为骨架,结合仓库中的构建脚本(sys/install.sh、sys/build.sh、sys/static.sh)、签名 Makefile 目标(binr/radare2/Makefile)、entitlements 文件(binr/radare2/radare2_macos.xml)与打包脚本(sys/osx-pkg.sh、dist/macos/osx-pkg-uninstall.sh),完整讲解在 macOS 上编译安装 radare2、处理 arm64e 指针认证、创建代码签名证书、签署二进制及其动态库、打包 .pkg 与卸载的每一步。读完本文,你将能够在不使用 root 权限的前提下,让 radare2 的调试器正常附加并调试目标应用,并掌握手动签名与自动签名的全部路径。
1. 为什么 macOS 上的 radare2 需要"额外步骤"
radare2 是一套 UNIX 风格的逆向工程框架与命令行工具集。在 macOS 上,从 Mac OS X 10.6 开始,任何需要调试权限的二进制都必须经过代码签名,并携带描述其权限的 plist 文件。这意味着:如果你希望 radare2 能在非 root 用户身份下调试其他应用,就必须完成签名与授权配置;否则只能以 root 运行,或者干脆无法附加调试。
原文档 doc/macos.md 明确指出,这套额外步骤同样适用于 iOS 用户(详见 doc/ios.md),其核心诉求可以概括为三点:
- 生成并信任一个代码签名证书(默认名为
org.radare.radare2); - 用该证书签署 radare2 主程序与所有动态库(libr*);
- 配置系统权限(Developer Tools 组、必要时关闭 SIP),使非特权用户能够调试。
从源码层面看,这些步骤并非散落的手工操作,而是被固化进了构建体系:sys/build.sh在检测到 Darwin 平台时会自动调用签名目标,sys/build.sh 中可见其逻辑:
${MAKE} macos-sign macos-sign-libs CERTID="${CERTID}" || ( echo "CERTID not defined. If you want the bins signed to debug without root" ... )其中CERTID默认即为org.radare.radare2(见 sys/build.sh),与 Makefile 中的定义保持一致。
2. 自动编译安装
radare2 在 macOS 上自动编译安装的入口是:
$ sys/install.shsys/install.sh 会依次完成以下工作:
- 解析参数(支持
--install使用cp而非符号链接、--prefix=指定安装前缀、--without-pull跳过远端更新等); - 自动探测 GNU Make(macOS 上优先使用
gmake); - 在 Darwin 平台检测系统 capstone 版本,决定是否使用
--with-syscapstone等配置参数; - 调用 sys/build.sh 完成 configure 与编译;
- 通过
sudo make symstall(默认安装目标,可被--install覆盖为install)安装到系统。
需要说明的是,该脚本在 macOS 上默认以符号链接(symstall)方式安装,便于开发迭代;若希望复制文件安装,请追加--install。此外,仓库在doc/下还提供 doc/macos.md 之外的交叉编译参考(如 doc/cross-compile.md),macOS SDK 相关的构建细节可参见 mk/darwin.mk,其中会根据xcodebuild -version检测 Xcode 主版本号,并在 Xcode > 10 时通过-platform_version macos显式指定部署目标与 SDK 版本。
3. 常见问题与前置条件
3.1 arm64e 调试目标:指针认证(PAC)与特殊构建
当 radare2 运行在arm64e处理器(Apple A12 及之后的 A 系列、M1 及之后的 M 系列芯片)上时,系统要求调试器必须针对该特定架构构建,因为调试器需要与内核的**指针认证(pointer authentication)**机制协同工作。要完成这一步,需要同时满足三个条件:
- 禁用 SIP:进入恢复模式(开机按住 CMD+R),打开"实用工具"菜单中的终端,执行
csrutil disable; - 为 radare2 设置特定 CFLAGS,强制按 arm64e 架构编译;
- 为内核设置自定义启动参数。
启动参数与编译命令可参考原文档给出的脚本片段:
# 为内核设置 arm64e 预览 ABI 启动参数并重启 sudo nvram boot-args=-arm64e_preview_abi sudo reboot# 以 arm64e 架构编译并安装 radare2 export CFLAGS="-arch arm64e" sys/install.sh这里的关键在于:普通 arm64 构建无法与 arm64e 的指针认证栈正确交互,只有按-arch arm64e构建的二进制才能被内核认可为合法的调试器。注意:禁用 SIP 会显著降低系统安全性,仅应在受控的开发/调试环境中执行。
3.2 调试授权的系统级要求
如果你希望通过 ssh 使用 radare2 调试器,或者 SDK(签名环境)没有正确配置,需要先开启 Developer Tools 的安全服务:
$ sudo DevToolsSecurity -enable此外,macOS 默认不允许调试位于用户主目录之外的二进制。如果确实需要调试/System、/usr/bin等系统路径下的程序,就必须禁用 SIP:
- 重启 Mac,按住CMD+R进入恢复模式;
- 打开"实用工具"菜单里的终端,输入:
$ csrutil disable这一限制源自 macOS 的 TCC(隐私保护)与 SIP 机制:主目录之外的可执行文件默认不受用户信任,调试器无法对其下断点或读取内存。
4. 代码签名:让调试器无需 root 运行
4.1 自动签名:install.sh 做了什么
doc/macos.md 说明,前文提到的sys/install.sh会在系统钥匙串中安装一个新的代码签名证书,并用它签署 radare2。进一步从构建脚本看,sys/build.sh 在 Darwin 上会执行:
${MAKE} macos-sign macos-sign-libs CERTID="${CERTID}"即同时签署主程序和所有动态库(详见下文 4.4)。因此,如果钥匙串中已存在有效证书,走sys/install.sh通常就能一次性完成"编译 + 签名 + 安装"。
4.2 手动创建代码签名证书
如果你希望完全手动控制,可以按以下步骤在 Keychain Access 中创建证书(原文档整理,基于 LLDB 的 code-signing 指南):
- 启动
/Applications/Utilities/Keychain Access.app; - 在窗口左上角的 "Keychains" 列表中选中"login"钥匙串;
- 依次选择菜单:Keychain Access → Certificate Assistant → Create a Certificate...;
- 填写以下设置:
- Name=
org.radare.radare2 - Identity Type=
Self Signed Root - Certificate Type=
Code Signing
- Name=
- 依次点击Create → Continue → Done;
- 点击 "My Certificates",双击新建的
org.radare.radare2证书; - 展开 "Trust" 折叠区,将 "Code Signing" 信任下拉菜单设为"Always Trust",并按提示输入用户名/密码授权;
- 将名为
org.radare.radare2的代码签名证书(注意不是同名公钥/私钥)从 "login" 钥匙串拖入左侧 "System" 钥匙串,移动过程中多次授权,并选择 "Always trusted"; - 在 Keychain Access 界面中,将 "System" 钥匙串里的
org.radare.radare2拖到桌面,得到~/Desktop/org.radare.radare2.cer; - 切换到终端,执行:
$ sudo security add-trust -d -r trustRoot -p basic -p codeSign -k /Library/Keychains/System.keychain ~/Desktop/org.radare.radare2.cer $ rm -f ~/Desktop/org.radare.radare2.cer- 退出 Keychain Access,重启 Mac;
- 运行
sys/install.sh(或者按下文 4.4 手动签名)。
证书名称并非写死:Makefile 中通过CERTID变量指定证书名,默认值为org.radare.radare2(见 binr/radare2/Makefile)。如果你已有其他合法证书,可以通过环境变量覆盖:
$ export CERTID="你的证书名" $ sys/install.sh4.3 签名机制背后的 plist 与 entitlements
签名并不只是"盖章"。radare2 在签名时会携带两类属性列表文件:
- Info.plist(binr/radare2/Info.plist):描述程序元信息,包括
CFBundleIdentifier(org.radare.radare2)、CFBundleName、CFBundleVersion,以及SecTaskAccess(allowed/safe)权限声明; - entitlements 文件(binr/radare2/radare2_macos.xml):声明调试器所需的授权,其内容为:
<key>com.apple.security.cs.debugger</key> <true/> <key>com.apple.security.cs.allow-dyld-environment-variables</key> <true/>其中com.apple.security.cs.debugger是 macOS 上调试器权限的关键 entitlement:只有携带该授权、且签名受系统信任的二进制,才能以非 root 身份附加并调试其他进程。allow-dyld-environment-variables则允许通过DYLD_*环境变量注入动态库加载行为(调试注入场景需要)。
签名时 Makefile 通过-sectcreate __TEXT __info_plist Info.plist把 Info.plist 嵌入 Mach-O 的__TEXT段,再以codesign -dvvv --deep -f -s ${CERTID} -i ${BUNDLE} --entitlements radare2_macos.xml radare2完成签署(见 binr/radare2/Makefile)。
4.4 手动签署 radare2 与动态库
首先签署 radare2 主程序:
$ make -C binr/radare2 macossign但这还不够——radare2 的代码被拆分为多个库(libr*,例如r_core、r_bin、r_debug、r_anal等,完整依赖列表见 binr/radare2/Makefile),调试器在运行时会动态加载这些 dylib,因此每一个依赖库都必须单独签名:
$ make -C binr/radare2 macos-sign-libs该目标会遍历SIGN_LIBS(由各库的libr_*.dylib拼接而成,见 binr/radare2/Makefile),逐个执行codesign -f -s ${CERTID} $LIB。
另一条更省事的路径是构建静态版本后只签一个文件:
$ sys/static.sh $ make -C binr/radare2 macossignsys/static.sh在 Darwin 分支不会添加-static链接标志(sys/static.sh),但会以--with-libr、--without-gpl等配置生成聚合库并安装到r2-static/目录,最终所有功能被打进单一的可执行文件,从而将签名对象从"1 个主程序 + N 个 dylib"简化为"1 个二进制"。
4.5 验证签名与授权非特权用户
使用系统自带工具验证签名是否成功、是否被系统信任:
$ codesign -dv binr/radare2/radare2-dv会输出签名的详细信息(签名者、标识、授权等)。随后,把当前非特权用户加入 Developer Tools 组,避免 Xcode 相关的授权弹窗:
$ sudo dscl . append /Groups/_developer GroupMembership <username>完成以上全部步骤后,即可无需 root直接调试:
$ r2 -d mybin原文档特别提醒:若你已有可用的签名证书,可通过设置环境变量
CERTID指定其名称,从而跳过重新创建证书的步骤。
5. 打包与分发:生成 macOS .pkg
radare2 的 macOS 分发包(.pkg)由脚本生成:
$ sys/osx-pkg.sh该脚本本身只是一个转发器,真正的工作在 dist/macos/build.sh 中完成。从仓库结构看,dist/macos/下包含:
- pkg/radare2.unpkg/PackageInfo:包元数据;
- pkg/Resources/:安装欢迎文案(welcome.rtf)、许可证(COPYING、COPYING.LESSER)与图标;
- pkg/Distribution:安装器分发描述。
生成的 .pkg 可通过系统installer命令安装(见 dist/macos/Makefile):
$ installer -pkg *.pkg -target /如果你使用 Homebrew,仓库也提供了对应的打包配方 dist/brew/radare2.rb,可作为以 brew 方式构建与分发的参考。
6. 卸载 .pkg 安装的 radare2
卸载从 r2 官网下载、或由sys/osx-pkg.sh生成的 .pkg 时,核心思路是:用pkgutil查询该包实际写入了哪些文件,再逐一删除。原文档给出的命令如下(以 root 执行):
$ pkgutil --only-files --files org.radare.radare2 | sed 's/^/\//' | tr '\n' '\0' | xargs -o -n 1 -0 rm -i命令分解说明:
pkgutil --only-files --files org.radare.radare2:列出该包注册的所有文件(相对路径);sed 's/^/\//':为每个相对路径补上根前缀/,还原为绝对路径;tr '\n' '\0':把换行分隔转成 NUL 分隔,避免路径含空格时被拆分;xargs -o -n 1 -0 rm -i:逐个删除,-i会逐条询问确认。
仓库还提供了一个更彻底的卸载脚本 dist/macos/osx-pkg-uninstall.sh:它会先删除包记录的全部文件,再删除包记录的全部空目录,最后执行pkgutil --forget org.radare.radare2注销包注册信息,可视为上述命令的安全增强版。
7. 常见问题速查
| 现象 | 原因 | 解决方案 |
|---|---|---|
r2 -d附加失败或无权限 | 二进制未签名或证书不受信任 | 完成第 4 节签名流程,并确认证书信任设为 Always Trust |
| 提示缺少调试权限 | Developer Tools 未开启 | sudo DevToolsSecurity -enable |
| 无法调试主目录之外的二进制 | SIP 限制 | 恢复模式下csrutil disable后重启 |
| arm64e 机器上调试异常 | 未按 arm64e 构建,PAC 无法协作 | 设置CFLAGS="-arch arm64e"并写入-arm64e_preview_abi启动参数 |
| 动态库未签名 | 只签了主程序 | 执行make -C binr/radare2 macos-sign-libs,或改用静态构建 |
| 已有自己的证书 | 默认证书名不匹配 | export CERTID=<证书名>后重新签名/安装 |
8. 延伸阅读
- iOS 平台存在相似的签名需求,请阅读 doc/ios.md;
- macOS 专用构建参数(Xcode 版本检测、SDK 版本指定)见 mk/darwin.mk;
- 静态构建的完整流程与验证逻辑见 sys/static.sh;
- 签名目标的实现细节(
macossign、macos-sign-libs、iOS 签名目标)见 binr/radare2/Makefile; - 调试器架构与使用方式可参考 doc/debug.md、doc/debug-internals.md。
至此,从一键安装到手动签名、从 arm64e 特殊构建到 .pkg 打包卸载,macOS 上的 radare2 调试链路已经完整打通。你现在应该能够独立完成"签名 → 授权 → 免 root 调试"的整套配置,并理解每一步背后的系统机制与源码依据。
【免费下载链接】radare2UNIX-like reverse engineering framework and command-line toolset项目地址: https://gitcode.com/gh_mirrors/ra/radare2
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考