reverse-skills-max: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok609hecl1pq6qi
2026-10-20 02:17:15 +03:00
commit da24c2bd20
2227 changed files with 443931 additions and 0 deletions

View File

@@ -0,0 +1,130 @@
---
name: re-lldb
description: >
lldb 调试(macOS/iOS):attach、expr、image。
触发词:lldb、macOS调试、iOS调试
capabilities: [debugging]
---
# lldb 动态调试(macOS/iOS)
## 何时使用 / 何时不用
- 用:macOS/iOS 目标动态调试(attach/启动/断点/表达式求值/符号查找)
- 用:Linux 上调试带 DWARF 的调试版程序(lldb 与 clang 工具链同源,DWARF 处理成熟)
- 不用:Linux 目标([[re-gdb]])、Windows 目标([[re-x64dbg]])
- 不用:iOS 越狱/证书环境问题(属 [[re-mobile]] 域);只读内存([[re-memdump]] 默认转储优先)
- 不用:脚本化大批量内存转储/取证([[re-memdump]] / [[re-mem-forensics]] 更对口)
## 工具准备
参考 [[re-analyze/platform-tips]] macOS 分支——SIP 与 TCC 限制 attach,需 Developer Tools 授权。
### lldb
- macOS: 自带(Xcode Command Line Tools: `xcode-select --install`)
- Linux: `apt install lldb` / `dnf install lldb` / `pacman -S lldb`
- macOS 更全: `brew install llvm`(含新版 lldb)
- 验证: `lldb --version`
- 版本差异: Xcode 自带 lldb、llvm.org 的 lldb、Swift 工具链 lldb 功能近似但版本号不同(`lldb --version` 确认);脚本依赖 `lldb.SBDebugger` API 时跨版本兼容性需验证(见 [[gotchas]])
### SIP 关闭或授权(attach 前置)
- 系统设置 > 隐私与安全性 > 开发者工具 > 授权使用 lldb 的终端(TCC 授权)
- 旧系统: `sudo DevToolsSecurity -enable`
- 说明: 一般不要关 SIP(可只对调试需求临时处理);iOS 内核级调试需 KDK/开发内核,属 [[re-mobile]] 域
## 操作步骤
1. **Developer Tools 权限确认**:
```sh
lldb -p <测试进程pid> # 若报 "please check the developer mode" / 权限拒绝 → 去系统设置授权终端
```
授权后重启终端;仍失败再检查 SIP 状态: `csrutil status`。
注意: TCC 授权弹窗需在系统设置手动确认,无法命令行绕过。
2. **attach/启动**:
```
(lldb) process attach --pid <pid> # 附加
(lldb) process attach --name Safari # 按名字附加(需唯一)
(lldb) target create ./sample # 或直接启动
(lldb) run --args arg1
(lldb) continue / c
```
iOS 设备: `platform select remote-ios` + `process connect connect://<device>`(需配合调试服务,越狱/证书要求见 [[re-mobile]])
- attach 时机注意: 目标已运行过初始化逻辑,入口前行为看不到——需要从入口看就 `target create` + `run` 启动模式
- 启动停在入口: `process launch --stop-at-entry`(等价 `-s`)
3. **`image lookup` 符号**:
```
(lldb) image lookup -n main # 按名字查符号
(lldb) image lookup -a $pc # 按地址查当前所在函数/源行
(lldb) image list # 已加载镜像(dylib 基址表)
(lldb) image lookup -rn dispatch # 正则匹配符号
```
stripped 二进制用 `image lookup -a` 反查地址归属模块,配合 `image dump symtab`
- 模块基址: `image list -o` 加偏移列——ASLR 下每次运行基址不同,脚本里先拿基址再算绝对地址(见 [[gotchas]])
4. **内存表达式 `expr`**:
```
(lldb) expr $rax
(lldb) expr $rax = 0 # 写寄存器
(lldb) expr (char*)0x100000000 # 类型化读地址
(lldb) expr -O -- @"hello" # Objective-C 求值(objc 运行时)
(lldb) memory read -c 20 -s 4 -f x $rsp # 读内存(缺 -f x 会报格式冲突错误)
(lldb) memory write -s 1 0x100000000 0x90 # 写字节(绕过校验)
```
- 表达式求值有副作用(会执行代码)——别在敏感路径上乱求值,见 [[gotchas]]
5. **断点与脚本**:
```
(lldb) breakpoint set -n main
(lldb) breakpoint set -a 0x100004000 -c '*(int*)($rsp) == 0x1234' # 条件断点
(lldb) breakpoint command add 1
> frame variable
> expr $rax
> continue
> DONE
```
Python 自动化: lldb 内置 Python——`script import lldb`,或用 `lldb -s script.lldb` 批处理。
- 符号断点: `breakpoint set -n objc_msgSend`(按符号名,模块加载后自动生效);正则: `-r '^check_'`
- 断点管理: `breakpoint list` / `breakpoint delete` / `breakpoint disable 1`
6. **单步/栈/线程**:
```
(lldb) thread step-over / step-into / step-out # 步过/步入/出函数(别名 next/step/finish)
(lldb) thread backtrace # 当前线程栈(别名 bt)
(lldb) thread list # 全部线程
(lldb) frame select 1 # 切栈帧
(lldb) frame variable # 当前帧局部变量
(lldb) register read # 全部寄存器
```
- 单步跳过 call 后的 `step-out` 配合返回寄存器看结果,是「验证函数返回」最快路径
7. **内存搜索与区域**:
```
(lldb) memory find 0x100000000 0x101000000 -e 0xdeadbeef # 区间内搜值/字节串
(lldb) memory find -s "password" 0x100000000 0x101000000 # 搜字符串
(lldb) memory region 0x100004000 # 该地址所属区域权限/边界
```
- 找密钥/常量: 先 `memory find` 定位,再断写入点;区域权限(RWX)异常段先看(壳/解密段)
8. **证据核对(收尾)**:断点命中记录、`frame variable`/`expr` 输出、`memory read` 转储(`memory read --force -o 文件` 导出)对照 [[re-triage]] 初勘值入档,结论写 [[re-analyze/analysis-contract]]
## 跨域联合
- [[re-binary-core]]:工作流第 6 步(macOS/iOS 调试器)
- [[re-mobile]]:iOS App/越狱动态调试的底层工具
- [[re-format-macho]]:先解析结构再调试(入口/LC_MAIN 与签名状态)
- attach 失败时按 [[re-analyze/platform-tips]] 转 [[re-memdump]]
## 常见坑与陷阱
- **SIP/TCC 拦截 attach**:非授权终端 attach 被拒(`permission denied` 或静默失败)——去系统设置开发者工具授权;关闭 SIP 只在极端情况
- **权限弹窗需手动确认**:TCC 每次对新的调试目标弹窗,脚本化 attach 会被卡住——预先授权目标程序
- **内核调试需额外配置**:macOS 内核调试要 KDK 匹配版本 + 开发内核启动,普通逆向用不上,别在用户态调试上浪费时间
- **签名状态**: 修改过的 Mach-O 未重签无法运行(见 [[re-format-macho]])——先 `codesign -f -s -` 重签再调试
- **task_for_pid entitlement/SIP/Hardened Runtime 三层限制**:现象——Developer Tools 已授权仍 attach 失败或目标启动即崩溃;原因——除 TCC 外还有三层:调试器需 task_for_pid entitlement,目标启用 Hardened Runtime 时调试 API 受限,SIP 限制系统进程 attach;对策——逐层排查(`csrutil status`、检查目标签名与 entitlement),测试目标可先去签名/重签([[re-format-macho]])再调试,参考 [[re-analyze/platform-tips]] macOS 分支
- **ASLR 基址漂移**:每次启动 dylib 基址不同——脚本里硬编码地址会失效;用 `image list -o` 拿基址换算,断点尽量下符号名(`-n`/`-s`)
- **表达式求值有副作用**:`expr` 会真实执行代码(调用函数/改内存)——在 hook 点求值可能改变目标行为,验证场景用 `frame variable` 只读优先
- 版本差异、调试服务器与边界见 [[gotchas]]

