# Godus (iOS) IPA 逆向分析报告

> 分析对象：`godus.ipa`（原始加密）与 `com.mobage.ww.a1913.godusios_1.47_und3fined.ipa`（砸壳/解密）
> 分析方式：4 个 sub-agent 并行（基本信息 / 网络域名 / 游戏引擎 / 安全与砸壳验证）
> 工作目录：`/Users/jarvis/Downloads/playground/_extract/{original,cracked}/Payload/Godus.app`

---

## 1. 基本信息

| 项目 | 值 |
|---|---|
| 应用名 | Godus |
| Bundle ID | `com.mobage.ww.a1913.godusios` |
| 版本 | `1.28999`（build `28999`）*注意：文件名写 1.47，以 plist 为准* |
| 开发商 / 发行 | 22Cans 开发，Mobage(DeNA) 发行 |
| 最低 iOS | 12.1 |
| 设备 | iPhone + iPad（UIDeviceFamily 1,2），仅横屏 |
| 架构 | arm64（单架构 Mach-O executable） |
| 主二进制 | `Godus`，37,356,784 字节 |
| 构建工具 | Xcode 15.4 / iphoneos17.5 SDK（21F77） |
| Team ID | `K5YPLWCC82` |
| 签名 | Apple App Store 正式签名（非 ad-hoc），无 embedded.mobileprovision |
| 权限声明 | 仅 `NSUserTrackingUsageDescription`（个性化广告）；无相机/定位/麦克风等 |
| ATS | 无全局任意加载；仅对 `game.22test.net`、`public.22cans.com` 允许明文 HTTP |
| URL Scheme | 无；`LSApplicationQueriesSchemes`: fb / instagram / tumblr / twitter |
| 本地化 | en, fr, it, de, es, ru, tr, ko, ja（+Base） |
| 图标 | AppIcon60x60@2x, AppIcon76x76@2x~ipad；Assets.car |
| Entitlements | Game Center、APNs production、associated-domains `applinks:22cans.com` |
| Info.plist | 原始与砸壳版**字节完全一致** |

---

## 2. 网络请求域名

### 2.1 游戏自有后端（第一方 22Cans / Cans-Services）
| 域名 / URL | 用途 | 来源 |
|---|---|---|
| `godus-live-rpc-v2.22cans.net` | 生产 RPC/玩法服务器 | serverEnvironmentLive.txt |
| `godusliveapi.cans-services.com` | 生产 API `?data=` | Live |
| `godus-sta-lb-8fc75ce120b13cb4.elb.us-west-2.amazonaws.com` | 预发布 RPC（AWS ELB） | Staging |
| `godusapi.cans-services.com` | 预发布/开发 API `/sta` `/dev` | Staging/Dev |
| `10.11.12.235` | 内网开发 RPC | Dev/Debug |
| `game.22test.net` | HTTP `http://game.22test.net/cgi/t.php` | 二进制 + ATS |
| `public.22cans.com` | HTTP `global-meta.json` | 二进制 + ATS |
| `godusanalytics.appspot.com` | 游戏埋点 | 二进制 |
| `geoip-1961948630.eu-west-1.elb.amazonaws.com` | GeoIP | 二进制 |
| `s3-eu-west-1.amazonaws.com/godusassets/` | 资源 CDN | 二进制 |

### 2.2 账号 / 客服 / IAP
`22cans.zendesk.com`、`godus.zendesk.com`、`cloud.ludei.com`（IAP 收据校验 `verify-purchases`）、`itunes.apple.com`、`graph.facebook.com`、fbcdn/scontent（FB 头像 CDN）

### 2.3 广告网络
- **AppLovin MAX**：`a/d/ms/rt/prod-a/vid/pdn/img/assets.applovin.com`、`*.applvn.com`、`cdnjs.cloudflare.com`、`compliance.iabtechnologylab.com`
- **IronSource / Supersonic**：`init.supersonicads.com`、`ironsrc.com`
- **Unity Ads**：`*.unityads.unity3d.com`、`{a,i,o}-adq.mediation.unity3d.com`、`{i,o}-sdk.mediation.unity3d.com`、`o-crash/o-ext.mediation.unity3d.com`
- **Google AdMob / Ad Manager**：`googleads.g.doubleclick.net`、`pagead2.googlesyndication.com`、`googleadservices.com`、`imasdk.googleapis.com`、`fundingchoicesmessages.google.com`、`ca-app-pub-REDACTED~REDACTED`
- 仅类符号未含端点：Chartboost、Vungle、Fyber、InMobi、Mintegral 等 mediation adapter

### 2.4 分析 / 归因 / 崩溃
Firebase 项目 `godus-b8f8e`：
`godus-b8f8e.firebaseio.com`、`*.appspot.com`、`firebaseinstallations/remoteconfig/logging.googleapis.com`、`crashlyticsreports-pa.googleapis.com`、`firebase-settings.crashlytics.com`、`app-measurement.com`
Apple Search Ads：`api-adservices.apple.com`、`app-analytics-services.com`
（**未发现** Adjust/AppsFlyer/Kochava/Branch/Amplitude/Mixpanel/Flurry/Sentry）

### 2.5 社交/支持
`www.facebook.com/godusgame`、`www.reddit.com/r/GODUS`、`discord.gg/aUfBcK7FSx`、`www.22cans.com`、`tactilefusion.com`、`docs.google.com`

### 2.6 服务器环境配置
- **Live**：RPC `godus-live-rpc-v2.22cans.net`，API `godusliveapi.cans-services.com`，appIDMobage `c8fefda5-…`
- **Staging**：RPC `godus-sta-lb-…elb.us-west-2.amazonaws.com`，API `godusapi.cans-services.com/sta`
- **Dev/Debug**：RPC `10.11.12.235`，API `godusapi.cans-services.com/dev`
- `debugMobile.txt` 默认 `serverEnvironment Staging`，含 `nonrelease/internal/noauth` 标志

---

## 3. 游戏引擎

**结论：22Cans 自研引擎（proprietary in-house engine），不是 Unity / Unreal / Godot / Cocos。**

证据：
- 引擎源码路径字符串 `$Id: //22cans/GODUS658/godus/game/src/PerforceId.h#1 $`（Perforce depot `//22cans/GODUS658/`）
- 自研类：`VoxelBrush`、`NavSystem`、`StreamedTerrain`、`RewardManager`、`CAkAudioMgr`
- 无 Unity 痕迹（无 UnityFramework/il2cpp/global-metadata.dat）；出现的 "Unity" 仅为 **Unity Ads 广告 SDK** 误报
- `iOS/*.pck` 魔数为 **`AKPK`**（不是 Godot 的 `GDPC`），实为 **Wwise 音频包**
- `Cocos2dx/Unreal/AdobeAir/Cordova` 等仅出现在广告 SDK 的框架探测枚举里

**完整技术栈：**
| 层 | 技术 |
|---|---|
| 渲染 | **Diligent Engine v2.x (2022)** RHI，支持 OpenGL ES / Vulkan(MoltenVK) / Metal / D3D11-12；HLSL 经 glslang + SPIRV-Cross 交叉编译 |
| 脚本 | **Lua 5.1**（179 个 `.lua`，含 `Mobile/scripts.lua`） |
| UI | **Autodesk Scaleform (GFx)** |
| 音频 | **Audiokinetic Wwise 2022.1**（`.pck`/`.bnk`/`.wem`） |
| 资源 | 自研 `data.bin`（208MB）+ CSV/Lua 数据；物理为自研（无 PhysX/Havok/Box2D） |

