Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,4 @@ Shellsmith 是 Android 与 iOS 双平台应用加固工具。Android 流程加
- [BYOS HTTPS 密钥服务](design/byos-key-server.md):用户自建服务所需信息、接口与联调要求。
- [BYOS 密钥服务端参考实现](design/byos-key-server-reference.md):Go/PostgreSQL 参考实现、KMS/HSM 后端、部署和运维手册。
- [证据目录](evidence/README.md):威胁模型、攻击树、实验矩阵、Chain A/B 报告和发布前证据门禁。
- [1.10.0-rc 验收与稳定版门槛](process/1.10.0-rc-acceptance.md):真机矩阵、BYOS、AAB 本地链和稳定版条件。
16 changes: 16 additions & 0 deletions docs/evidence/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,22 @@ python3 scripts/evidence/recovery_benchmark.py \
--command "python3 tests/scripts/check-pvm2-art.py --min-api 26 --output target/evidence/pvm2-art" \
--output docs/evidence/artifacts/pvm2-art-benchmark.json

# 单台 Android 设备安装/启动/PSS/日志/私有目录采样
python3 scripts/evidence/device_acceptance.py \
--serial <serial> --apk <signed.apk> \
--package <package> --activity .MainActivity \
--output docs/evidence/artifacts/device-<serial>.json

# BYOS 协议负面探测(需要测试 endpoint)
python3 scripts/evidence/byos_probe.py \
--base-url https://keys.example.com \
--output docs/evidence/artifacts/byos-probe.json

# AAB 本地 bundletool 验证(不代表 Play 分发)
bash scripts/evidence/aab_local_verify.sh \
--bundle protected.aab --device <serial> \
--ks upload.p12 --ks-key-alias upload --ks-pass-env UPLOAD_KS_PASS