View File

@@ -0,0 +1,110 @@
# lldb 命令速查与操作序列
lldb 是命令行调试器(macOS 自带 / Linux 发行版仓库 / llvm.org 独立构建)。命令分族记忆:`target`(会话)→ `process`(运行)→ `breakpoint`(断点)→ `thread`(线程/步进)→ `frame`(栈帧)→ `memory`/`register`(内存/寄存器)→ `image`(符号/镜像)。`image` 是 `target modules` 的别名。官方参考: lldb.llvm.org(GDB to LLDB 映射页 + 命令参考)。
## 命令族速查
### 会话与运行
- `target create <文件>` 加载目标;`target list` / `target delete`
- `process launch [--stop-at-entry] [-- args]` 启动(停入口);`run [args]` 等价简写
- `process attach --pid <pid>` / `--name <名>` 附加;`process detach` 脱离;`process kill` 终止
- `continue` / `c` 继续;`process interrupt` 中断(Ctrl+C);`process status` 当前状态
- `lldb -p <pid>` 命令行直接附加;`lldb -s script.lldb <文件>` 批处理执行脚本文件
### 断点
- `breakpoint set -n <符号>` 符号断点(模块加载后自动生效);`-a <地址>` 地址断点;`-r <正则>` 正则断点
- `breakpoint set -n func -s <模块>` 限定模块;`-c <条件>` 条件断点
- `breakpoint list` / `delete` / `disable <id>` / `enable <id>` / `clear`
- `breakpoint command add <id>` 批量执行命令(`> ... > DONE` 结束);`breakpoint command delete <id>` 移除
### 步进与栈
- `thread step-over` / `step-into` / `step-out`(别名 `next` / `step` / `finish`)
- `thread step-inst` 单指令步进;`thread until <地址>` 运行到地址(循环内用)
- `thread backtrace`(`bt`);`thread list`;`thread select <n>` 切线程
- `frame select <n>` 切栈帧;`frame variable` 局部变量;`frame info` 当前帧信息
### 寄存器与表达式
- `register read`(全部)/ `register read rax`;`register write rax 0` 写寄存器
- `expr <表达式>` 求值;`expr $rax = 0` 写;`expr (char*)0x...` 类型化读地址
- `expr -O -- <objc表达式>` Objective-C 求值(需 objc 运行时在目标进程)
- `expr -l objc++ -- ...` 切语言(C++ 目标用 c++)
### 内存
- `memory read [-c 数量] [-s 宽度] [-f 格式] <地址>`(格式冲突报错时显式给 `-f x`)
- `memory write -s <宽度> <地址> <值>` 写字节
- `memory find <起> <止> [-e 表达式|-s 字符串]` 区间搜索字节/字符串
- `memory region <地址>` 区域权限/边界(看 RWX 异常段)
- `memory read --force -o <文件> <地址> <地址+长度>` 导出到文件(大段转储)
### 符号与镜像
- `image list` 已加载镜像基址;`image list -o` 加偏移(ASLR 换算)
- `image lookup -n <名>` / `-a <地址>` / `-rn <正则>` 查符号归属
- `image dump symtab [<模块>]` 符号表全量;`target symbols add <文件>` 手动加载符号文件
- `image lookup -t <类型名>` 查类型定义(调试版目标)
### Python 脚本
- `script` 进 Python 交互;`script import lldb` 用 `lldb.debugger` 句柄
- `command script import <模块>` 注册 Python 命令;`lldb -s script.lldb` 批处理
- 常用: `lldb.debugger.GetSelectedTarget().FindFunctions("main")` 系列
## 常用操作序列(组合套路)
### 1. 附加 → 断点 → 验证调用参数
```
lldb -p <pid>
(lldb) breakpoint set -n objc_msgSend -s <目标模块>
(lldb) breakpoint command add 1
> register read rdi rsi # x64 ABI 前两个参数
> thread backtrace
> continue
> DONE
(lldb) continue
```
### 2. 定位校验/授权逻辑(符号 → 断点 → 改值绕过)
```
(lldb) target create ./sample
(lldb) run --args <参数>
(lldb) breakpoint set -n strcmp # 或 -n 目标校验函数
(lldb) continue → 命中后:
(lldb) register write rax 0 # 改返回值(相等)
(lldb) continue # 观察是否绕过
```
### 3. 内存搜索找密钥/常量
```
(lldb) memory find -s "flag{" 0x100000000 0x101000000
(lldb) memory find 0x100000000 0x101000000 -e 0xdeadbeef
# 命中地址 → 断写入点或 memory region 看归属模块 → 上溯调用者
```
### 4. 解密循环自动跑完(条件断点 + until)
```
(lldb) breakpoint set -a <循环尾地址> -c '*(int*)($rdi) == 0xABCD'
(lldb) continue # 条件满足才停
(lldb) memory read -c 16 -s 1 -f x <输出地址>
```
## 实现教训(内化)
- 断点尽量符号名(`-n`),别用硬编码地址——ASLR 下每次运行基址漂移
- `memory read` 不指定格式时报格式冲突——`-f x`(十六进制)是调试常规选项
- `expr` 有副作用(执行代码):验证场景先用 `frame variable` 只读,确认需要再求值
- 条件断点条件写错不会报错,只是永远不命中——先无条件断确认能停,再加条件
- 批处理 `lldb -s` 脚本里每条命令一行;出错不中断,注意末尾输出
## 使用注意
- 全部在沙箱内执行([[re-analyze/platform-tips]] 最高原则);attach 需 Developer Tools 授权
- 结论写 [[re-analyze/analysis-contract]];与 [[re-triage]] 初勘值对照;iOS 目标权限/证书问题走 [[re-mobile]]