---

## 4. 其它关键信息 & 砸壳验证

### 4.1 砸壳（解密）验证 ✅
| | 原始 | 砸壳 |
|---|---|---|
| `Godus` cryptid | **1**（加密） | **0**（已解密） |
| `AppLovinSDK` cryptid | 1 | 0 |
| 差异字节 | — | 仅 cryptid 一字节（offset 4696）+ 整个加密区 81920–31064063 |
| Info.plist / 19 个 libswift | 相同 | 字节一致 |
| `SC_Info/Godus.sinf` | 1048B，签署名 `Account-A` | 1072B，重签 `Account-B`，新增 crdt/asdt 字段 |
| 签名状态 | Obsolete（旧 App Store） | `invalid signature (code or signature have been modified)` |
| 标记文件 | 无 | `Payload/decrypt.day` = `und3fined` |

**结论：砸壳版确为真·解密、功能等价；但保留的 Apple 正式签名/CMS 已失效，需重新签名才能侧载运行。** 异常点：sinf 被重签（签署人身份变化）、额外新增 `AppLovinSDK.sinf`、19 个 dylib 仅改 mtime。

### 4.2 安全 / 反调试
- **无 SSL 证书固定（no pinning）**、无 frida/ptrace 自杀检测
- 越狱检测仅来自广告 SDK（检查 `/Applications/Cydia.app`、MobileSubstrate）
- 反作弊是**服务端存档校验**（`SOMEONE_HACKED_THE_SAVE`、hash 比对），非客户端加固
- 二进制存在被门控的调试/作弊函数（`DebugUnlockAllGodPowers` 等，发布版不可达）

### 4.3 资源加密
- `data.bin`（208MB，magic `e5 17 0f 00`）= 自定义打包归档，**未加密**（内含明文 PNG/JPEG/MP3/KTX）
- `iOS/*.pck`（`AKPK`，含 `GodusMain.pck` 53MB）= Wwise 流式音频包，**未加密**，含明文 JPEG/WAV
- `config.csv`（1295 行全局调参表）、`fileBalanceManifest.txt`（Perforce 清单）

### 4.4 第三方 SDK（买量变现栈）
IronSource 8.0.0 + Ad Quality 7.19.1、Google AdMob/GMA 11.3.0、UMP 2.6.0、Unity Ads 4.11.3、AppLovin 12.4.2、Facebook Audience Network、Firebase 10.29/10.25（Core/Crashlytics/RemoteConfig/ABTesting/Installations）、Soomla + LUDE（IAP）、OM SDK；Info.plist 约 150 条 SKAdNetwork。

### 4.5 账号 / 内购
- 账号：**Mobage(DeNA)** 为主（`appIDMobage`），集成 Facebook 登录、Game Center；无 Sign in with Apple
- IAP：StoreKit + Soomla/LUDE，商品见 `Mobile/InitialWorldSetup/shopData.csv`（GEM_100_AAC $4.99 … GEM_2800_AAC $99.99、REMOVE_ADS $1.99 等）

### 4.6 游戏内容结构
`Mobile/` 共 1341 文件（1156 CSV + 179 Lua）：`Balance/`、`GUI/`、`InitialWorldSetup1-8`、`ExpeditionMode/Event_01-17`、`UpworldLevels`、`HubworldLevels`、`TutorialLevels`、`VS/Maps`（多人地图）等。Perforce changelist = `65111`。

### 4.7 Firebase 配置
项目 `godus-b8f8e`，App ID `REDACTED_FIREBASE_APP_ID`，API key `REDACTED_GOOGLE_API_KEY`，分析/广告开关默认关闭。

---

# 深度逆向（第二阶段：4 个专项 sub-agent）

> 本章是逆向价值最高的部分：容器格式、脚本逻辑、网络协议、音频与配置。原始包里的字符串是加密的，以下全部基于**砸壳版**二进制与明文数据文件分析。

---

## 5. `data.bin` 容器格式 —— 已完全逆向并全量解包

`data.bin`（208,801,485 字节）是 22Cans 自定义的**哈希索引归档**，**无压缩、无加密**，所有资源均为明文。

### 5.1 精确字节布局
```
+-------------------------------+ 0x00
| header: 3 x u32               |  magic=0x000F17E5, count=5519, build_id=0x25F64172
+-------------------------------+ 0x0C
| TOC: count x 12 bytes         |  [u32 offset][u32 size][u32 OAT32(path)]
+-------------------------------+ 0x0C + 12*5519 = 0x102C0
| payload[0..5518]              |  原始资源，每个 16 字节对齐，间隙为 0x00 填充
+-------------------------------+ EOF
```
- 首条 payload 偏移 `0x102C0` = `12 + 12×5519`，该处正好是 `89 50 4E 47`（PNG magic）—— 结构自证。
- 空间完全对账：`资源 208,695,659 + 头/TOC 66,240 + 对齐填充 39,586 = 208,801,485`（=文件大小，无遗漏）。

### 5.2 文件命名哈希已破解（关键突破）
TOC 每项第 3 个 dword **不是内容校验**（与 crc32/adler32/fnv1a 都不匹配），而是**逻辑资源路径的 Jenkins one-at-a-time 32 位哈希**：
```python
def oat32(s):          # Bob Jenkins "one-at-a-time"
    h = 0
    for c in s:
        h = (h + c) & 0xFFFFFFFF
        h = (h + (h << 10)) & 0xFFFFFFFF
        h ^= h >> 6
    h = (h + (h << 3)) & 0xFFFFFFFF; h ^= h >> 11
    h = (h + (h << 15)) & 0xFFFFFFFF
    return h
```
验证：`imported/cactum/models/cactum1.glb → 0x3494bd2d`（命中且 TOC size 与真实 GLB 长度一致）。用字典攻击（data.bin 内字符串 + 松散 CSV/Lua + Godus 二进制字符串）恢复出 **640 个文件名（473 个高可信）**。

### 5.3 资源清单（5,519/5,519 全部提取）
| 类型 | 数量 | 字节 | 说明 |
|---|---:|---:|---|
| glTF / GLB 模型 | 2,112 | 92.5 MB | 二进制 glTF 2.0 |
| PNG 图片 | 1,556 | 66.6 MB | 贴图/精灵/UI |
| 文本/配置 | 1,381 | 2.3 MB | Lua、CSV、shader technique、粒子 `.ptc` |
| SPIR-V 着色器 | 192 | 0.5 MB | `03 02 23 07` magic |
| JPEG | 132 | 0.6 MB | |
| 嵌套 Godus bundle | 51 | 11.1 MB | magic `0x6792AB2B`/`0xFB1F2B0C`（动画组） |
| 原始二进制块 | 68 | 15.9 MB | 含 2 个 4 MiB 块（疑似高度场浮点） |
| BIU 图集包 | 14 | 12.8 MB | `BIU\x05\x042.25`，内嵌帧名列表 |
| 字体 TTF/OTF | 8 | 6.2 MB | cinecaption、ptsans、nanumgothic… |
| PSD | 1 | 0.06 MB | |
| 空文件 | 4 | 0 | 别名/删除标记 |