# 检查证据结构是否满足发布候选基线
bash scripts/check-evidence-ready.sh --baseline
```
Expand Down
120 changes: 120 additions & 0 deletions docs/process/1.10.0-rc-acceptance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# 1.10.0-rc 验收与稳定版门槛

状态:`rc`。当前候选版本 `1.10.0-rc.1`,目标是决定进入 `1.10.0` 稳定版、发 `1.10.0-rc.2`,还是保持 rc。

## 1. 验收范围

本清单只覆盖 1.10.0 已有能力,不新增功能:

- DEXB v6/v7、PVM2、路由 assets、业务 SO、PAS2
- RASP、Root/调试策略、FLAG_SECURE、ADB 策略
- BYOS `device_approval`(Play 模式无账号时保持 `unverified`)
- AAB 本地 bundletool 链(不代表 Play 分发)
- iOS freeRASP、`block_on_critical`、App Attest 客户端(如有真机)
- 三平台安装包、更新清单、签名状态

## 2. 设备矩阵

| 平台 | 最低要求 |
|---|---|
| Android | API 21、26、29、31、35 各至少一台;arm64 + armeabi-v7a |
| Android 页面 | 4 KB 页至少一台;16 KB 页设备有则加测 |
| 厂商 | 至少一个小米/华为/OPPO/vivo 等主流 ROM |
| 工控 | Android 4.4/armeabi-v7a 如有发布需求 |
| iOS | iOS 13+ 真机;freeRASP 与 App Attest 分开记录 |
| 桌面 | Windows/macOS/Linux 安装、启动、更新一次 |

## 3. 功能验收

每个设备至少记录:

- 安装、首次启动、冷启动、热启动
- 登录、核心业务、关键页面
- PVM2 必保方法
- ARouter/TheRouter 页面跳转(启用路由 assets 时)
- 业务 SO 加载
- 清数据、覆盖升级、卸载重装
- 截图/录屏/ADB 策略
- 启动 TotalTime、PSS、崩溃/ANR

失败样本必须保留,不得只记录成功。

## 4. BYOS

### 4.1 `device_approval`

必须验证:

- 产物注册
- 未知设备待批准
- 管理员批准
- 首次取钥与缓存启动取钥
- 错包名/错证书/错授权方式
- 重放/并发重放
- 撤销设备/产物后拒绝
- 主密钥轮换、数据库备份恢复
- 日志不含 IKM、Authorization、完整证明

### 4.2 `play_integrity`

无 Play 账号时:

- 只运行 mock/单元测试
- 状态标记 `unverified`
- 不宣称 Play 分发已验证

## 5. AAB 本地链

不需要 Play 账号:

```bash
bundletool validate --bundle=protected.aab
bundletool build-apks --bundle=protected.aab --output=protected.apks \
--ks=... --ks-key-alias=... --ks-pass=env:...
bundletool install-apks --apks=protected.apks --device-id=<serial>
```

验证:

- base + install-time dynamic feature
- 条件/按需模块(如有)
- Asset Pack(如有)
- split 安装、清数据、覆盖升级

结论必须写“本地 bundletool 通过,Google Play 分发未验证”。

## 6. 发布链

- Release 工作流手动触发
- `CI 通过` 为 main 必需检查
- macOS Developer ID/公证状态
- Windows Authenticode 状态
- 更新签名私钥备份
- SHA-256、`latest.json`、`.sig` 校验

## 7. 证据

- `bash scripts/check-evidence-ready.sh --baseline`
- `docs/evidence/chain-a-report.md`、`chain-b-report.md` 更新
- 每个实验绑定输入哈希、脚本版本、设备/环境
- 未验证项保留

## 8. 稳定版门槛

满足以下条件才发 `1.10.0`:

- rc 阶段无 P0/P1 未解决
- 设备矩阵通过
- 路由 assets 真机通过
- BYOS `device_approval` 通过
- AAB 本地链通过
- 三平台安装包启动通过
- 安装包签名状态明确
- 证据门禁通过
- 未验证项在 Release Notes 中保留

不满足时:

- 有 P0/P1:发 `1.10.0-rc.2`
- 只有 P2/P3/文档:可评估直接发 `1.10.0`
- 外部能力缺失:稳定版可作为 APK/桌面版发布,但 Play/App Store 能力保持 `unverified`
74 changes: 74 additions & 0 deletions docs/process/2026-10-23-xop-diff-audit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# XopProtector 分支差异审计(2026-10-23)

**状态:** 仅审计,不合并、不改代码、不删除上游目录。本文记录本地分支与 `origin/main` 的真实基线、冲突面和逐项裁决,供后续决定「合入、上游 PR 或归档」。

> 2026-10-28 更新:已按本文拆出 `fix/cross-platform-sdk-path`、`feat/protect-so-include-only` 和 `fix/dex-sha1-bitlen`;三个分支目前仅在本地,尚未推送或开 PR。

## 基线

| 项目 | 值 |
|---|---|
| 本地 `HEAD` | `e408b87`(2026-09-19,`增强PVM2 / 支付 True-VMP,适配Android16,增强SO 保护`) |
| `origin/main` | `4a41d0b`(2026-10-20,合并 shadowhook 2.0.1) |
| 本地与远端关系 | 本地 `main` 落后 `origin/main` 5 个提交 |
| `e408b87..origin/main` | 36 个文件,`+5657 / -692` |
| 本地未提交工作区 | 22 个文件,`+1614 / -237` |

## 远端 5 个提交的主题

```text
4a41d0b Merge pull request #21 from ouchangxin/feature/upgrade_shadowhook_2.0.1
08f940f 升级shadowhook框架版本到2.0.1
3cefb55 SO 加载策略调整(L2e 为主),Dobby ARM64 重定位增强,16KB 页对齐
5990c31 更新版本为0.7.2
7b18e91 修改SO冷启动策略,避免 attach 全表 RC4 和体积误判 L2e
```

主要改动集中在 SO 保护与加载链路:`business_so.cpp`、`BusinessSoProtector.java`、Dobby ARM64、`elf_util`、`NativeLibDirRedirect`、`p4-so-ab-matrix.ps1`。这不是一条 PVM2 格式升级线。

## 本地未提交 diff 的冲突面

本地未提交的 22 个文件里,与 `origin/main` 已改动文件重叠、不能直接 rebase 的至少有:

- `build.gradle.kts`
- `native/src/main/cpp/dex/dex_file.cpp`
- `native/src/main/cpp/vm/pvm2_format.cpp`
- `native/src/main/cpp/vm/pvm2_format.h`
- `packer/.../BusinessSoProtector.java`
- `packer/.../PackerMain.java`
- `packer/.../TrueVmpTrampoline.java`
- `packer/.../elf/ReadElf.java`

其余本地改动(`AssetsEncryptor`、`AutoVmpPolicy`、`Pvm2Compiler`、`Pvm2Morph`、`Pvm2Opcodes`、`ResPathObfuscator`、测试和 `settings.gradle.kts`)需要逐项对照,不能按「22 个文件整体 rebase」处理。

## 逐项裁决

| 项目 | 事实 | 裁决 |
|---|---|---|
| 本地 PVM2 v6 | 本地 `pvm2_format.h` 在 V5 后新增 V6;`origin/main` 只到 V5;`third_party/xopprotector` 已支持 V6–V9 | **先做语义对照**:把本地 v6 的寄存器置换、10 字节 handler、三变体 dispatch 与 third_party 的 v6–v9 逐项比较。若只是重复实现,丢弃并在 third_party 补齐仍缺的 dispatch 密钥流;不要先假定是独有能力 |
| `find_class_desc` contextClassLoader | `third_party` 已有 `forName` + `contextClassLoader`,并用 `string_from_utf8` 处理 MUTF-8;本地仍用 `NewStringUTF` | **丢弃本地这条**。third_party 已领先,不存在「third_party 未必有」的问题 |
| `dex_file.cpp` SHA-1 溢出 | `origin/main` 仍是 `size_t bit_len`;本地改为 `uint64_t`,修复 32 位 ABI 下 `len * 8` 溢出;`third_party/xopprotector` 未 vendoring `dex/`,该文件不参与 Shellsmith 主线编译 | **保留为独立上游 PR**,只回 Xop 独立壳线;不要合入 third_party(没有目标文件),也不要把它算作 Shellsmith 主线修复 |
| `build.gradle.kts` 的 `exportShellFiles` | `origin/main` 已对 `build.gradle.kts` 做了 143 行改动 | rebase 后对照远端实现;仅在本地版本确实更稳健且不冲突时保留,否则丢弃 |
| `TrueVmpTrampoline` / `ReadElf` / `PackerMain` / `BusinessSoProtector` | 本地与远端同时改动,语义需要逐段比对 | 按「SO 加载」「True-VMP」「DEX/ELF 读取」拆成独立改动,不整体合并 |
| PVM2 v6 与 third_party v9 的关系 | third_party 是 Shellsmith 的独立演进线,V9 已包含 V6–V8 能力 | 不能把 Xop 本地 v6 当作 third_party 的升级来源;只把 third_party 缺失的语义作为候选 |

## 不做什么

- 不直接 `git rebase` 22 个未提交文件;先 `git fetch`,以 `origin/main` 为基线重新评估。
- 不把 `origin/main` 的 SO 保护改动与本地 PVM2 v6 改动混成一个提交。
- 不把 `dex_file.cpp` 的 SHA-1 修复合入 `third_party/xopprotector`;该目录没有 `dex/`,Shellsmith 主线也不编译它。
- 不在 diff 审计完成前删除或归档 `XopProtector`;本地 HEAD 落后 5 个提交,当前比较基线不是最新上游。

## 下一步

1. `git fetch origin`,确认 `origin/main` 仍为 `4a41d0b` 或更新;以最新远端为基线重跑 diff。
2. 先处理 `dex_file.cpp` 的 SHA-1 修复:独立分支、独立 PR、仅回 Xop 上游。
3. 对本地 PVM2 v6 与 third_party v6–v9 做语义对照,输出「重复 / 缺失 / 冲突」三列清单。
4. 对 `build.gradle.kts`、`TrueVmpTrampoline`、`ReadElf`、`PackerMain`、`BusinessSoProtector` 逐文件裁决。
5. 全部裁决完成后,再决定 Xop 目录是归档、保留为支付 True-VMP 实验线,还是只保留上游 PR。

## 关联

- [第三方 PVM2 运行时](https://github.com/kairowan/Shellsmith/tree/main/third_party/xopprotector)
- [路线图](roadmap.md)
- [Android 代码保护升级方案](../design/android-code-protection-upgrade.md)
2 changes: 2 additions & 0 deletions docs/process/release-1.10.0-checklist.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# 1.10.0 发布检查清单

> RC 验收矩阵见 [1.10.0-rc 验收与稳定版门槛](1.10.0-rc-acceptance.md)。

> 本清单对应 `next` 集成分支。`main` 在全部条目完成前保持 1.9.0,不因普通 PR 合并触发 Release。

## 1. 分支与集成
Expand Down
66 changes: 66 additions & 0 deletions scripts/evidence/aab_local_verify.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
cd "$ROOT"

BUNDLE=""
OUTPUT_DIR="${AAB_EVIDENCE_DIR:-target/evidence/aab-local}"
BUNDLETOOL="${BUNDLETOOL:-bundletool}"
KS=""
ALIAS=""
KS_PASS_ENV=""
DEVICE=""

while [[ $# -gt 0 ]]; do
case "$1" in
--bundle) BUNDLE="$2"; shift 2 ;;
--output) OUTPUT_DIR="$2"; shift 2 ;;
--bundletool) BUNDLETOOL="$2"; shift 2 ;;
--ks) KS="$2"; shift 2 ;;
--ks-key-alias) ALIAS="$2"; shift 2 ;;
--ks-pass-env) KS_PASS_ENV="$2"; shift 2 ;;
--device) DEVICE="$2"; shift 2 ;;
*) echo "未知参数: $1" >&2; exit 2 ;;
esac
done

test -n "$BUNDLE" || { echo "需要 --bundle <protected.aab>" >&2; exit 2; }
test -f "$BUNDLE" || { echo "AAB 不存在: $BUNDLE" >&2; exit 2; }
mkdir -p "$OUTPUT_DIR"
LOG="$OUTPUT_DIR/commands.log"
: > "$LOG"

run() {
echo "+ $*" | tee -a "$LOG"
"$@" 2>&1 | tee -a "$LOG"
}

run "$BUNDLETOOL" validate --bundle="$BUNDLE"

APKS="$OUTPUT_DIR/protected.apks"
SIGN_ARGS=()
if [[ -n "$KS" ]]; then
test -n "$ALIAS" || { echo "提供 --ks 时必须提供 --ks-key-alias" >&2; exit 2; }
SIGN_ARGS+=(--ks="$KS" --ks-key-alias="$ALIAS")
if [[ -n "$KS_PASS_ENV" ]]; then
SIGN_ARGS+=(--ks-pass="env:$KS_PASS_ENV")
fi
fi

run "$BUNDLETOOL" build-apks \
--bundle="$BUNDLE" \
--output="$APKS" \
--overwrite \
"${SIGN_ARGS[@]}"

if [[ -n "$DEVICE" ]]; then
run "$BUNDLETOOL" install-apks --apks="$APKS" --device-id="$DEVICE"
fi

if command -v shasum >/dev/null 2>&1; then
shasum -a 256 "$BUNDLE" "$APKS" | tee "$OUTPUT_DIR/checksums-sha256.txt"
else
sha256sum "$BUNDLE" "$APKS" | tee "$OUTPUT_DIR/checksums-sha256.txt"
fi

echo "AAB 本地验证完成:$OUTPUT_DIR"
Loading
Loading