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,APIgodusliveapi.cans-services.com,appIDMobagec8fefda5-… - Staging:RPC
godus-sta-lb-…elb.us-west-2.amazonaws.com,APIgodusapi.cans-services.com/sta - Dev/Debug:RPC
10.11.12.235,APIgodusapi.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,magice5 17 0f 00)= 自定义打包归档,未加密(内含明文 PNG/JPEG/MP3/KTX)iOS/*.pck(AKPK,含GodusMain.pck53MB)= Wwise 流式音频包,未加密,含明文 JPEG/WAVconfig.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 位哈希:
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)…
按用途分组(节选):
- 持久化/云存档/认证:
PersistForceSaveGameGetAuthValueGetNumClaimsLoggedInIsCloudUploading - 配置/数值:
Config(k[,v])GetConfigGetOverrideValueTableTableStringBalanceUnlockModifierString - UI/HUD:
EnableHUDElementShowUIClearUILockHudComponent… - 相机/输入:
SetCameraLockCameraToRegionZoomToDoCameraShake - 活动锁:
LockActivityUnlockActivity(0/1=雕刻 2=sprog 4=销毁岩石/树) - 世界读:
Belief()Gems()WheatCount()PopulationCountGetSculptLayersGetFirstFollowerInRadius… - 世界写:
BuildAbodeCastPowerSpawnFollowerKillAllFollowerInRadiusTrySetFireSetBelief… - 卡牌/解锁:
GiveCardCardOwnedUnlockStarterPackGivePowerUpgrade - 广告/IAP/社交:
LuaCallback_WatchAd_PressedTabLuaCallback_Facebook_InviteSuccess - 调试:
IsDebugIsDesktopDebugDisplayLuaStateLog
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 注册):
opRPCAuthenticateopRPCGetCurrentPlayeropRPCSetCurrentPlayerDataopRPCGetAssetopRPCGetAssetHashesopRPCPutAssetopRPCDeleteFolderopRPCGetHubDataopRPCGetFriendsopRPCSendInventoryTransactionsopRPCFinishGooglePlayPurchase。 - 服务端错误码枚举:
InvalidAuthenticationClientVersionOutdatedSessionExpiredInvalidDigestCopyInProgress等。
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/domain22cans.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 %svswe 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;KeychainGodusRPC/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 语言);AppTrackingTransparencyAPI。 - 三重同意层并存:Google UMP(GDPR/TCF)、AppLovin consent flow(Terms/Privacy±ATT 的
ALConsentFlow*.json)、Apple ATT(IDFA)。 - 每个 SDK 的
NSPrivacyTrackingDomains全为空;App 根无自有PrivacyInfo.xcprivacy。 - 仅 GMA 清单声明真实 tracking(
DeviceIDtracking=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嵌入运行时loadOK(本机无 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、
pygltflib361(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、PhotonTPeer/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"——客户端安全较弱。砸壳版已验证为真解密、功能等价。