### 5.4 其它发现
- 内嵌原始源工程路径 560 条（`D:\Perforce\godus\game\data\VFX\Textures\...`、`D:/Github/godus_sourceart/...`）、Maya `.mb` 动画、`.tga/.psd/.ptc` 源文件路径。
- 最后一个 TOC 项（hash=0）是一份 **139 行动画名清单**。
- **签名 carving 兜底只找到 1 个未覆盖 blob** → 证实 TOC 完整覆盖整个 payload 区，**无隐藏顶层资源**。

**产物**：`_extract/unpack_data_bin.py`（纯 stdlib，`python3 unpack_data_bin.py`）、输出 `_extract/data_bin_out/{named 473, unnamed 5046, _manifest.csv, _names.csv, _inventory.txt}`。

---

## 6. Lua 游戏逻辑与引擎绑定 API（相当于"mod API 全表"）

### 6.1 脚本架构
- 179 个 `.lua`（明文，非字节码）。引擎固定查找三份：`scripts.lua`、`functions.lua`、`scripts_visiting.lua`；其中 `Mobile/scripts.lua`（4,182 行）是**全局引导**，其余为各关卡 `<map>/scripts.lua`。
- **无 require/dofile/import**——引擎自行按名加载，再用全局表共享。
- 事件模型：`_EventListeners_` + `triggerEvent(name,ctx)` / `addEventListener(tbl,name)`；引擎回调 `onPostLoad/onStartPlay/onUpdate/onCardDismissed/onSculptComplete/onTempleComplete/onFollowerBorn…`。
- **作用域覆盖系统** `_OverrideLogic_`（scripts.lua:1958）：监听表声明 `overrides={hudVisFlags,activityLock,tableOverride,configOverride,sculptLock,cameraLock,timeOfDay}`，注册时应用、注销时还原。

### 6.2 引擎暴露给 Lua 的绑定（308 个）—— 高频调用
`Persist`(844) · `Console`(565) · `After`(551) · `Config`(513) · `ClearTip`(289) · `SetCamera`(248) · `TriggerAlert`(187) · `TriggerTipGUI`(123)…
按用途分组（节选）：
- **持久化/云存档/认证**：`Persist` `ForceSaveGame` `GetAuthValue` `GetNumClaims` `LoggedIn` `IsCloudUploading`
- **配置/数值**：`Config(k[,v])` `GetConfig` `GetOverrideValue` `Table` `TableString` `BalanceUnlockModifierString`
- **UI/HUD**：`EnableHUDElement` `ShowUI` `ClearUI` `LockHudComponent` …
- **相机/输入**：`SetCamera` `LockCameraToRegion` `ZoomTo` `DoCameraShake`
- **活动锁**：`LockActivity` `UnlockActivity`（0/1=雕刻 2=sprog 4=销毁岩石/树）
- **世界读**：`Belief()` `Gems()` `WheatCount()` `PopulationCount` `GetSculptLayers` `GetFirstFollowerInRadius` …
- **世界写**：`BuildAbode` `CastPower` `SpawnFollower` `KillAllFollowerInRadius` `TrySetFire` `SetBelief` …
- **卡牌/解锁**：`GiveCard` `CardOwned` `UnlockStarterPack` `GivePowerUpgrade`
- **广告/IAP/社交**：`LuaCallback_WatchAd_PressedTab` `LuaCallback_Facebook_InviteSuccess`
- **调试**：`IsDebug` `IsDesktop` `DebugDisplay` `LuaStateLog`

### 6.3 经济系统（数值可直接用于分析）
- 货币：**宝石**(硬)、**信仰 Belief**、**小麦**、**矿石**、**云石云石 Cloudstone**（软/资源）。
- 兑换常数（`config.csv`）：`GemCostPerBelief=0.005`、`GemCostPerWheat=3.33`、`GemCostPerOre=10`、`GemsPerBuildSecond=0.00347`、`InitialGems=20`、`NumberOfGemsPerFullCell=0.18`。
- `Balance/GemCost.csv` = "时间→宝石"阶梯（1 宝石↔288 建造秒/1440 sprog 秒/200 信仰…）。
- **神威消耗（信仰）Live**：TotemActivate 20 / Totem 100 / FingerOfGod 200 / Beautify 5000 / Meteor 10000 / TidalWave 20000 / Tornado 30000 / Volcano 50000 / **Armageddon 80000**。
- 解锁阈值：`populationLevels.csv`(人口 4→Card_Sculpting … 600→Card_CliffSculptingLevel3)、`grainLevels.csv`、`oreLevels.csv` 等。
- 宝石升级店 `GUI/powerUpgradeData.csv`（结算/神威升级 10/20/40/80/160 宝石）。

### 6.4 内购目录（`Mobile/InitialWorldSetup/shopData.csv`）
`CASH` 档：GEM_50_AAD $4.99 / GEM_120_AAD $9.99 / Gems_250 $19.99 / Gems_650 $49.99 / Gems_1400 $99.99 / REMOVE_ADS $1.99 / BUNDLE_STARTER $2.99 / BUNDLE_SHAMAN $9.99。
`GEMS` 档：Belief_1000=5、Belief_10000=40、Wheat_300=125、Ore_1000=900、Cloudstone_Large=225、Revive=1。礼包内容见 `Balance/Offerings/OfferingPacks.csv`、奖励见 `Balance/specialCards.csv`。

### 6.5 关卡/多人格式
- 每个地图目录固定 CSV 集：`info.csv`(头+内联覆盖)、`unlocks.csv`、`influence_areas.csv`、`initialMapObjects.csv`、`templePositions.csv`、`rewardChests.csv`、`scripts.lua`。
- **内联数值覆盖**：`info.csv` 里的 `Config,<key>,<val>` 与 `Table,<t>,<col>,<row>,<val>` 可为单张地图重调全局经济（数据驱动，很干净）。
- `Mode` 枚举：`0=POP 领地战 / 1=ARM 末日战 / 2=CTG / 3=远征事件 / 4=教程 / 5=Hubworld`；VS 地图按后缀 `_POP/_ARM/_CTG` 区分模式。
- 事件体系：`Balance/Story/storyEventDetails.csv`（UID 1/1602/1606/1607 等）+ 每事件 `EventCtrl_NN` 中心图 + `RewardData.csv` 星数→奖励表。

### 6.6 调试/作弊入口（发布版被门控）
| 触发 | 位置 | 效果 |
|---|---|---|
| 按键 `u`(code 43) | `InitialWorldSetup/scripts.lua:1407` | `endTutorial()` 跳过教程 |
| 按键 `14..19` | `InitialWorldSetup6/scripts.lua:819` | 设置 `DebugHouseRank` 建指定等级房屋 |
| `DebugSetTutorial(name)` | `Mobile/scripts.lua:936` | 跳到任意教程，"X" 跳过全部 |
| `showTutorialProgress()` | `Mobile/scripts.lua:846` | 调试浮层（教程/Belief/Gems/云状态） |
| `DEBUG_MODE=IsDebug()` / `DESKTOP_MODE=IsDesktop()` | scripts.lua:5-6 | 全局门控 |
- `config.csv` 调试开关：`DebugUnlockAllGodPowers=0`、`Monetization_Debugging=0`、`GUI_ShowAllResources=0`、`TESTCALL_*` 等。