View File

@@ -0,0 +1,40 @@
# lldb 工具特有坑与边界
## macOS 权限栈(attach 前置,逐层排查)
- **TCC(隐私与安全性 > 开发者工具)**:非授权终端 attach 报 `permission denied` 或静默失败——系统设置手动授权后重启终端;弹窗无法命令行绕过
- **DevToolsSecurity**:旧系统(10.14 前)还需 `sudo DevToolsSecurity -enable`;新系统此命令已非必需
- **task_for_pid entitlement**:调试器进程需要 task_for_pid 权限——普通终端下 lldb 依赖 Developer Tools 授权链,越狱/企业环境另有路径(属 [[re-mobile]] 域)
- **Hardened Runtime**:目标启用 Hardened Runtime(macOS 10.14.4+)时调试 API 受限(如 `get-task-allow` 缺失)——目标先重签(`codesign -f -s -` 或带 `com.apple.security.get-task-allow` entitlement,见 [[re-format-macho]])
- **SIP**:`csrutil status` 确认;SIP 关闭只影响系统保护进程 attach,普通目标不用动
- 排查顺序: TCC 授权 → DevToolsSecurity → csrutil → 目标签名/entitlement——逐层排除,别一上来关 SIP
## 版本差异
- **Xcode lldb vs llvm.org lldb**:Xcode 自带版本与上游 llvm 版本不同步(版本号差异大);`brew install llvm` 的 lldb 新于系统版,功能/API 更新——脚本依赖以实际版本为准
- **Swift 工具链 lldb**:Swift 表达式求值支持最好;无 Swift 需求的逆向场景用系统/llvm 版即可
- **Python API 兼容**:`lldb.SBDebugger` API 跨版本大体稳定但偶有增减——`lldb -s` 批处理脚本比 Python 脚本跨版本更稳
- **Linux 发行版 lldb 版本滞后**:apt/dnf/pacman 的 lldb 版本落后上游——需要新特性时用 llvm.org 官方二进制或 brew
## 调试行为坑
- **表达式求值有副作用**:`expr` 会真实执行代码(调用函数、写内存、触发消息发送)——在 hook 点乱求值可能改变目标行为甚至崩溃;只读验证用 `frame variable`
- **条件断点永远不命中**:条件里引用了未加载符号/类型时会静默失败——先无条件断确认能停,再逐级加条件
- **ASLR 基址漂移**:macOS 默认开启随机基址——每次 `run` 后 `image list` 基址都变;脚本硬编码地址失效,用符号断点或 `image list -o` 换算
- **stripped 目标没有 `-n` 断点**:`breakpoint set -n` 找不到符号——用 `image lookup -a` 反查地址归属,或对 `-rn` 正则碰运气;地址断点 + `image list -o` 换算
- **`memory read` 格式冲突**:不同宽度/格式混用时报 `invalid format`——显式 `-s 4 -f x` 一组组给
- **attach 后目标冻结**:附加后目标默认暂停(SIGSTOP)——`continue` 才恢复;忘记 continue 会以为目标卡死
- **wow64 类场景(32 位目标)**:64 位 lldb 调试 32 位 macOS 目标正常(系统自带 32 位支持),但 `expr` 的指针宽度按 64 位算——按目标位数写表达式
## 反调试与边界
- **ptrace 检测**:目标可调 `ptrace(PT_DENY_ATTACH)` 拒绝附加(启动即拒绝)——先静态定位([[re-format-macho]] / [[re-ida]] 找 ptrace 调用),patch 掉后再调试
- **调试器特征检测**:`sysctl`/`task_info` 枚举调试标志——检测点先静态处理(见 [[re-anti-analysis]])
- **内核调试门槛高**:macOS 内核调试需 KDK 版本匹配 + 开发内核启动参数——普通逆向不划算,别在用户态调试上耗时间
- **iOS 远程调试**:`platform select remote-ios` + debugserver 需要签名/越狱环境——环境问题归 [[re-mobile]],本技能只管命令层面
## 使用注意
- 全部在沙箱内执行([[re-analyze/platform-tips]] 最高原则);attach 需 Developer Tools 授权
- 目标为恶意样本时先静态初勘([[re-triage]] 哈希/[[re-format-macho]] 结构)再动态
- 结论写 [[re-analyze/analysis-contract]];符号/地址证据与 [[re-triage]] 初勘值对照