### 6.7 可复用技巧
- **CSV→Lua 回调桥**：`GUI/statRowData.csv` 的行内嵌 `<lua>func:arg1:arg2</lua>`，引擎调用对应全局函数——任何 mod 都可注册函数并被 CSV 引用。
- **枚举契约**：`AutoEnum()` 块（`en_GuiTip`/`en_HudComponent`/`en_ButtonID`/`en_InfoPopupMode`）必须与 C++ 枚举同步，是可恢复的引擎交互点地图。

**产物**：`_extract/analysis_lua.md`。

---

## 7. 网络协议 / 认证 / 存档校验（逆向核心价值）

游戏有**三条彼此独立的通道**：

| 通道 | 传输 | 用途 | 编码 |
|---|---|---|---|
| **RPC 后端** | **Exit Games Photon C++ SDK**（UDP/ENet，默认 **5055**；TCP 备选 **4530**） | 实时多人、社交、**云存档/资源同步**、认证 | Photon 字节键参数字典 + ENet 分帧；自定义"加密"握手 → `opRPCAuthenticate` |
| **REST API** | HTTPS GET | 账号注册/查询、Bug 上报、埋点、GeoIP | `GET <base>?data=<base64(JSON)>`，响应 base64(JSON) |
| **埋点** | HTTP POST | 事件、登录跟踪 | JSON body |

### 7.1 RPC = 自托管 Photon LoadBalancing（已确认）
- 二进制含 `N9ExitGames13LoadBalancing…`、`N9ExitGames6Photon8Internal8EnetPeerE`、Godus 自研包装 `NetworkLogic::CustomOperationRequest` 等 RTTI。
- 默认端口硬编码：`mov w0,#0x13bf`(=5055 UDP)、`mov w0,#0x11b2`(=4530 TCP)。
- 状态机：`STATE_CONNECTING_TO_RPC_SERVER → STATE_ESTABLISHING_ENCRYPTION_ON_RPC_SERVER → STATE_AUTHENTICATING_ON_RPC_SERVER → STATE_CONNECTED_TO_RPC_SERVER`（失败打印 `Encryption failed to establish`）。
- 操作集（opcode 0..11 注册）：`opRPCAuthenticate` `opRPCGetCurrentPlayer` `opRPCSetCurrentPlayerData` `opRPCGetAsset` `opRPCGetAssetHashes` `opRPCPutAsset` `opRPCDeleteFolder` `opRPCGetHubData` `opRPCGetFriends` `opRPCSendInventoryTransactions` `opRPCFinishGooglePlayPurchase`。
- 服务端错误码枚举：`InvalidAuthentication` `ClientVersionOutdated` `SessionExpired` `InvalidDigest` `CopyInProgress` 等。

### 7.2 REST `?data=` 编码（已确认）
- `godusAPIURL` 本身以 `?data=` 结尾，客户端只在其后追加 **标准 Base64 的 JSON**（base64 字母表 `+/`，`nlohmann::json` 静态链接）。
- 注册/查询：`GET https://godusliveapi.cans-services.com?data=<b64>`，JSON = `{"Op":1,"Id":"<uid>","FRS":"<..>","GPGId":"<..>"}`（注册）或 `{"Op":2,"Id":"<uid>"}`（查询），返回 64 位网络 id。
- 无 gzip/deflate/加密（zlib 只用于 `blob.zip`）。

### 7.3 认证流程（已确认要点）
- 登录类型 `g_signInTypeStore ∈ {facebook, mobage, guest}`；**Mobage(DeNA) 为主**。
- ExitGames token → "Authorizing it with Mobage" → `opRPCAuthenticate`；账号升级走 `AHUpgrade::AUTHENTICATE2`。
- 凭据存 iOS Keychain：service **`GodusRPC`**，account/domain **`22cans.com`**，哨兵值 `ThisIsNotIt`；另存 `guest.dat`/`nick.dat`。
- Photon app 身份与密钥硬编码（见 7.6）。

### 7.4 存档校验（**可被篡改，重要**）
- 本地存档格式（**已由反汇编修正**）：`[u32 magic][u32 version]` 后跟**一串记录**，每条 `key[60] || u32 长度 || data`；**最后一条是校验记录** `00*60 || u32 0x10 || 原始 16 字节 MD5`。MD5 输入 = **所有非校验记录 data 字段的拼接**（8 字节头/60 字节 key/4 字节长度都不参与哈希）。
  - 成功：`checksum has succeeded: expected %s`（digest 与 `record.data[0:16]` 逐字节比对）
  - 失败：`checksum has failed:` + **`SOMEONE_HACKED_THE_SAVE`**
- **漏洞点（已实测验证）**：校验是**无密钥的客户端 MD5**，全部信息都在客户端；改档后重算 MD5 写回校验记录即可通过（详见 §13）。该检查只是"防误改"而非"防作弊"。
- 云存档 = `blob.zip`（zip + zlib/deflate），内容 `zprofile/zstate/homeworld/presence/newprofile`；上传前对 blob 计算 MD5（`Blob (%i bytes) has hash %s` vs `we calc %s`），且该 MD5 hex 由**客户端**随 `opRPCPutAsset` 一起上传 → 同一类弱点。经 `opRPC*Asset*` 同步；冲突走 `SHOW_CHOOSE_SAVE_DIALOGUE` → 本地/远程解决。
- **资源下载校验**：`assets.json` 提供 **MD5 + SHA-1** 双校验（源 `s3-eu-west-1.amazonaws.com/godusassets/`）。

### 7.5 Bug 上报签名（**硬编码弱密钥**）
```
POST http://<host>/web/report/bug      Content-Type: application/json
X-Signature = hex(HMAC_SHA256(body, key))
key = "REDACTED"        // 硬编码，5 字节
```
（SHA-256 仅用于此处，IV 常量可确认。）

### 7.6 硬编码密钥/标识汇总
| 项 | 值 | 评估 |
|---|---|---|
| Bug 上报 HMAC 密钥 | `REDACTED` | 极弱，可伪造上报 |
| Photon app（iOS） | `Godus-iOS` / key1 `REDACTED` / key2 `REDACTED` | 泄露 |
| Photon app（Android） | `Godus-Android` / `REDACTED` / `REDACTED` | 泄露 |
| 2048-bit RSA 公钥（base64 DER） | `REDACTED_RSA_PUBKEY` | 用途待定（IAP/清单签名） |
| Ludei/CocoonJS IAP api_key | `REDACTED` | 泄露（旧渠道） |
| AdMob App ID | `ca-app-pub-REDACTED~REDACTED` | 公开标识 |
| Firebase | project `godus-b8f8e`，API key `REDACTED_GOOGLE_API_KEY` | 公开标识 |

### 7.7 安全结论
- **无 TLS 证书固定**；且 ATS 对 `game.22test.net`、`public.22cans.com` 放行明文 HTTP。
- RPC 的"加密"是 Godus `NetworkLogic` 的自定义字节键 Photon 操作握手（真实密码算法疑在 Photon SDK 内），失败打印 `Encryption failed to establish`。
- 综合：**本地改档、请求伪造都较容易**，客户端无强加固。

**产物**：`_extract/analysis_protocol.md`（含函数/字符串地址，`file offset = VMA − 0x100000000`）。

---

## 8. 音频包（AKPK/Wwise）与配置/资产

### 8.1 AKPK 容器格式（已逆向）
`.pck` **不是**标准 Wwise FilePackager 顶层，而是 `AKPK` 包装（version 1），内含一个 Wwise SoundBank（`BKHD/DIDX/DATA/HIRC`）及可选散列 `.wem`。全部**明文**（PCM16 或 Wwise-Vorbis），无自定义加密。
```
0x00 "AKPK" | 0x04 headerLength | 0x08 version=1
0x0C languagesLength | 0x10 banksLength | 0x14 streamsLength | 0x18 externalsLength(可选)
body: LANGUAGES | banks(FILE_TABLE) | streams(FILE_TABLE) | externals(EXTERNAL_TABLE)
偏移 = startBlock * blockSize
```
| 包 | 大小 | 内容 |
|---|---:|---|
| Init.pck | 4,638 | 元数据 bank（`INIT`/`STMG`/`HIRC`/`ENVS`/`PLAT=iOS`） |
| BubbleTunes.pck | 1.5 MB | 音乐 bank（DIDX 50 个 wem + HIRC 2184 对象） |
| GodusMain.pck | 53.6 MB | 主音效 bank（696 个 wem，语言 `english(us)`）+ 47 个流式 wem（`sfx`） |

`BKHD`：generatorVersion **145 = Wwise 2022.1**，projectID 305。共提取 **793 个 `.wem` + 3 个 `.bnk`（83 MB）**。（早前"含 JPEG/ID3"是压缩数据里的字节巧合，DIDX 扫描证明无图片。）

### 8.2 `config.csv`
- 1,295 行，格式 `key, live, staging, debug, #comment`；`##` 为分类标题（共 71 个 `#`/`##` 段）。
- 主要段（19 个 `##`）：Belief、GOD POWERS–BELIEF、GOD POWERS–OTHER、INFO BUBBLE、HEIGHT±、BEAUTY±、TAP on Follower/Object、PANNING、METEOR、TAPS PER ROCK/TREE、STORY MODE、TOTEM BELIEF COST、GEM BALANCING。
- 代表值：`InitialBelief 0/1000/500`、`InitialFollowers 2`、`DayTimeLength 900/6000/6000`、`TreeGrowthTime 3600/60/60`、`believe_* `（见 §6.3）、`InviteReward 2`、`SpeedupBoostEnabled 0/1/0`、`StoryModeBoatCapacity 30`。
- 另有 `Mobile/Balance/config.csv`（相机/设计覆盖），两者叠加使用。

### 8.3 硬件分级与资产
- `Mobile/HwLevelControls.csv`：9 档画质 `DesktopHigh(100) … MobileSuperLow(800)`，逐档关海面 shader/阴影、降 `ProjectedShadowRes(512→0)`。
- `Mobile/SystemToHwLevel.csv`：机型→画质档映射（iPhone6,1…iPhone10,4、iPad、Nexus 5…）。
- `Assets.car`（Xcode 15.4 生成，StorageVersion 17）：36 renditions / 7 命名资源（`AppIcon`、`22Cans_TightCrop512`、`CreativeUK`、**`PoweredByDiligent`** 等）——再次印证 Diligent 渲染器。
- 本地化 10 种（Base/en/de/es/fr/it/ja/ko/ru/tr）；`*.lproj/InfoPlist.strings` 仅含 `NSUserTrackingUsageDescription`。
- `Mobile/fileBalanceManifest.txt`：Perforce 平衡数据清单 3,391 行（Desktop 2,047 + Mobile 1,341；2,904 CSV / 475 Lua）；`changelist.txt = 65111`。
- `keyboard.txt`：桌面调试热键（F 战斗/B 建造/H 回家/T 时间线/5 商店/1 神力/2 定居点/3 神龛/4 礼物）。

**产物**：`_extract/unpack_pck.py`、输出 `_extract/pck_out/`（793 wem + 3 bnk）。

---

## 9. 分析产物索引

| 文件/目录 | 内容 |
|---|---|
| `_extract/original/Payload/Godus.app` | 原始加密包解包 |
| `_extract/cracked/Payload/Godus.app` | 砸壳解密包解包 |
| `REVERSE_ENGINEERING_REPORT.md` | 本报告 |
| `_extract/analysis_data_bin.md` | data.bin 容器逆向详版 |
| `_extract/analysis_lua.md` | Lua 逻辑/绑定 API 详版 |
| `_extract/analysis_protocol.md` | 协议/认证/存档详版（含地址） |
| `_extract/analysis_audio_config.md` | AKPK/配置详版 |
| `_extract/analysis_sdk_business.md` | SDK 与用户业务详版 |
| `_extract/analysis_architecture.md` | 应用架构详版（待生成） |
| `_extract/modding/README.md` | Lua mod 开发指南（325 绑定全表） |
| `_extract/modding/skeleton/` | 可用的 mod 脚手架（示例/CSV/注入说明） |
| `_extract/analysis_previews.md` | 模型/贴图预览详版 |
| `_extract/previews/index.html` | **资源预览画廊**（2112 模型 + 1689 贴图缩略图） |
| `_extract/preview_assets.py` | 预览生成管线 |
| `_extract/analysis_savetamper.md` | 存档完整性/绕过详版 |
| `_extract/godus_save.py` | 存档解析/校验/重建工具 |
| `_extract/save_demo/` | 改档绕过演示样例与转录 |
| `_extract/unpack_data_bin.py` | data.bin 全量解包脚本 |
| `_extract/unpack_pck.py` | Wwise pck 解包脚本 |
| `_extract/data_bin_out/` | 5,519 个解包资源 + 清单 |
| `_extract/pck_out/` | 793 wem + 3 bnk |

---

## 10. SDK 与用户相关业务分析

> 详版：`_extract/analysis_sdk_business.md`。以下把每个 SDK 映射到它支撑的**用户可见功能**，并汇总变现模型、隐私合规与用户生命周期。除 AppLovin 为独立 framework、Swift 为系统 dylib 外，其余第三方 SDK 均**静态链接进主二进制**。

### 10.1 SDK → 用户功能映射
| SDK（版本） | 支撑的用户可见功能 | 游戏内落点 |
|---|---|---|
| **IronSource / LevelPlay 8.0.0**（中介+竞价） | 激励视频/插屏/横幅/原生广告 | `LuaCallback_WatchAd_PressedTab`、`Card_AdForGems`/`Card_AdForBoost` |
| **IronSource Ad Quality 7.19.x** | 广告质量/反作弊监控（后台） | 支撑"举报广告" |
| **AppLovin MAX 12.4.2**（动态 framework） | 激励/插屏/横幅/原生/MREC + 自有 consent/ATT 流程 | 同上广告位、首启同意页 |
| **Google AdMob/GMA 11.3.0** | 广告投放 + 安装归因/deeplink（`/pagead/conversion/app/deeplink`）、IMA 视频 | 中介需求方 |
| **Google UMP 2.6.0** | GDPR/CCPA/IAB TCF **同意弹窗** | 首次启动同意流程 |
| **Unity Ads 4.11.3** | 激励/插屏/横幅 + SKAN 信号采集 | 中介需求方 |
| **Facebook Audience Network + Graph** | FB 广告需求（经 AdMob）+ 社交登录/好友/邀请 | `LuaCallback_Facebook_InviteSuccess`、`StickyTabs.FACEBOOK_SYNC` |
| **Firebase Core/Installations/RemoteConfig/ABTesting** | 远程配置 / A-B 实验 / 特征开关（热更） | C++/Lua 读取 live-ops 开关 |
| **Firebase Crashlytics** | 崩溃/异常上报 | 后台，支撑客服 |
| **GA4 (`app-measurement`)** | 产品分析/转化事件 | 后台 |
| **Apple Search Ads (AdServices)** | 付费 UA 归因 / SKAN | 后台 |
| **SKAdNetwork ×108** | 隐私保护的安装归因 | 后台 |
| **ATT** | IDFA 权限弹窗 | 首启/同意流程 |
| **Soomla + Ludei InApp** | 内购编排 + 收据校验（`cloud.ludei.com`） | 商店/宝石卡 |
| **OM SDK** | 广告可见性测量（IAB） | 广告渲染 |
| **Mobage/DeNA SDK** | 主账号平台 + 计费 + Mobage 分析 + 推送回调 | 登录/账号绑定/购买 |
| **Apple StoreKit/Game Center/APNs/AdServices** | IAP、成就/排行榜、推送、通用链接 | 内购/成就/通知 |

> **未发现** Adjust/AppsFlyer/Kochava/Branch/Amplitude/Mixpanel/Sentry/Bugsnag。

### 10.2 账号与身份业务
- 登录方式：**Mobage(DeNA) 为主**、Facebook（直连 Graph v2.0）、Game Center、游客；Android 另有 Google Play Games；**无 Sign in with Apple**；Twitter 已禁用。
- **账号升级/绑定**：`AHUpgrade::AUTHENTICATE2`；游客→Mobage（`ConvertLCDToMobage`）。游戏内催绑：完成 `Card_Discovery` → `InhibitOfferings()` + `ShowConnectGodusDialogue`；FB 绑定走 `StickyTabs.FACEBOOK_SYNC`。
- FB 绑定奖励阶梯（`SocialLogin_RewardData_Facebook`）：信仰卡 → 贴纸包 → 看好友进度 → 访问好友世界 → 多设备游玩。
- **云存档冲突 UX**：`SHOW_CHOOSE_SAVE_DIALOGUE` → `SAVECONFLICT_RESOLVE_LOCAL/REMOTE`；"Found Homeworld"/"TAP LOAD / TAP KEEP"；迁移失败给宝石补偿（`LOC_SAVELOST_*`，churn 挽留）。
- 跨端身份：REST `{"Op":1,"Id","FRS","GPGId"}` 换 64 位网络 id；Keychain `GodusRPC`/`22cans.com`。

### 10.3 变现模型
- **宝石(硬通货)来源**：初始 20、挖矿 0.18/格、**看激励视频 1 宝石**、IAP、活动/社交奖励。
- **流向**：加速/填充（`GemCostPerBelief=0.005`、`GemCostPerWheat=3.33`、`GemCostPerOre=10`）、神威/神龛升级（10–180 宝石）、复活探险者（1 宝石）、增援（0.15/秒/千人×1800–2700s）。
- **IAP 目录**（`shopData.csv`）：Gems **50/120/250/650/1400** → **$4.99/$9.99/$19.99/$49.99/$99.99**；**Remove Ads $1.99**（促销 $0.99）；**Starter $2.99**；**Shaman $9.99**；宝石买软资源（信仰/小麦/矿石/云石）、贴纸包、复活。另有多套已注释的旧宝石档（说明经济经过重平衡）。
- **礼包**（`OfferingPacks.csv`）：Starter **-66%**/3 天，Shaman **-70%**；`OfferingFeatured.csv` 约 27 个轮换项（-20~30%，限购）；`OfferingSeasonals.csv` = Christmas2022（+ Halloween）。
- **看广告返利**：`Card_AdForGems`(=1 宝石) / `Card_AdForBoost`(=跟随者 Boost)；时间线插屏后推 Remove Ads；`Card_Revive` 兜底。

### 10.4 隐私 / 跟踪合规
- ATT 文案 `"Your data will be used to deliver Personalised Adverts to you."`（9 语言）；`AppTrackingTransparency` API。
- 三重同意层并存：**Google UMP**（GDPR/TCF）、**AppLovin consent flow**（Terms/Privacy±ATT 的 `ALConsentFlow*.json`）、**Apple ATT**（IDFA）。
- **每个 SDK 的 `NSPrivacyTrackingDomains` 全为空**；App 根无自有 `PrivacyInfo.xcprivacy`。
- 仅 **GMA** 清单声明真实 tracking（`DeviceID` tracking=true + 关联的广告/互动数据）；Firebase 清单均为"不关联、不追踪"的崩溃/诊断。
- `ITSAppUsesNonExemptEncryption=false`。

### 10.5 留存 / live-ops
- **教程漏斗**：22+ 教程键 + 每步 `SendTutorialStepAnalytics` 埋点；三个脚本化教学世界 `SelectMission(2|3|4)`。
- **远航/事件**（留存核心）：UID 1 Voyage of Discovery（600s）、1602 Arctic Expedition（3600s）、1606 Azure Archipelago、1607 Burning Isles；入场 30 跟随者、3 星 → 贴纸奖励；**增援即时间/宝石闸门**；约 150 张任务图。
- **每日/季节**：Astari 节庆 ≈24h 循环、Prayers 每 15 分钟、圣诞/万圣节 12 天窗口。
- **推送**：`aps-environment=production`（内容服务端/Mobage 驱动）。
- **社交**：FB 好友/邀请（`InviteReward=2` 宝石）、Hubworld 交易/投票、Discord/Reddit/商店评分。

### 10.6 用户生命周期
```
首启 → 三重同意(ATT/UMP/AppLovin) → 广告 SDK 初始化 → 标题/读环境(默认 Staging)
     → 登录(游客/Mobage/FB/GC) → 云存档对账(冲突→选本地/远程)
     → 教程漏斗(全程埋点) → 首次变现(催绑/Starter/Shaman/RemoveAds/看广告返利)
     → 留存环(宝石经济 + 远航事件 + 每日节庆 + 季节外观 + 社交 + 推送)
     → 客服(内嵌 Bug 上报 + Zendesk + Crashlytics + 分析)
```

**结论**：Godus 是典型的**买量变现 F2P**——自研引擎承载玩法与 live-ops（Lua/CSV 数据驱动），外部用 IronSource/AppLovin/GMA/Unity 四路中介 + Firebase 做广告与分析、UMP/ATT 处理同意、Mobage 做账号与计费。隐私清单存在**明显的漏报**（中介 SDK 未申报关联数据、tracking domains 全空），而主二进制里确实存在 doubleclick/applovin/unityads/app-measurement 等跟踪流量。

---

## 11. Lua mod 开发文档（可编译/可用）

> 成品：`_extract/modding/README.md`（807 行）+ `skeleton/` 脚手架。基于对 179 个 `.lua` 的**全量重扫**。

### 11.1 绑定参考（关键交付物）
- 从脚本中提取出**所有"被调用但非 Lua 定义"的标识符 = 325 个**；其中 **315 个在 `Godus` 二进制字符串中原样存在 = 真·C 绑定**。
- 剩余 **10 个**（`getTutorialStep`/`getSettleStep`/`getFarmStep`/`SendStepCompletedAnalytics`/`CompleteHomeworldEvent` 等）不在二进制中 → 由**引擎会加载但本地缺失的 `functions.lua`** 提供（推断）。
- 每条绑定给出：`名称 | 依真实调用点推断的签名 | 用途 | 原文 path:line 示例`，分 19 大类（定时器、持久化、配置/表、UI/HUD、提示、minimap、相机/输入、活动锁、世界读、世界写、箭头、卡牌、音频/VFX/时间、分析、事件/试炼、广告/IAP/社交、调试/平台）。

### 11.2 安装模型
- **无模块系统**（无 `require/dofile/package`）：引擎只按名加载 `scripts.lua`、`functions.lua`、`scripts_visiting.lua` + 每图 `<map>/scripts.lua`。
- 注入方式：追加到 `Mobile/scripts.lua`（全局）或某地图的 `scripts.lua`；**推荐安全模式 = 监听表 + `addEventListener`**。
- 事件分发：`treggerEvent` 回调形如 `tbl[event](context)`（无隐式 self）。
- **新发现**：`scripts.lua` 含 3 行 `#` 前缀行（146、3351–3352）却能启动 → 加载器会**剥离 `#` 注释**。

### 11.3 覆盖 schema（`_OverrideLogic_`，scripts.lua:1958–2101）
监听表 `overrides` 的键（**每个值都是数组**）：`hudVisFlags, hudBtnFlags, hudLockFlags, activityLock, sculptLock, vfxDisable, tableOverride, configOverride, cameraLock, stamina, lostWonder, timeOfDay, timelineOpening`。注册时应用、注销时还原；文档指出内置的 `tableOverride` 多表分支**有 bug**（scripts.lua:2023）。

### 11.4 其它
- **CSV→Lua 桥**：`Mobile/GUI/statRowData.csv` 的 `<lua>func:args</lua>` 单元格调用全局 `func`。
- **调试/作弊**：`DebugSetTutorial`、`endTutorial`、`showTutorialProgress`、`DEBUG_MODE/DESKTOP_MODE`、数字键码 33/35/43/14–20、`keyboard.txt`、config 开关。
- **数据调参**：config.csv 分段、Balance/InitialWorldSetup 各 CSV 列义、每图 `Config,`/`Table,`（含 `hard:`/`easy:medium:` 变体前缀）。
- **注意**：枚举需与 C++ 一致（禁止改号）、二进制已解密需重签才能运行、本指南为经验性（官方无 mod 沙箱文档）。

### 11.5 校验（已执行）
- Lua 语法：`luaparser`(ANTLR) OK（273 AST 节点）+ `lupa` 嵌入运行时 `load` OK（本机无 lua/luac/luajit，改用 Python 方案）。
- 脚手架 `mod_example.lua` 引用的 **14 个引擎调用全部命中 315 真绑定集**且在游戏脚本中有真实调用点（0 个臆造 API）。
- 绑定参考 315 行唯一、0 重复；24/24 表格格式一致；两份 CSV 解析通过、`<lua>` 标签配对。

---

## 12. 资源预览（模型 / 贴图）

> 成品：`_extract/previews/index.html`（画廊），管线 `_extract/preview_assets.py`。

- **2,112 个 GLB 全部解析成功**（100% glTF 2.0 / GLB v2，**0 扩展**，无 Draco/量化）；生成 **2,112 个模型缩略图 + 1,689 个贴图缩略图 + 8 个字体育样 + 34 张 contact sheet**。
- 导出器分布：Plattar UnityGLTF 1,623、`pygltflib` 361（22Cans 工具）、Khronos Blender I/O 128；总三角面 ≈570k；材质名有语义（如 `CherryTree_M`、`Shaman_Crafting_Base_m`）。
- **无 GPU 渲染**：自写 numpy 软件光栅器（固定等轴相机 → 重心坐标面片散射 + 法线明暗 + 深度着色 + painter's algorithm），320×320/模型。局限：只做几何渲染、不采样外部贴图（故非游戏内观感）。
- **贴图现实**：GLB 的 `images[].uri` 是**外部文件名引用**（共 1,512 处/269 个名字），但只有 473 个命名资源恢复了路径 → **按名匹配成功 0/269**；未命名资源保留 `idx_hash` 名。
- 贴图：1,556 PNG + 132 JPEG + 1 PSD；含 6 张 2048×2048 大图；命名目录 `sprites/`(35)、`sprites/flags`(31)、`splash`(6) 等。
- 字体 8 个（`ptsans-regular.ttf`、`cinecaption227.ttf`、`nanumgothic`、`roboto/inter-currency` 等）。

---

## 13. 存档完整性逆向与 MD5 绕过（实证验证）

> 成品：`_extract/godus_save.py`（工具）、`_extract/demo_savetamper.py`、`_extract/save_demo/`（样例 + 转录）。地址换算 `file offset = VMA − 0x100000000`。

### 13.1 精确格式（反汇编确认）
```
[0x00] u32 magic    (build_flag ^ 0x17；loader 接受 0x53 桌面 / 0x5a 移动 / 0x17 旧版)
[0x04] u32 version  (本 build 写 0x00107147)
[0x08] record 0 ... record N, 最后一条为校验记录

record          = key[60] || u32 LE length || data[length]
checksum record = 0x00*60 || u32 LE 0x10 || md5_digest[16]   // key 全 0 即校验记录
```
- **MD5 输入 = 所有非校验记录 `data` 字段的拼接**；8 字节文件头、60 字节 key、4 字节长度**都不参与哈希**。
- 存储的是 **原始 16 字节 MD5**（`== hashlib.md5(...).digest()`），hex 仅用于日志。

关键地址：写入器 `0x1002fabe8`、加载器 `0x1002fc354`、MD5 finalize `0x1000da798`、MD5 变换 `0x1000dac38`、MD5 IV `0x101c02260`、`blob.zip` 哈希 `0x1002fd540`、`opRPCPutAsset` 哈希 `0x1002afd90`。

### 13.2 绕过实证（`demo_savetamper.py`）
```
STEP1 合法存档      expected == stored           verify=True   ("checksum has succeeded")
STEP2 改数据(100→999) kept checksum 不变          verify=False  (触发 SOMEONE_HACKED_THE_SAVE)
STEP3 重算 MD5 写回校验记录                        verify=True   ("checksum has succeeded")
RESULT: valid=True -> tampered=False -> bypass=True   ✅ 绕过成功
```
（样例为**合成存档**，但与确认格式字节兼容；用 `hashlib.md5` 与二进制内 MD5 语义双重校验一致。）

### 13.3 云存档同一弱点
`blob.zip` 由 `0x1002fd540` 做 MD5；`opRPCPutAsset` 的 `(hash %s)` 是**本地计算、随上传参数一起发送**（`0x1002afd90`/`0x1002afdb0`）→ 客户端可自算，除非服务端独立重算。

### 13.4 结论
完整性校验为**无密钥、无签名、无 MAC 的客户端 MD5**，任何人逆向格式后即可重算通过。修复需引入**设备外密钥的 HMAC/签名**或**服务端校验**。

---

## 14. 应用架构（iOS 壳层 / 引擎嵌入 / 依赖）

> 详版：`_extract/analysis_architecture.md`。地址换算 `file offset = VMA − 0x100000000`。

### 14.1 总体：单二进制、静态全链接（仅两处动态库）
- **只有一个主可执行文件 `Godus`**，几乎所有第三方 SDK（Diligent、MoltenVK、Wwise、Photon、Firebase、GMA/AdMob、IronSource/LevelPlay、Unity Ads、约 15 家广告网络）都**静态链接进主二进制**。
- **唯一独立加载物**：`Frameworks/AppLovinSDK.framework`（动态，`@rpath`）+ `Frameworks/libswift*.dylib`（Swift 5 运行时，因最低 12.1 < 12.2 无系统 Swift）。
- 无 `libcurl`；HTTP 走 `nativeformat::http::ClientNSURLSession`（CFNetwork/NSURLSession）。

### 14.2 iOS 壳层
- 入口 `main`(`0x100016cc4`)：解析 `-forcegl` → 全局 `g_forceGL`(`0x1021a8830`)，随后 `UIApplicationMain(_,_,nil,AppDelegate)`。**无 SwiftUI/SceneDelegate**。
- `Base.lproj/Main.storyboardc` 场景：初始 VC = `ModeSelectionViewController`；`EAGLViewControllerID`/`MVKViewControllerID`/`MetalViewControllerID` 均为 `GameViewController`，视图分别为 `EAGLView`/`MVKView`/`MetalView`。
- Shell 类（ObjC++）：`AppDelegate`、`ModeSelectionViewController`、`GameViewController`（含原生对话框/键盘桥 `ShowDialog:withMsg:cb:btn1:btn2:btn3:`）、`BaseView`、`AppViewBase`、`EAGLView`/`MVKView`/`MetalView`。
- **渲染后端选择**：默认 **Vulkan（MoltenVK，`goVulkan:`→`MVKViewControllerID`）**；`-forcegl` → OpenGL ES（`goOpenGLES:`→`EAGLViewControllerID`）；`goMetal:` 在本 build 是 **no-op**（Metal 场景存在但未接选择器）。
- 引擎实例：各视图 `initWithCoder:` → `[self initApp:4|5|6]`（GLES/Vulkan/Metal）→ `AppViewBase._theApp = std::unique_ptr<Diligent::IOSAppBase>`；每帧由 **CADisplayLink → `AppViewBase::render`** 驱动。

### 14.3 引擎分层
```
L0 iOS 壳        main → UIApplicationMain → AppDelegate → ModeSelectionVC → GameViewController + AppViewBase
L1 平台服务      IOSAppBase / AppBackboneiOS / log_ios.mm / util_ios.mm / Keychain / StoreKit / GameKit / Wwise sinks
L2 渲染 RHI      Diligent Engine：GL | Vulkan+MoltenVK+SPIRV-Cross | Metal；glslang / SPIRV-Tools / DiligentTools
L3 网络          NetworkLogic → ExitGames Photon(UDP/ENet 5055 + Chat)；nativeformat::http → NSURLSession
L4 持久化        SaveLoad(MD5 校验) / Downloader / blob.zip(zlib) / cereal / nlohmann
L5 UI            "Scaleform" 命名的 HUD 子系统（**无 GFx RTTI，未链接中间件**）+ 原生对话框桥
L6 脚本          Lua 5.1 + After/NonPausingAfter/AddToTimer 调度 + 自定义 C 绑定
L7 玩法          VoxelBrush / NavSystem / Follower / Card / Shop / Reward / Story / Alert / HUDController
```

### 14.4 依赖与模块
- `otool -L`：强链 `OpenGLES/Metal/MetalKit/UIKit/QuartzCore/AudioToolbox/AVFoundation/StoreKit/GameKit/Security/CFNetwork/libsqlite3/libz/libc++/@rpath/AppLovinSDK`；弱链 `AdSupport/JavaScriptCore/WebKit/AppTrackingTransparency/Combine/CryptoKit/MetricKit/SwiftUI`。
- **类前缀→厂商**（`__objc_classname`，2,493 个）：`GAD*`441/GMA*(GMA)、`UAD*/UADS*`240/`USRV*`94(Unity Ads)、`APM*`168/`FIR*`121/FBL*+RCN*+ABT*(Firebase/GA4)、`UMP*`(同意)、`IS*/SML*/SS*`≈700(IronSource/LevelPlay)、`MA*/AL*`(AppLovin)、以及 InMobi/Mintegral/MyTarget/Vungle/Yandex/Pangle/Chartboost/Fyber/Soomla/Ludei 等 adapter。

### 14.5 启动时序（要点）
```
1 main: -forcegl → g_forceGL；UIApplicationMain(AppDelegate)
2 didFinishLaunching: 装配 window；Firebase/GoogleUtilities swizzler、广告 SDK 初始化
3 初始 VC = ModeSelectionViewController
4 viewDidAppear: 选后端（Vulkan 默认 / -forcegl → GLES）
5 GameViewController 场景 → initApp: → new Diligent::IOSAppBase；CADisplayLink
6 引擎启动: 读 serverEnvironment*.txt(默认 Staging) → config.csv+Balance 覆盖 → 画质档(SystemToHwLevel)
            → Wwise 初始化+载 iOS/*.pck → Lua 引导(scripts.lua) → InitBalanceValues → 资源下载校验 → 挂载 data.bin
7 登录/网络: BootLogin → AHLogin → ExitGames token → opRPCAuthenticate → 云存档同步(blob.zip)
8 主循环: CADisplayLink → AppViewBase::render → Diligent present
```

### 14.6 线程 / 其它
- 主循环 = **CADisplayLink（主线程）**；无独立渲染线程证据。Wwise 音频线程、Firebase worker queue、IronSource `ISNThreadSafeQueue`、NSURLSession、Photon `TPeer/EnetPeer` 服务循环。
- **Marmalade 血统**：二进制保留 `CIw*`/`IwGx*`/`s3e*`/`MarmaladeDelegate` —— 原为 Ideaworks3D Marmalade 项目，后移植到原生 iOS（保留 `nativeformat` 命名与 `CIw*` 资源类）。
- **Scaleform 说明**：仅有 `SCALEFORM::` 等字符串，**无 `GFx*`/`Scaleform::` RTTI** → UI 是自研 HUD 沿用了旧标签，GFx 中间件未链接。
- 运行时数据：`data.bin`（打包资产，OAT32 命名）、`iOS/*.pck`（Wwise）、`Mobile/*`+`config.csv`（授权源）、`serverEnvironment*.txt`/`debugMobile.txt`、存档+Keychain。

---

## 附：结论一句话
Godus iOS 是 **22Cans 自研引擎 + Lua 5.1 + Diligent 渲染 + Wwise 2022.1 音频 + Scaleform UI** 的买量变现 F2P 游戏；后端为自托管 **Photon LoadBalancing（UDP/ENet 5055）** + Base64(JSON) REST API，账号以 Mobage 为主；**存档仅靠无密钥的客户端 MD5 校验**（`SOMEONE_HACKED_THE_SAVE` 可绕过）、无 TLS 固定、Bug 上报硬编码弱密钥 `"REDACTED"`——客户端安全较弱。砸壳版已验证为真解密、功能等价。