RE&SEC · Research Notes
Mobile Security · Reverse Engineering

无尽冬日 (Whiteout Survival CN) iOS 逆向安全分析报告

一次针对 Unity/IL2CPP 手游的离线静态逆向:破解元数据周期异或、定位资源包与加密 Lua 业务逻辑,并剖析其反篡改与供应链暴露面。

发布 2026-10-12 目标 com.gof.china · 1.15.6 iOSUnity / IL2CPP NetEase 易盾离线静态分析 约 91 分钟阅读
目录

01 · 概述与目标#

目标样本:com.gof.china_1.15.6_und3fined.ipa 分析对象:Payload/whiteoutsurvivalcn.app(已脱壳 / decrypted) 报告版本:v1.0 分析性质:授权安全研究 / 移动应用安全评估(见文末免责声明)


0. 报告导读(TL;DR)#

目标
无尽冬日(Whiteout Survival 国服),Century Games / 点点互动,com.gof.china 1.15.6 (build 135)
引擎
Unity 2022.3.52f1 + IL2CPP(含 XXLua/LuaInterface 脚本层)
加壳
样本已脱壳(FairPlay cryptid=0),Payload/decrypt.day = "und3fined"
关键发现 1
global-metadata.dat 使用 固定 17 字节周期密钥 NTESCSLLVMPASSKEY 做整文件 XOR 加密,已成功还原(version=31, 8511 个类型、19294 条字符串字面量全部可读);密钥前缀 NTES + 元数据中的 NetEase.NetSecProtect 符号,指向 网易易盾 NetSec 加固
关键发现 2
AssetBundle 目录(blocksInfo/CAB- 名)明文可读,但压缩块数据被加密(flags=0x0243 含 kArchiveUsesAssetBundleEncryption;实测 UnityPy 仅在块数据解压处失败),疑似逐包密钥 XOR(CalcEncryptKeyFromString/BundleEncryptOffset)
关键发现 3
游戏业务逻辑位于加密的 Lua 字节码包(luapackage_32/64、toluaout_32/64_*.unity3d,各 ~20MB),运行时由 Helper.DecryptLuaBytecode 解密执行 → 跳过首个加密块后已还原 53MB Lua 逻辑文本
关键发现 4
自带反调试 / 越狱检测 / 资源完整性校验(网易易盾 AntiCheatResult、isJailbreak、isDebuggerAttached、SC_DATA_TAMPERED)
关键发现 5
通知扩展 CGPushServerExtension 声明 NSAllowsArbitraryLoads=true(明文 HTTP 放行)
关键发现 6
生产包内残留构建/内网发布脚本(含内部 Bitbucket 仓库与私有 Pod 源 oauth2: 引用),构成供应链信息泄露
关键发现 7
大量第三方 SDK 与追踪能力(Adjust、ThinkingData、BDASignal、字节 UnionOpenPlatform、腾讯 CrashSight、微信/抖音),隐私与合规面较大
总体风险
中高:加固以"符号/元数据模糊 + 周期 XOR + Lua 字节码加密"为主,均为可离线还原的越权前防护;未见证书固定(pinning),敏感配置以可逆编码硬编码于包内

1. 目标标识(Host Identification)#

项 值
IPA 文件名 com.gof.china_1.15.6_und3fined.ipa
IPA 大小 / SHA-256 754,433,203 B (721 MiB) / 1e64c47197def718e28f5ed0acd4aeba03bcfe497bf6b3284ff086d060a8b3aa
显示名称 无尽冬日(CFBundleDisplayName)
Bundle ID com.gof.china
版本 / 构建号 1.15.6 / 135
应用目录 Payload/whiteoutsurvivalcn.app
最低系统 iOS 12.0(MinimumOSVersion)
构建 SDK iphoneos 26.1(Xcode 26.1 / DTXcodeBuild 17B100)
签名团队 Team ID HM5Y58WVBP,application-identifier = HM5Y58WVBP.com.gof.china
引擎 Unity 2022.3.52f1(game_res_mark 头 "UnityFS … 2022.3.52f1")
脚本后端 IL2CPP(Data/Managed/Metadata/global-metadata.dat 存在)
自研 SDK dd_sdk_unity_version = 8.0.5.0-GOFCN-1(Century Games 自研 SDK)
主可执行文件 whiteoutsurvivalcn(arm64, 138,720 B, SHA-256 e90956ef…62336)
Unity 主库 Frameworks/UnityFramework.framework/UnityFramework(arm64, 77,587,120 B, SHA-256 d7262bd5…a93658)

说明:Payload/decrypt.day 内容为 und3fined,配合脱壳工具使用;主二进制与 UnityFramework 的 LC_ENCRYPTION_INFO_64.cryptid 均为 0,即代码段已解密,可直接进行静态分析。


2. 包结构总览#

脱壳后的 whiteoutsurvivalcn.app 共 6,218 个文件 / 约 901 MB(含分析过程中生成的中间文件)。

whiteoutsurvivalcn.app/
├── whiteoutsurvivalcn                    主二进制 (arm64, 138 KB, 仅做 Unity/SDK 引导)
├── Info.plist                            应用配置(权限/URL Scheme/ATS 等)
├── PrivacyInfo.xcprivacy                 隐私清单
├── ddCommon.json                         ★ 自研 SDK 配置(含可逆编码的密钥/密钥串)
├── UOPSDKConfig.json                     字节 UnionOpenPlatform 配置(app_id 789841)
├── Assets.car                            2.3 MB(App 图标等资源)
├── CenturyGameResources.bundle/          自研 SDK 资源(含 merge 脚本、mopub SKAdNetwork 清单)
├── CenturyGameiOSAccount/Payment/…        自研 SDK 各功能 bundle
├── CGSQRCode.bundle / CenturyGameSmartHelpRes.bundle
├── Frameworks/                           100 MB,15 个内嵌框架 + 12 个 Swift 运行库 dylib
│   ├── UnityFramework.framework/         ★ Unity 引擎 + IL2CPP + 游戏原生代码
│   ├── AdjustSdk / AdjustSigSdk          Adjust 归因
│   ├── ThinkingSDK / ThinkingDataCore    数数 ThinkingData 埋点
│   ├── BDASignalSDK                      字节信号 SDK
│   ├── CrashSight* (Core/Adapter/Plugin) 腾讯 CrashSight 崩溃捕获
│   ├── UnionOpenPlatform*                字节抖音开放平台(登录/分享/归因)
│   ├── AFNetworking / Protobuf           网络 / 序列化
│   ├── FirebaseNIMessInstallation        Firebase 安装归因
│   └── libswift*.dylib                    Swift 运行库
├── PlugIns/CGPushServerExtension.appex/  ★ 通知服务扩展(NSAllowsArbitraryLoads=true)
├── Data/
│   ├── Managed/Metadata/global-metadata.dat  ★ IL2CPP 元数据(XOR 加密)
│   ├── Raw/data/                         715 MB,5,316 个资源包子目录/文件(含 luapackage_32/64)
│   ├── Raw/sound/                        CriWare .acb 音频
│   ├── Raw/world/                        世界地图 .bytes 配置
│   └── (globalgamemanagers / level0-2 / resources.assets 等)
├── SC_Info/                               FairPlay 签名信息(whiteoutsurvivalcn.sinf 等)
├── install/                              ★ 残留构建脚本(buildIpa.sh / autoUpdateRepoPublic.sh)
└── _CodeSignature/CodeSignature

3. 分析方法与工具链#

阶段 方法 / 工具 产出
解包 unzip(IPA 为 store 压缩) 完整 app 目录
加壳确认 otool -l(LC_ENCRYPTION_INFO_64) cryptid=0,已脱壳
架构 file / lipo / otool -h arm64 单架构,MH_PIE
静态串 strings / nm / otool -L / dyld_info SDK、反调试、网络端点线索
配置 plutil / codesign -d --entitlements / Python JSON 权限、entitlements、密钥配置
IL2CPP 还原 自研 Python 解析器(自相关求密钥周期 → 众数恢复密钥 → 结构解析) 类型 8,511 / 字符串字面量 19,294 / 标识符 88,084
资源格式 十六进制头分析 + 元数据方法名交叉验证 资源包 XOR 加密结论

关键突破点:global-metadata.dat 的周期 XOR。详见第 6 章与附录脚本 artifacts/decrypt_global_metadata.py。


4. 报告结构#

章节 内容 文件
01 概述、目标标识、包结构与总体结论 本文件
02 第三方 SDK 清单、权限与隐私分析 report/02_sdk_privacy.md
03 Unity 资源、资源包加密与内容分析 report/03_unity_assets.md
04 二进制结构与反篡改 / 反调试机制 report/04_binary_antitamper.md
05 网络端点、配置与硬编码密钥 report/05_network_secrets.md
06 IL2CPP 元数据加密还原(核心技术章节) report/06_il2cpp_metadata.md
07 风险汇总、攻击面与加固建议 report/07_risk_remediation.md
08 内购 / 充值系统逆向(支付 SDK、协议、配置) report/08_iap.md
09 玩法 / 系统架构与网络协议地图 report/09_gameplay.md
10 数值 / 配表体系与属性公式 report/10_numeric.md
11 活动 / 节日运营与活动模型 report/11_events.md
附录 解密脚本与可复现命令 report/appendix.md

5. 免责声明#

本报告仅用于经授权的安全研究、兼容性评估与防御加固。所涉脱壳、元数据还原、串提取等均为离线静态分析,未对任何线上服务发起攻击、未绕过任何付费/授权,也未分发任何受版权保护的内容。请遵守当地法律法规与软件许可协议,勿将本文技术用于未授权用途。


02. 第三方 SDK 清单、权限与隐私画像#

分析对象:无尽冬日(Whiteout Survival CN) 包名(Bundle ID):com.gof.china 版本:CFBundleShortVersionString = 1.15.6(CFBundleVersion = 135) 构建工具链:Xcode 26.1(DTXcode = 2611 / DTXcodeBuild = 17B100),SDK iphoneos26.1 产物路径:extracted/Payload/whiteoutsurvivalcn.app(已解密 IPA,只读分析,未做修改) 主二进制 SHA-256:e90956ef435b67fba08ead8064778d349520179980423efc07705a9a99c62336 签名:Apple iPhone OS Application Signing,TeamIdentifier HM5Y58WVBP,Format=app bundle with Mach-O thin (arm64)

分析方法:plutil / PlistBuddy 解析各 Info.plist、codesign -d --entitlements :- 提取授权、strings 提取符号、find / grep / python3 解析资源 JSON 与隐私清单。所有版本号、标识符均逐字引自文件,未作推测;无法验证处已明确标注。


1. 嵌入式框架(Framework)完整清单#

Frameworks/ 下共有 15 个 .framework,另有 13 个 Swift 运行库动态库(libswiftCore.dylib 等,属 Unity 打包产物,非第三方 SDK)。全部版本信息读取自各框架自身的 Info.plist(CFBundleShortVersionString / CFBundleIdentifier)。

# Framework CFBundleIdentifier 版本 分类 作用与风险备注
1 UnityFramework.framework com.unity3d.framework 1.15.6 (135) 游戏引擎 Unity IL2CPP 运行时(79 MB),承载全部游戏逻辑与原生桥接;攻击面最大,需关注 UnitySendMessage 等 JSBridge 通道。
2 AdjustSdk.framework org.cocoapods.AdjustSdk 5.4.1 归因/分析 Adjust 安装与事件归因 SDK;声明 NSPrivacyTracking=true,会采集 DeviceID 用于追踪与第三方广告,是本 App 最核心的广告追踪组件。
3 AdjustSigSdk.framework com.adjust.sdk.sig 1.0 归因/分析 Adjust 签名 SDK(ADJSigner,符号 sign:withActivityKind:withSdkVersion:),对归因参数做签名校验;采集 DeviceID / 诊断数据,需联网。
4 ThinkingDataCore.framework org.cocoapods.ThinkingDataCore 1.0.2 分析 数数科技(ThinkingData)埋点内核;自身隐私清单为空,实际能力由 ThinkingSDK 承载。
5 ThinkingSDK.framework org.cocoapods.ThinkingSDK 3.0.6 分析 数数科技事件分析 SDK;采集产品交互、崩溃、性能、粗略位置(CoarseLocation)、UserID、DeviceID,用途 Analytics。
6 BDASignalSDK.framework org.cocoapods.BDASignalSDK 1.0.1 归因/分析 字节跳动 BDA Signal SDK(设备信号采集,配合 UOP 归因);访问磁盘空间、文件时间戳、UserDefaults。
7 CrashSight.framework com.cs.CrashSight 1.0 崩溃上报 腾讯 CrashSight(原 Bugly)崩溃采集主 SDK;符号含 CSCrashSightManager / CrashSightDelegate,采集崩溃、性能、DeviceID、UserID(不关联用户)。
8 CrashSightCore.framework com.uqm.CrashSightCore 1.0 崩溃上报 CrashSight 核心实现层。
9 CrashSightAdapter.framework com.uqm.CrashSightAdapter 1.0 崩溃上报 CrashSight 与宿主/Unity 的适配层。
10 CrashSightPlugin.framework com.uqm.CrashSightPlugin 1.0 崩溃上报 CrashSight Unity 插件封装。
11 UnionOpenPlatformCore.framework ByteDance.UnionOpenPlatformCore 25.0.0 广告/归因 字节跳动「融合开放平台(UOP)/ 抖音开放平台」核心,内嵌 RangersAppLog、RangersAPM、APMInsightCore、HMDEmbed 等子 bundle;唯一显式 NSPrivacyTracking=true 并列出追踪域名的框架(见 §3)。
12 UnionOpenPlatformDataLink.framework ByteDance.UnionOpenPlatformDataLink 25.0.0 广告/归因 字节 UOP 数据链路(归因/链路拉活);采集 GameplayContent、UserID。
13 AFNetworking.framework com.alamofire.AFNetworking 4.0.1 网络 通用 HTTP 网络库,被多数 Objective-C SDK 依赖;本身无独立隐私声明。
14 Protobuf.framework org.cocoapods.Protobuf 3.29.5 序列化 Google Protocol Buffers 3.29.5,用于协议编解码;隐私清单为空(无采集)。
15 FirebaseNIMessInstallation.framework com.google.FirebaseNIMessInstallation 1.0 推送 基于 Google Firebase Installations 的封装(PROJECT:FirebaseNIMessInstallation-1),为推送提供 Installation ID/FID 能力。MinimumOSVersion = 9.0。

备注:CFBundleShortVersionString 中 Adjustment/ThinkingData 等 CocoaPods 框架版本为 Pod 版本号,能对应到上游发布版本;CrashSight* 与 UnionOpenPlatform* 的版本号为 SDK 内自填(CrashSight 均为 1.0、UOP 为 25.0.0),无法从产物进一步验证其内部小版本,已如实标注。

1.1 次要/内嵌组件(由框架携带,非独立 framework 目录)

  • UnionOpenPlatformCore.framework/ 内嵌:RangersAppLog.bundle(字节 AppLog 埋点)、APMInsightCore.bundle 与 RangersAPMPrivacyInfo.bundle(字节 APM 性能监控)、HMDEmbedPrivacyInfo.bundle(火山引擎 HMD 崩溃嵌入)。
  • Unity 工程同时打包了 CenturyGameiOS* 系列 bundle:CenturyGameiOSAccount(账号)、CenturyGameiOSPayment(支付)、CenturyGameiOSReport(上报)、CenturyGameiOSTool、CenturyGameiOSWebViewBridge(WebView 桥)、CGSQRCode、CenturyGameSmartHelpRes、CenturyGameResources。均为自研/OEM 模块,其隐私清单见 §3。

2. Info.plist 权限与声明#

2.1 主 App(com.gof.china)

NS*UsageDescription(隐私用途说明)
Key 值(逐字) 评估
NSUserTrackingUsageDescription Your data will be used to deliver personalized ads to you ATT 追踪弹窗文案,配合 Adjust/UOP 归因使用。
NSPhotoLibraryUsageDescription We want to use photo for changing your avatar 相册(更换头像)。
NSCameraUsageDescription We want to use camera for changing your avatar 相机(更换头像)。
NSMicrophoneUsageDescription 我们需要使用麦克风以用于客服服务 麦克风(客服语音)。
NSCalendarsUsageDescription 我们需要使用日历以用于活动提醒 日历读取(活动提醒)。
NSCalendarsWriteOnlyAccessUsageDescription 我们需要使用日历以用于活动提醒 日历(仅写入)iOS 17+ 权限。
NSLocationWhenInUseUsageDescription empty ⚠️ 占位/未填写:声明了定位能力但文案为 empty,为明显的合规瑕疵(若真调用定位会触发审核风险;也可能仅被 SDK 声明而未实际使用)。

注意:应用仅声明了 NSLocationWhenInUseUsageDescription,未声明 NSLocationAlwaysAndWhenInUseUsageDescription,即不支持后台持续定位。

LSApplicationQueriesSchemes(可探测的第三方 App Scheme)
fb, fb-messenger, whatsapp, weixin, weixinULAPI, weixinURLParamsAPI,
douyinopensdk, douyinliteopensdk, douyinsharesdk, snssdk1128, weibosdk

覆盖 Facebook、WhatsApp、微信(weixin / weixinULAPI / weixinURLParamsAPI)、抖音(douyinopensdk 等)、微博。说明 SDK 具备跨 App 拉活/分享能力(canOpenURL 探测)。

CFBundleURLTypes(自定义 URL Scheme 注册)
CFBundleURLName Scheme 说明
centurygame com.diandian.logger.20173 点点数据/自研日志回传(20173 = 游戏 ID)。
cgsdk ddplatform-20173 CenturyGame SDK 平台回调。
bytedanceAttribution com.gof.china ⚠️ 把主 Bundle ID 本身注册为 URL Scheme,用于字节归因回跳。
weixin wx32374c9038cf9759 微信开放平台 AppID。
douyin awebivvetg90lv93 抖音开放平台 client_key。
(空 dict) — 存在一个空 URL Type(打包瑕疵)。
UIBackgroundModes
remote-notification

仅声明远程推送后台模式,未申请 location / audio / fetch 等。

其他关键键
  • NSAdvertisingAttributionReportEndpoint = "https://adjust-skadnetwork.com\u200b" —— ⚠️ 末尾含不可见零宽空格(U+200B,0x200B),共 31 字符。这不是合法可解析的目标域名,存在被系统忽略或配置失效的风险,属打包/配置瑕疵,建议修正为纯 ASCII URL。
  • UIRequiresFullScreen = true、UIRequiresPersistentWiFi = true、MinimumOSVersion = 12.0、UIDeviceFamily = [1,2](iPhone/iPad)。
  • Unity 推送相关:UnityNotificationDefaultAuthorizationOptions = 7、UnityAddRemoteNotificationCapability = false、UnityUseAPSReleaseEnvironment = false。
  • dd_sdk_environment_production = true、dd_sdk_unity_version = "8.0.5.0-GOFCN-1"(数数 SDK 生产环境)。
Entitlements(codesign -d --entitlements :- whiteoutsurvivalcn)
application-identifier            = HM5Y58WVBP.com.gof.china
aps-environment                   = production
com.apple.developer.applesignin   = [Default]
com.apple.developer.associated-domains = [
    applinks:appleunilink.campfiregames.cn,
    applinks:xfmr.adj.st
]
com.apple.developer.game-center   = true
com.apple.developer.team-identifier = HM5Y58WVBP

2.2 推送扩展 PlugIns/CGPushServerExtension.appex

二进制 Info.plist(已 plutil -convert xml1 解析):

Key 值
CFBundleIdentifier com.gof.china.20173
CFBundleShortVersionString / CFBundleVersion 1.15.6 / 135
CFBundleDisplayName NotificationServer
NSExtensionPointIdentifier com.apple.usernotifications.service
NSExtensionPrincipalClass NotificationService
NSExtension 通知服务扩展(可修改推送内容/图片)
MinimumOSVersion 10.0
UIRequiredDeviceCapabilities arm64
NSAppTransportSecurity NSAllowsArbitraryLoads = true ⚠️
无 NS*UsageDescription / UIBackgroundModes / CFBundleURLTypes —

Appex Entitlements:

application-identifier            = HM5Y58WVBP.com.gof.china.20173
com.apple.developer.team-identifier = HM5Y58WVBP

扩展本身只持有 application-identifier 与 team-id,未继承主 App 的 aps/关联域名等权益,权限相对收敛。


3. 隐私清单(PrivacyInfo.xcprivacy)汇总#

产物内共发现 22 个 PrivacyInfo.xcprivacy。以下按主 App、Appex、框架三类归纳。

3.1 主 App 隐私清单(PrivacyInfo.xcprivacy)

NSPrivacyAccessedAPITypes(Required Reason API) | 分类 | 理由码 | |------|--------| | NSPrivacyAccessedAPICategorySystemBootTime | 35F9.1 | | NSPrivacyAccessedAPICategoryDiskSpace | E174.1 | | NSPrivacyAccessedAPICategoryUserDefaults | CA92.1 | | NSPrivacyAccessedAPICategoryFileTimestamp | 0A2A.1, C617.1 |

NSPrivacyCollectedDataTypes | 数据类型 | Linked | Tracking | 用途 | |----------|--------|----------|------| | NSPrivacyCollectedDataTypeDeviceID | true | false | Analytics, Other | | NSPrivacyCollectedDataTypePhotosorVideos | true | false | AppFunctionality |

NSPrivacyTracking = false(主 App 清单自述不追踪,但与 Adjust / UOP 框架清单中 NSPrivacyTracking=true 存在聚合层面的矛盾,见 §7)。

3.2 Appex 隐私清单(CGPushServerExtension.appex/PrivacyInfo.xcprivacy)

  • NSPrivacyAccessedAPITypes:仅 NSPrivacyAccessedAPICategoryUserDefaults(CA92.1)。
  • NSPrivacyCollectedDataTypes:空。
  • NSPrivacyTracking = false,NSPrivacyTrackingDomains = []。

3.3 各框架隐私清单要点

Framework / Bundle Tracking 被声明采集的数据类型 Required Reason API
AdjustSdk(Adjust.bundle) true DeviceID(Linked,Analytics + ThirdPartyAdvertising,Tracking=true)、ProductInteraction UserDefaults(C A92.1)、FileTimestamp(C617.1)
AdjustSigSdk false OtherDiagnosticData、DeviceID —
ThinkingSDK false ProductInteraction、CrashData、PerformanceData、CoarseLocation、UserID、DeviceID UserDefaults(1C8F.1)、DiskSpace(E174.1,7D9E.1)、SystemBootTime(35F9.1)、FileTimestamp(C617.1)
ThinkingDataCore false 空 —
BDASignalSDK (未声明 keys) 空 DiskSpace(E174.1)、FileTimestamp(DDA9.1)、UserDefaults(CA92.1)
CrashSight (无 tracking 键) PerformanceData、CrashData、DeviceID、UserID UserDefaults(CA92.1)、DiskSpace(E174.1)、FileTimestamp(C617.1)、SystemBootTime(35F9.1)
UnionOpenPlatformCore true DeviceID、CrashData、PerformanceData、OtherDiagnosticData FileTimestamp(C617.1,DDA9.1)、SystemBootTime(35F9.1)、DiskSpace(E174.1)、UserDefaults(1C8F.1,CA92.1)
UnionOpenPlatformCore/RangersAPM false OtherDiagnosticData、PerformanceData、CrashData、UserID、DeviceID UserDefaults、DiskSpace、FileTimestamp、SystemBootTime
UnionOpenPlatformCore/HMDEmbed false OtherDiagnosticData、PerformanceData、CrashData、UserID、DeviceID DiskSpace、FileTimestamp
UnionOpenPlatformDataLink false GameplayContent、UserID UserDefaults(CA92.1)
Protobuf false 空 —
UnityFramework 及 CenturyGameiOS* false DeviceID、PhotosorVideos(Account 额外含 Emails/UserID;Payment 含 PurchaseHistory;Report 含 PerformanceData/OtherUsageData) SystemBootTime、DiskSpace、UserDefaults、FileTimestamp

UnionOpenPlatformCore 显式列出的追踪域名(NSPrivacyTrackingDomains):

klink-tracking.volceapplog.com
toblog-tracking.volceapplog.com
abtest-tracking.volceapplog.com
tobapplog-tracking.volceapplog.com
alink-tracking.volceapplog.com

AdjustSdk 显式列出的追踪域名:

https://consent.adjust.com   https://consent.adjust.io   https://consent.adjust.net.in
https://consent.adjust.world https://consent.adjust.cn   https://consent.eu.adjust.com
https://consent.tr.adjust.com https://consent.us.adjust.com

4. ⚠️ 关键发现:Appex 开启 ATS 任意加载,主 App 未开启#

  • 主 App(com.gof.china)没有 NSAppTransportSecurity 键(PlistBuddy Print :NSAppTransportSecurity 返回 Does Not Exist),即主 App 遵循系统默认 ATS(强制 HTTPS/TLS)。
  • 推送扩展 CGPushServerExtension.appex(com.gof.china.20173)在 Info.plist 中显式声明: xml <key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict> 即允许该扩展发起任意明文 HTTP 请求,绕过 ATS。

风险解读:这是"最小权限面"上的不一致——一个职责仅为"通知服务扩展"的组件,却拥有全 App 最宽松的网络策略。通知服务扩展运行在推送到达的后台时机,若其拉取图片/富媒体内容的 URL 可控或校验不足,则明文 HTTP 通道可被中间人(同 Wi-Fi 攻击者、恶意代理)篡改/注入。Apple 审核亦会要求 NSAllowsArbitraryLoads 提供合理说明。建议:仅对确需的白名单域名使用 NSExceptionDomains,或在扩展内强制 HTTPS,移除全局任意加载。


5. 能力(Capabilities / Entitlements)#

能力 Entitlement 值 说明
Game Center com.apple.developer.game-center true 接入苹果游戏中心(排行榜/成就)。
Sign in with Apple com.apple.developer.applesignin [Default] 支持"通过 Apple 登录",属账号体系。
关联域名 com.apple.developer.associated-domains applinks:appleunilink.campfiregames.cn、applinks:xfmr.adj.st Universal Link:前者疑为苹果生态统一链接/自有域名,后者 xfmr.adj.st 为 Adjust 短链域名,用于归因跳转。
推送环境 aps-environment production 生产 APNs,配合 remote-notification 后台模式与通知服务扩展。
团队标识 com.apple.developer.team-identifier HM5Y58WVBP 签名团队。

未发现 iCloud/KVStore、HealthKit、Wallet、App Groups 等敏感权益;未发现 group.* App Group(主 App 与 Appex 之间无共享容器声明)。


6. 广告 / 归因标识#

6.1 CenturyGameResources.bundle/mopub-sdk-id.json —— SKAdNetwork 标识列表

  • 该文件为 JSON 数组,共 154 条唯一 SKAdNetworkIdentifier(无重复),字段格式 {"SKAdNetworkIdentifier":"<id>.skadnetwork"}。
  • 前若干条示例: 22mmun2rn5.skadnetwork, 238da6jt44.skadnetwork, 24t9a8vw3c.skadnetwork, 252b5q8x7y.skadnetwork, 275upjj5gd.skadnetwork, ... 末尾:... x5l83yy675.skadnetwork, 7fmhfwg9en.skadnetwork, qu637u8glc.skadnetwork
  • 经验证的常见广告网络条目存在:cstr6suwn9.skadnetwork、f38h382jlk.skadnetwork、v9wttpbfk9.skadnetwork、n38lu8286q.skadnetwork、mtkv5xtk9e.skadnetwork、5a6flpkh64.skadnetwork、22mmun2rn5.skadnetwork 均为 True。
  • ⚠️ 重要不一致:主 App 的 Info.plist 不含 SKAdNetworkItems 键(PlistBuddy Print :SKAdNetworkItems → Does Not Exist)。SKAdNetwork 标识仅存在于资源 JSON 中。结合 CenturyGameResources.bundle/merge_infoplist.py 的逻辑(仅当 gad_appid 非空时才把 mopub_data 写入 pl['SKAdNetworkItems']),可推断本 CN 构建未把该列表合并进运行时 Info.plist——即 SKAdNetwork 归因在系统层面很可能未生效(或依赖其他注入途径)。这属于配置/构建缺陷,需人工在目标环境复核。
  • NSAdvertisingAttributionReportEndpoint 指向 https://adjust-skadnetwork.com(但末尾带 U+200B,见 §2.1)。

6.2 ddCommon.json(根目录,明文 JSON,含大量密钥/标识)

字段 值(逐字) 说明
platform.ios.wechat_app_id wx32374c9038cf9759 微信开放平台 AppID(与 CFBundleURLTypes 一致)。
platform.ios.douyin_client_key awebivvetg90lv93 抖音开放平台 client_key(与 URL Scheme 一致)。
platform.ios.bugly_id 341c16d88c 腾讯 Bugly/CrashSight iOS App ID。
platform.android.bugly_id 1ea45351f9 Android 侧 Bugly ID(同发布仓)。
platform.*.game_id 20173 游戏 ID(与 URL Scheme ddplatform-20173、com.diandian.logger.20173 一致)。
platform.android.access_id / access_key 1580019064 / AQC2K08T7CLS 腾讯 TPNS 推送 access_id/key(明文)。
platform.android.XG_SERVER_SUFFIX tpns.sh.tencent.com 腾讯移动推送服务端。
id 3281 应用/配置 ID。
helpshift / helpshift_ios 8c855fd7c4cc6b899e2c64f37ecc65b3 Helpshift 客服 SDK ID。
adjust c1540cc8f7...(长十六进制串) Adjust 归因配置(已编码/加密)。
constants / secret / tga / rum.* / smarthelp.* / umbra_gateway.* 多段长十六进制密文 服务端配置与密钥材料(生产/沙箱两套)。

风险:ddCommon.json、UOPSDKConfig.json 以明文形式随包分发(位于 .app 根),其中包含 access_key、客服 ID、部分凭据密文等;虽大部分为客户端可见配置,但结合 tga_encryption_info、secret* 等字段,值得作为"客户端硬编码密钥"专项审计对象。

6.3 UOPSDKConfig.json

{
  "app_id": "789841",
  "osdk_type": "Omnichannel_ActivityLink",
  "client_key": { "douyin_key": "" },
  "debug_mode": false
}
  • app_id = 789841 为字节开放平台应用 ID;douyin_key 在 CN 构建中为空;debug_mode = false。

7. 隐私画像总结与风险评级#

7.1 数据采集面

本 App 的第三方 SDK 组合呈现"游戏引擎 + 双归因(Adjust / 字节 UOP)+ 双分析(ThinkingData / 字节 AppLog)+ 崩溃(腾讯 CrashSight)+ 推送(Firebase Installation + 腾讯 TPNS)"的典型重度商业化矩阵:

  • 追踪类(Tracking=true):AdjustSdk(DeviceID → 第三方广告)、UnionOpenPlatformCore(DeviceID / 诊断数据,追踪域名 *-tracking.volceapplog.com)。
  • 分析类:ThinkingData(含粗略位置、ProductInteraction、UserID、DeviceID)、Unity 自研 Report(PerformanceData / OtherUsageData)。
  • 崩溃/性能类:CrashSight(CrashData / PerformanceData / DeviceID / UserID)、UOP 内嵌 RangersAPM / HMDEmbed。
  • 标识符:Adjust(含签名 ADJSigner)、字节 BDA Signal、Firebase Installation ID、微信 AppID、抖音 client_key、Bugly ID。

7.2 风险清单(按严重度)

级别 发现 依据
🔴 高 23 个框架中,聚合隐私清单与主 App 自述矛盾:主 App NSPrivacyTracking=false,但 AdjustSdk 与 UnionOpenPlatformCore 均声明 NSPrivacyTracking=true 且采集 DeviceID 用于追踪/第三方广告,并列出追踪域名。若未在 App Store Connect 正确申报"用于追踪",存在合规与审核风险。 各 PrivacyInfo.xcprivacy
🔴 高 推送扩展开启 NSAllowsArbitraryLoads=true,而主 App 未开启,网络策略不一致,扩展可在后台发起明文 HTTP。 Appex Info.plist(见 §4)
🟠 中 SKAdNetwork 列表(154 条)未合并进主 App Info.plist,归因在系统层面可能失效;同时 NSAdvertisingAttributionReportEndpoint 末尾含零宽空格(U+200B),疑似非法 URL。 mopub-sdk-id.json、Info.plist、merge_infoplist.py
🟠 中 NSLocationWhenInUseUsageDescription = "empty",声明能力但文案未填,属合规瑕疵;框架(ThinkingData)声明采集 CoarseLocation。 主 App Info.plist
🟡 低 明文敏感配置随包分发:ddCommon.json / UOPSDKConfig.json 含 access_key、bugly_id、secret*、tga_encryption_info 等(多为客户端配置,但应做密钥分离)。 根目录 JSON
🟡 低 bytedanceAttribution 将主 Bundle ID com.gof.china 注册为 URL Scheme,可能被其他 App 探测/唤起,且存在一个空 CFBundleURLTypes 条目。 主 App Info.plist
🟡 低 广泛的第三方 App Scheme 探测(FB/WhatsApp/微信/抖音/微博),跨 App 拉活能力显著。 LSApplicationQueriesSchemes
⚪ 信息 未发现 App Group / iCloud / HealthKit / Wallet 等高敏感权益;Appex 权限极简(仅 application-identifier)。 codesign entitlements

7.3 建议

  1. 统一网络策略:移除 Appex 的 NSAllowsArbitraryLoads,改用 NSExceptionDomains 白名单或强制 HTTPS。
  2. 修正 NSAdvertisingAttributionReportEndpoint 的 U+200B,并确认 SKAdNetworkItems 是否正确注入到发布版 Info.plist。
  3. 在 App Store Connect 按实际 SDK 行为申报"追踪"数据,修正主 App 与框架隐私清单的语义差异;补全 NSLocationWhenInUseUsageDescription 文案或移除该键。
  4. 抽查 Adjust / UOP 归因回传报文的 HTTPS 与签名校验;对 ddCommon.json 中疑似密钥字段做安全审计。
  5. 以 UnionOpenPlatformCore(体积最大、追踪域名最多)与 UnityFramework(攻击面最大)为优先逆向目标,核查其网络与 JSBridge 边界。

附:本报告所有标识符与版本号均来自产物文件的直接读取(plutil / PlistBuddy / codesign / strings / python3)。凡产物中无法确证的项(如 CrashSight 内部小版本、SKAdNetwork 标识对应的广告网络归属)均未臆断;相关结论以"可能/疑似"标注。


03 · Unity 资源与内容保护分析(Whiteout Survival CN / 无尽冬日)#

目标:extracted/Payload/whiteoutsurvivalcn.app(已脱壳/已解密 IPA,Bundle 版本 1.15.6 / Build 135,Bundle ID com.gof.china)。 引擎:Unity 2022.3.52f1,脚本后端:IL2CPP(arm64 Mach-O),热更:IFix + ToLua。 本文所有结论均基于对原始文件的二进制解析与实验,未修改 app 包体(临时文件写在 artifacts/)。


1. Data/ 目录布局总览#

whiteoutsurvivalcn.app/
├── whiteoutsurvivalcn              # 138,720 B  Mach-O arm64 启动器
├── Frameworks/UnityFramework.framework/UnityFramework  # IL2CPP 主体二进制
├── Data/
│   ├── boot.config                 # build-guid=2a9abc3bc9814e5498a345cecaa532da
│   ├── globalgamemanagers          # 341,444 B(明文标准序列化文件头)
│   ├── globalgamemanagers.assets   # 686,836 B
│   ├── resources.assets            # 2,340,004 B(明文)
│   ├── level0 / level1 / level2    # 场景(明文)+ *.resS 流数据
│   ├── sharedassets0/1/2.assets
│   ├── unity default resources     # 695,864 B
│   ├── ScriptingAssemblies.json    # 125 个程序集清单
│   ├── RuntimeInitializeOnLoads.json
│   ├── Managed/
│   │   ├── Metadata/global-metadata.dat   # 9,902,340 B(加密,见 §2)
│   │   ├── Resources/mscorlib.dll-resources.dat
│   │   └── mono/4.0/machine.config        # 仅 33,598 B(无托管 DLL)
│   ├── Resources/unity_builtin_extra      # 425,220 B
│   └── Raw/
│       ├── data/   # 5,316 个 .unity3d AssetBundle,合计 715 MB
│       ├── world/  # 4 个 .bytes 自定义二进制配置(非 UnityFS,见 §5)
│       ├── sound/  # 36 个 CriWare .acb/.awb/.acf(39 MB,见 §7)
│       └── game_res_mark           # 3,546 B(本身也是一个 UnityFS Bundle)
  • Data/Managed/ 下没有任何托管 DLL,只有 Metadata/global-metadata.dat 与 mono/4.0/machine.config → 确认为 IL2CPP 全 AOT 编译;业务 C# 代码已编入 Frameworks/UnityFramework.framework/UnityFramework(Mach-O arm64)。
  • Data/Raw/* 是随包分发的 StreamingAssets 预置资源(首发资源),其余通过 AssetDataInfo.GetUrl 从 CDN 增量下载。

Unity 版本证据

$ xxd -l 48 Data/globalgamemanagers
00000000: 0000 0000 0000 0000 0000 0016 0000 0000
00000010: 0000 0000 0000 045c 0000 0000 0005 35c4
00000020: 0000 0000 0000 0490 0000 0000 0000 0000
00000030: 3230 3232 2e33 2e35 3266 3100 0900 0000  2022.3.52f1.....
$ strings -a Data/globalgamemanagers | grep -E "^20[0-9][0-9]\.[0-9]"
2022.3.52f1

globalgamemanagers、resources.assets、level0、sharedassets*、unity_builtin_extra 全部为明文标准 Unity 序列化文件(文件头 <metadataSize><fileSize><version=0x16=22>... + 版本串 2022.3.52f1),可被 AssetStudio / UnityPy 直接读取、未加密。

ScriptingAssemblies.json(共 125 项)

前 63 项为 UnityEngine.* 模块;其余 62 项为游戏/第三方程序集,关键项:

类别 程序集
游戏框架 Assembly-CSharp.dll, Assembly-CSharp-firstpass.dll
自研框架 CenturyGame.GameFramework.dll, CenturyGame.ShaderFramework.ShaderLibrary.dll, CenturyGame.ShaderLibrary.Builtin.dll
热更(IFix) IFix.Core.dll, Debugger.dll
Lua 生态 (Lua 虚拟机在原生层,*.Wrap 绑定见 metadata)
CriWare 音频 CriMw.CriWare.Runtime.dll
数数/抖音 SDK Unity.dd.sdk.scripts.core/account/accountcn/payment/rate/push/adjust/wechat/tga/bugly/reyun/wjx/smartHelp/tools/advertising/report/helpshift.dll(+ 各 .demo.dll)
其它 spine-unity.dll, OdinSerializer.dll, com.Tivadar.Best.HTTP.dll, Unity.AI.Navigation.dll, Unity.Notifications.Unified/iOS.dll, HdgRemoteDebugRuntime.dll(远程调试!), CString.dll, PathCreator.dll, Unity.ScriptableBuildPipeline.dll

RuntimeInitializeOnLoads.json

SRDebugger.AutoInitialize.OnLoadBeforeScene / OnLoad   (Assembly-CSharp)
com.Tivadar.Best.HTTP $BurstDirectCallInitializer
OdinSerializer ...
Unity.MemoryProfiler.MetadataInjector

即游戏内自带 SRDebugger 调试面板 与 HdgRemoteDebugRuntime 远程调试运行时,逆向时可用作入口线索。


2. global-metadata.dat 加密(IL2CPP 元数据保护)#

  • 文件大小 9,902,340 B,Data/Managed/Metadata/ 下打包态即为密文;密文头为 E1 4F F4 A9(明文魔数应为 AF 1B B1 FA = IL2CPP Metadata v31)。
  • 加密方案(由本项目 artifacts/decrypt_global_metadata.py 验证):整文件 17 字节循环 XOR,密钥

KEY = b"NTESCSLLVMPASSKEY" # 17 字节("NTESCSLLVMPASSKEY") 解密后魔数 0xFAB11BAF 校验通过,version = 31,字符串表完全可读 → 已成功还原出 out_identifiers.txt(2.1 MB) / out_literals.txt(567 KB) / out_types.txt(278 KB)。 - 采用 17 字节周期使密文呈现约 73% 可打印字符,属于伪装式周期 XOR,并非强加密;但由于游戏另有 Enable_Encrypt_NHP(网易易盾 NetEase 安全通信) 与 IFix 热更,说明官方安全重心在运行期而非静态资源。


3. AssetBundle 容器格式:明文 UnityFS(关键发现)#

对 Data/Raw/data 中全部 5,316 个 .unity3d 扫描:

$ cd Data/Raw/data && grep -l "UnityFS" *.unity3d | wc -l
5316            # 5316/5316 全部以明文 "UnityFS" 开头

容器头是明文且完全合法,例如 config_login_logo_01381e8462c1673211ae1bda35252d09.unity3d:

00000000: 556e 6974 7946 5300 0000 0008 352e 782e  UnityFS.....5.x.
00000010: 7800 3230 3232 2e33 2e35 3266 3100 0000  x.2022.3.52f1...
00000020: 0000 0000 05f6 0000 0041 0000 005b 0000  .........A...[..
00000030: 0243 0000 0000 0000 0000 0000 0000 0000  .C..............
00000040: 1e00 0100 b201 0000 0ec8 0000 0566 0003  .............f..
00000050: 0e00 0801 0000 1a00 f018 0004 4341 422d  ............CAB-
00000060: 3566 6561 3936 3935 3663 3437 6534 3766  5fea96956c47e47f
00000070: 6235 3333 3561 3435 6530 3531 3437 3462  b5335a45e051474b
00000080: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000090: 1600 0100 1616 0b00 220d 0d08 0023 0ec8  ........"....#..

字段解析(大端):signature="UnityFS",fileVersion=8,unityVersion="5.x.x",unityRevision="2022.3.52f1",size=0x5f6=1526,blocksInfoCompressed=0x41=65,blocksInfoUncompressed=0x5b=91,flags=0x0243。

  • flags & 0x3F = 3 → 块压缩算法 LZ4HC;
  • flags & 0x200 → BlockInfoNeedPaddingAtStart(2022.1.1+ 语义),因此 header 之后按 16 字节对齐到 0x40 才是 blocksInfo;
  • blocksInfo 可正常解压且为明文,完整读出目录信息(CAB 名、节点偏移/大小)。以自研解析器(artifacts/parse2.py)验证:
FILE config_login_logo_...unity3d (1526B)
  header: ver=8 engine=5.x.x player=2022.3.52f1 size=1526 ci=65 ui=91 flags=0x00000243
  blocksInfo decompressed OK: 91B (declared 91)
  uncompressedDataHash=00000000000000000000000000000000 blocks=1
    block[0] uncompressed=3784 compressed=1382 flags=0x0003
  nodes=1
    node[0] offset=0 size=3784 flags=0x00000004 path='CAB-5fea96956c47e47fb5335a45e051474b'

注意:uncompressedDataHash 恒为 全 0(正常 Unity 应为内容哈希),疑似打包工具抹除。

3.1 加密位置:仅首个压缩块被加密

关键证据:UnityPy 1.25.2 打开上述包时抛异常,但其 traceback 精确指向 block data 解压(BundleFile.py:174-175 → CompressionHelper.decompress_lz4),而非 blocksInfo 解压(BundleFile.py:141):

File "UnityPy/files/BundleFile.py", line 49, in __init__
    m_DirectoryInfo, blocksReader = self.read_fs(reader)
File "UnityPy/files/BundleFile.py", line 174, in read_fs
    b"".join(
File "UnityPy/files/BundleFile.py", line 175, in <genexpr>
    self.decompress_data(
File "UnityPy/helpers/CompressionHelper.py", line 94, in decompress_lz4
    return lz4.block.decompress(data, uncompressed_size)
_block.LZ4BlockError: Decompression failed: corrupt input or insufficient space in destination buffer.

对 Data/Raw/data 随机 300 个包逐块尝试标准 LZ4HC 解压(artifacts/batch.py):

total analyzed: 300
bundles where ALL blocks decompress : 0
bundles where NO block decompresses  : 145     # 单块包 → 整包无法解
bundles where block[0] fails         : 300     <a id="num"></a>

# 100% 命中
per block-index [ok,fail] (first 8):
   block[0]: ok=0   fail=300
   block[1]: ok=155 fail=0
   block[2]: ok=74  fail=0
   block[3]: ok=46  fail=1   (唯一 1 例抖动)
   block[4..7]: 全部 ok

结论明确:

  1. 容器 + blocksInfo(含目录/CAB 名)是明文可读的;
  2. 每个 Bundle 的第一个数据块(block[0])被加密/加扰,第 2 块起为标准 LZ4HC 明文;
  3. 单块包(145/300)因此整体不能被 UnityPy/AssetStudio 解析 —— 这正是"反提取"目的:block[0] 通常承载 Unity 序列化文件的文件头 + 类型树 + 对象表,破坏它即可让整包无法解析。

对 GPU 士兵包的直接证据(artifacts/parse2.py):

block[0] uncompressed=131072 compressed=80594 flags=0x0003  -> DECRYPT/COMPRESS FAIL
block[1] uncompressed=14456  compressed=13563 flags=0x0003  -> LZ4 OK -> 14456B

3.2 加密方案推断(与 metadata 符号吻合)

解密后的 IL2CPP 元数据包含如下自研符号,与上述现象一一对应:

CenturyGame.GameFramework.Helper-CalcEncryptKeyFromString0
CenturyGame.GameFramework.Helper-EncryptXOR0 / EncryptXOR1 / EncryptXOR2
CenturyGame.GameFramework.Helper-CheckLuaBytecodeHeader0
CenturyGame.GameFramework.Helper-EncryptLuaBytecode0 / DecryptLuaBytecode0
CenturyGame.GameFramework.AssetDataInfo-get_BundleEncryptOffset0
CenturyGame.GameFramework.AssetDataInfo-CalcOffsetFromString0
CenturyGame.GameFramework.AssetDataInfo-CheckFlag0 / CheckFlags0 / HasMark0 / GetUrl0
类型: AssetDataInfo / AssetBundleMgr / AssetLoader / BundleAssetLoader / BundleLoader
      AssetBundleContentData / AssetBundleData / AssetBundleCache / AssetBundleDownloadHandler

推断的保护设计:

  • AssetDataInfo.BundleEncryptOffset + CalcOffsetFromString(...):由资源名/URL 字符串派生一个加密偏移,用于定位加密区间的起点/长度;
  • Helper.CalcEncryptKeyFromString(...) + EncryptXOR/1/2:由字符串派生 XOR 密钥,对 Bundle 的首块做异或加扰(三种变体可能对应不同资源分组/版本);
  • 因此这是自研 XOR 块级加密,而非 Unity 官方的 Unity CN 加密(后者 flags 应为 0x400/0x1400 并带 16+16+16+16 字节的 AES-ECB 派生密钥头;本包 flags 仅 0x0243,不含该位,UnityPy 亦未走 ArchiveStorageDecryptor 分支)。

密钥破解尝试(未成功,作为证据):

尝试 结果
单字节 XOR 全暴力(0x00–0xFF,12 个包) 全部 NO
2 字节循环 XOR 暴力 未命中(耗时过高未跑完)
复用元数据密钥 NTESCSLLVMPASSKEY 未命中
复用 CAB-<hash> / 文件名 / IFix / CenturyGame 等固定串 未命中

→ 表明密钥按资源串逐包派生(CalcEncryptKeyFromString),并非全局固定密钥,强度高于元数据的周期 XOR。

旁证(决定"是首块还是定长前缀"):在 300 采样中,只要包有 ≥2 块,block[1] 永不解压失败,且多块包中 block[0] 的压缩块最小为 14,573 B(art_effect_ui_material_common_depend_...)。这说明被加密区间与块边界对齐(即恰好第一个数据块),而不是"固定前 N 字节"式的连续前缀。


4. 内容清单(Data/Raw/data,5,316 个 .unity3d,715 MB)#

4.1 目录分类(按文件名首两段统计)

分类 数量 说明
ui_panel / ui_panelitem / ui_single 2,403 + 82 + 20 UI 面板 Prefab/贴图
scene_battle 687 战斗场景、特效、GPU 士兵
scene_city 559 城市/建筑/地表动画
art_effect 326 通用特效
art_actor 245(另 art_actorrig 28) 角色骨骼/3D
actor_battle 133 战斗角色(英雄红/蓝方、士兵)
art_spine / spine_ui / spine_build 126 + 125 + 6 Spine 2D 立绘/动画
atlas_ui / atlas_fx / atlas_world 88 + 78 + 12 图集
scene_world 68 大地图(SLG)
scene_refinescience / scene_towerdefence / scene_brawlwar / scene_starvip / scene_soldier 55 / 38 / 6 / 9 / 7 各玩法场景
actor_hero / scene_hero 22 + 5 英雄展示
config_* 14 配置映射(config_atlas_mapping、config_sound_mapping 等)
mat_*、shader、3party_spine_runtime、scenes_depend 少量 材质/着色器/依赖
luapackage_32/64、toluaout_32/64、unity_mono_scripts 5 Lua 业务逻辑与脚本入口(见 4.3)

4.2 代表性文件名(30 个)

actor_animation2d_spritemesh_c126e0fbcea5a30f011a656c1665e773.unity3d
actor_battle_battle_hero_eleonora_1155d29d82b0406c0625f9ba3d610f60.unity3d
actor_battle_battle_hero_judge_red_7447a4cf3744a4a21effe75c5dc0c7c6.unity3d
actor_battle_battle_hero_smith_a07b5a03fa060d11124feb28bc2c2c92.unity3d
actor_battle_battle_gpu_soldier_archer_blue_59ffd7348be8d3ebba087fdabed91a1e.unity3d
art_actor_hero_3d_hero_builder_anim_battle_depend_7fc535c5b4879c6c971473d337c9a61d.unity3d
art_actor_hero_3d_hero_exhibit_dominic_depend_b8d8eb14a94fb164f843b5ee478446b9.unity3d
art_actor_hero_3d_hero_exhibit_wu_ming_depend_605881138cd32d24ad58875a2817215e.unity3d
art_scene_city_build_building_pier_3d_city_anim_building_pier_01_anim_depend_0aead504dd44c057a955cc5b3ccd1959.unity3d
atlas_ui_common_94c4c36d820b45c2f28ae821bcf160ba.unity3d
atlas_ui_login_846c36fdcdbce8aa97db8d45552abdf8.unity3d
config_atlas_mapping_b583fdbab488a1bb0176a8313d68841f.unity3d
scene_battle_effect_beastmaster_fx_hero_beastmaster_attack_hit_ec6357f4237d0bd48167c3425dcd9a2f.unity3d
scene_battle_effect_captain_fx_hero_captain_skillxp_xuli_550c5fa82e69c4f07f0201128aaf7bec.unity3d
scene_battle_effect_gisela_fx_hero_gisela_xp_smoke_v_r_fml_4bb6fc594479503db3d34878adf0f637.unity3d
scene_battle_effect_hector_fx_hero_hector_skill_xp_lod_870ab33a2eafb0a7ae067405b8f6bf66.unity3d
scene_battle_effect_ligeia_fx_hero_ligeia_xpskill_boom_yly_b97d6eac9f0e551c89bee7049ce5e02d.unity3d
scene_battle_effect_molly_fx_hero_molly_skill01_hit_b85d1a4489364a3580e132b98cb65a1f.unity3d
scene_battle_effect_seo_yoon_fx_hero_yoon_xp_buff_lod_27b4cbad785323920cfc644edfaaae74.unity3d
scene_city_building_accessory_city_building_upgradeboard_05_d7fb61199c55186112e8103d4b9c8e1a.unity3d
scene_city_building_city_anim_building_fishing_ice_cave_01_4a7b46389f44c9f30fc310bc40722fda.unity3d
scene_city_building_city_building_furnace_02_50c336f062e3282411d3845d24898564.unity3d
spine_ui_puzzlesystem_cardenvelope01_anim_49db00cbd100bd2e4cfc6fc2840364ee.unity3d
ui_panel_capitalwar_capitalwarpersonalinfopanel_c6adc61f8bb7cdfc298d3dd282d45fc1.unity3d
ui_panel_hero_effect_fxui_recruit_chouka_front_purple_jxm_f693b4b130eee6de56a866cc8135481d.unity3d
ui_panel_worldscene_worldmapnestnamepanel_6ff410282a7ccf7c6fb6184928575982.unity3d
ui_panel_soldier_fxui_soldie_pikeman12_jianying_wwj_54b9b4cdb86460ea26088cd66ba22456.unity3d
ui_panel_dress_dresspreviewpanel_d2bb496996770a4afd952c4e6e5400d0.unity3d
luapackage_32_974121449b64808d202866a5fe28f953.unity3d

4.3 Lua / 业务逻辑 Bundle(重要)

包名中含 lua / tolua 的共 9 个(真正承载逻辑的 5 个):

luapackage_32_974121449b64808d202866a5fe28f953.unity3d   (20,161,980 B)
luapackage_64_743799ffbb0b96aabfb80d262995bb74.unity3d   (20,194,704 B)
toluaout_32_760a415d51765d7d69bbfa7db9e1af14.unity3d
toluaout_64_c52eccf42487f8303f69a2d41c5aba16.unity3d
unity_mono_scripts_8b2eb1dcfa8c5ba7bd0c39f4d6257e85.unity3d
  • 采用 ToLua(luapackage + toluaout + metadata 中大量 *Wrap 绑定,如 UnityEngine_AssetBundleWrap、CriWare_CriAtomListenerWrap)→ 大部分界面/玩法业务逻辑用 Lua 编写,以 TextAsset 形式打进 AssetBundle。
  • luapackage_32 结构(artifacts/parse2.py):blocks=406,每块 uncompressed=131072(128 KB),path='CAB-c6d925562e3180c1714285c203e48d85'。
  • 由于仅 block[0] 被加密,我们跳过首块、解出其余 405 块(53,046,432 B),可见大量 Lua 视图/逻辑字符串:
$ strings -a luapackage_32_*.partial.bin | grep -icE "function|local |return|require|tolua"
5310
$ strings -a luapackage_32_*.partial.bin | head
-DumpSaveData: value is function, path=%s
game_module_ui_view_findinggame_FindingGameReturnEnergyTipView
TipViewBaseNew GUIBase#FindingGameReturnEnergyTipView
...

→ 证实 游戏业务逻辑确实在加密 Lua Bundle 内。此外 Helper.CheckLuaBytecodeHeader / EncryptLuaBytecode / DecryptLuaBytecode 表明 Lua 字节码/源码额外做了一层加密(luapackage 首块被 XOR 保护,字节码本身可能再被 EncryptLuaBytecode 处理)。


5. Data/Raw/world/*.bytes(自定义二进制,非 AssetBundle)#

4 个文件均不是 UnityFS:

map_world_config_item_72ad90ca83f877f34cc2e16af679c906.bytes     32,942 B
map_world_config_mask_6d8d1979ff02460f3df6faf566a7a01c.bytes     720,004 B
map_world_config_setting_29d541c1d26eff676e2d02b24932a7d7.bytes      248 B
map_world_config_terrain_5199904f17161e093854c3716634bcd2.bytes  526,137 B

setting 头部 hexdump:

00000000: 0100 0000 b004 0000 0000 4040 0000 a043  ..........@@...C
00000010: 0000 803f 0000 8c42 cdcc 4c3f 6666 a63f  ...?...B..L?ff.?
00000020: 2ba7 0540 a283 2140 a283 e13f 6795 1340  +..@..!@...?g..@

item 头部:0100 0000 7600 0000 0356 0000 0d56 0000 ...(0x01 版本 + 计数 + 递增索引)。

  • 这些是世界地图(SLG 大世界)配置,采用自研紧凑二进制 + IEEE-754 小端浮点;可能经 EncryptXOR 变体处理(首字节版本标记 0x01 保留,其余为数值)。与 AssetBundle 是两套不同的存储/加密路径(Data/Raw/world vs Data/Raw/data)。

6. 音频:CriWare(CRI ADX2 / AFS2)#

Data/Raw/sound/ 共 36 个文件,39 MB,全部为 CriWare(CRIWARE)中间件 容器:

$ xxd -l 16 acf_GOF_CRI_...acf       # ACF 全局配置
00000000: 4055 5446 0000 3e58 0001 0158 0000 029a  @UTF..>X...X....
$ xxd -l 16 acb_sound_login_...acb   # ACB
00000000: 4055 5446 0009 2d58 0001 01f8 0000 03af  @UTF..-X........
$ xxd -l 16 awb_music_guide_...awb   # AWB
00000000: 4146 5332 0204 0200 0500 0000 2000 0000  AFS2........ ...
  • @UTF = CriWare ACB UTF 表(ACB Format/PC Ver.1.37.1 Build:);AFS2 = AWB 音频流容器。
  • 元数据确认存在 CriWare.CriFsLoadAssetBundleRequest、CriWare_CriAtomListenerWrap、CriWare_CriMonoBehaviourWrap,以及 CriMw.CriWare.Runtime.dll → 使用 CRI Atom / ADX2,音频自带 CRI 加密密钥体系(ACB Header 中的 Crypt 字段 + AWB Key;解密需 CriWareDecrypter/acb2wav + 对应 key)。
  • 语音/节日资源可见:acb_zh_voice_story_local_*、acb_zh_voice_heroexhibit_local_*、acb_music_loading_holiday_dragonboat2026_*、acb_music_loading_holiday_midautumn2026_*、acb_music_loading_holiday_worldcup2026_*、acb_sound_battle_*、acb_sound_slg_* 等。

注意:CriWare 的加密是独立于 Unity 资源加密的第二套保护,即使解密了 Bundle,音频仍需 CRI key 才能还原。


7. 结论与保护强度评估#

层面 保护方式 实际强度
C# 逻辑 IL2CPP AOT + global-metadata.dat 17 字节循环 XOR 弱(周期 XOR 易解,已还原全部符号)
程序集 无托管 DLL 随包;IFix 热更 中(需动态抓取 IFix patch)
AssetBundle 明文 UnityFS + 仅首块自研 XOR 加密(CalcEncryptKeyFromString + BundleEncryptOffset) 中:容器/目录明文,只要破解首块密钥即可 100% 还原资源
Lua 业务逻辑 ToLua luapackage/toluaout + 首块 XOR + EncryptLuaBytecode 中:逻辑集中在这 5 个包,是逆向重点
世界地图配置 自研二进制(Data/Raw/world/*.bytes) 中(需逆格式)
音频 CriWare ADX2 + CRI key 中(独立密钥)
运行期 网易易盾 Enable_Encrypt_NHP / NetEase_* 安全通信、SRDebugger、HdgRemoteDebugRuntime 运行时网络加密,静态无关

逆向利用路径(建议): 1. 元数据已解 → 从 out_identifiers.txt 定位 Helper.EncryptXOR0/1/2、CalcEncryptKeyFromString、AssetDataInfo.CalcOffsetFromString,在 UnityFramework 中定位实现以还原首块密钥算法; 2. 解出首块后,把每个 .unity3d 的 block[0] 还原为标准 LZ4HC 流,即可用 UnityPy/AssetStudio 全量导出贴图、Spine、Prefab、Shader; 3. 针对 luapackage_32/64,反编译 Lua 字节码(注意 DecryptLuaBytecode/CheckLuaBytecodeHeader 的二次加密)以获取业务逻辑; 4. 音频使用 CriWare 对应 key 解密 ACB/AWB。


附:本次分析复现脚本(均位于 artifacts/)

脚本 用途
decrypt_global_metadata.py 还原 global-metadata.dat(17 字节 XOR)
parse_unityfs.py / parse2.py UnityFS 头 + blocksInfo + 逐块解压解析
unitypy_test.py UnityPy 加载复现失败(失败证据)
batch.py 300 包逐块成功率统计(block[0] 全失败)
crack.py / keytest.py 单/双字节 XOR 与候选密钥爆破(均未命中)
dump_blocks.py 跳过首块、导出其余块内容(Lua 逻辑取证)

04 - 二进制结构、运行时保护与反篡改分析#

目标:Whiteout Survival CN / 无尽冬日(com.gof.china,版本 1.15.6),已解密 IPA(com.gof.china_1.15.6_und3fined.ipa)。 App 包路径:extracted/Payload/whiteoutsurvivalcn.app 分析日期:2026-10-12 | 平台:macOS (darwin),工具链:file / otool / lipo / nm / strings / plutil 本次分析仅做只读检查,未修改 App 包内任何文件。


0. 二进制清单与总体结构#

0.1 三主二进制概况

| 二进制 | 相对路径 | 大小 | file 类型 | CPU | 文件类型 | |---|---|---|---:|---|---|---| | 主可执行文件 | whiteoutsurvivalcn | 138,720 B | Mach-O 64-bit executable | arm64 | MH_EXECUTE | | Unity 引擎库 | Frameworks/UnityFramework.framework/UnityFramework | 77,587,120 B | Mach-O 64-bit dylib | arm64 | MH_DYLIB | | 推送扩展 | PlugIns/CGPushServerExtension.appex/CGPushServerExtension | 74 KB 级 | Mach-O 64-bit executable | arm64 | MH_EXECUTE |

lipo -info 对三者均返回 Non-fat file ... architecture: arm64,即均为单架构 arm64(无 arm64e / 无 32 位 slice)。主可执行文件是一个"瘦启动器"(thin launcher,全文仅约 12 条可打印字符串),真正的游戏逻辑全部位于 UnityFramework(IL2CPP)与其元数据中。

0.2 关键 Mach-O 头信息(otool -h / otool -hv)

二进制 magic cputype ncmds sizeofcmds flags(hex) 关键 flag 解析
whiteoutsurvivalcn 0xfeedfacf 16777228 (ARM64) 30 2872 0x00200085 NOUNDEFS DYLDLINK TWOLEVEL **PIE**
UnityFramework 0xfeedfacf 16777228 (ARM64) 93 10880 0x00910085 NOUNDEFS DYLDLINK TWOLEVEL BINDS_TO_WEAK NO_REEXPORTED_DYLIBS MH_HAS_TLV_DESCRIPTORS(dylib,PIE 由加载器保证)
CGPushServerExtension 0xfeedfacf 16777228 (ARM64) 31 3592 0x00200085 NOUNDEFS DYLDLINK TWOLEVEL **PIE**

结论: - 两个可执行文件均带 MH_PIE(ASLR 已启用,0x200000 位)。 - UnityFramework 是 MH_DYLIB,无 MH_PIE 标志(dylib 本身在进程内由 dyld 随机化加载)。

0.3 加密状态 LC_ENCRYPTION_INFO_64(cryptid)

二进制 cryptoff cryptsize cryptid 含义
whiteoutsurvivalcn 81920 16384 0 已解密(__TEXT 可读)
UnityFramework 802816 68730880 0 已解密(cryptsize ≈ 全部 __TEXT)
CGPushServerExtension 16384 16384 0 已解密

三个二进制的 cryptid 均为 0,确认 IPA 已完成 App Store 加壳解密(属于 "und3fined"(越狱工具)解密产物,非原始加密 IPA)。LC_BUILD_VERSION:主二进制与 UnityFramework 均为 platform 2 (iOS)、minos 12.0、sdk 26.1。

0.4 栈保护与 ARC 证据

命令:nm -u <bin> | grep -i stack_chk,nm -u <bin> | grep -E "_objc_(retain|release|autorelease|storeStrong)"

二进制 ___stack_chk_fail / ___stack_chk_guard 数量 ARC 符号(_objc_*)
whiteoutsurvivalcn ❌ 未引用 0 部分:objc_release、objc_retainAutoreleasedReturnValue、objc_autoreleasePoolPush/Pop(Unity 启动器样板)
UnityFramework ✅ ___stack_chk_fail, ___stack_chk_guard 2 完整:objc_retain/storeStrong/storeWeak/autorelease/retainBlock 等 12 项
CGPushServerExtension ✅ ___stack_chk_fail, ___stack_chk_guard 2 完整 objc_retain/release/storeStrong 等

结论:UnityFramework 与推送扩展开启了栈溢出保护(stack canary)并使用 ARC;主可执行文件作为极简 Unity 启动器未启用 canary(无自有 C 逻辑)。此外 UnityFramework 引用了 _ptrace、_sysctl、_sysctlbyname、_fork、_forkpty、_pthread_atfork —— 这些是反调试 / 环境探测的典型依赖(详见第 3 节)。

0.5 链接的动态库(otool -L)

主可执行文件(11 项,仅 1 个 @rpath 第三方库):

/usr/lib/libz.1.dylib
/usr/lib/libsqlite3.dylib
/usr/lib/libicucore.A.dylib
/System/Library/Frameworks/SwiftUI.framework/SwiftUI          (weak)
/System/Library/Frameworks/StoreKit.framework/StoreKit
/System/Library/Frameworks/Foundation.framework/Foundation
/usr/lib/libobjc.A.dylib
/usr/lib/libc++.1.dylib
/usr/lib/libSystem.B.dylib
/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation
@rpath/FirebaseNIMessInstallation.framework/FirebaseNIMessInstallation

推送扩展 CGPushServerExtension.appex(13 项):

/System/Library/Frameworks/CFNetwork.framework/CFNetwork
/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics
/System/Library/Frameworks/CoreMedia.framework/CoreMedia
/System/Library/Frameworks/CoreMotion.framework/CoreMotion
/System/Library/Frameworks/CoreTelephony.framework/CoreTelephony
/System/Library/Frameworks/Foundation.framework/Foundation
/System/Library/Frameworks/UIKit.framework/UIKit (weak)
/System/Library/Frameworks/AdSupport.framework/AdSupport
/System/Library/Frameworks/UserNotifications.framework/UserNotifications
/System/Library/Frameworks/UserNotificationsUI.framework/UserNotificationsUI
/usr/lib/libobjc.A.dylib
/usr/lib/libSystem.B.dylib
/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation

LC_RPATH(主二进制):/usr/lib/swift、@executable_path/Frameworks、@loader_path/Frameworks。 LC_LOAD_DYLIB @rpath 第三方框架(全部位于 UnityFramework):AFNetworking、AdjustSdk、AdjustSigSdk、BDASignalSDK、Protobuf、ThinkingDataCore、ThinkingSDK、UnionOpenPlatformCore、UnionOpenPlatformDataLink、CrashSightPlugin、CrashSightAdapter、CrashSightCore、CrashSight、FirebaseNIMessInstallation 以及 libswift*.dylib 系列。


1. UnityFramework 链接的系统框架(otool -L 全量)与隐私/权限映射#

UnityFramework 共链接 77 个 dylib/framework(otool -L "$UF" | tail -n +2 | wc -l → 77)。以下按隐私/能力域归类(全部为系统框架,第三方见第 7 节):

归类 框架 隐私 / 权限含义
广告与追踪 AdSupport(weak)、AdServices(weak)、AppTrackingTransparency(weak) 读取 IDFA/ASIdentifier;ATT 授权弹窗(NSUserTrackingUsageDescription)
设备与网络 CoreTelephony 读取运营商、SIM/网络信息(≈ 设备指纹)
运动传感器 CoreMotion(weak) 加速度/陀螺仪/计步(隐私敏感)
相册与媒体 Photos、PhotosUI(weak)、AssetsLibrary、AVFoundation(weak)、AVKit、MediaPlayer、MediaToolbox、CoreMedia、CoreVideo、VideoToolbox、ImageIO 相册/相机/麦克风/视频播放(截图分享、客服上传)
支付 StoreKit(weak) App 内购买 / 收据校验
登录/社会化 AuthenticationServices、SafariServices、WebKit、Social、JavaScriptCore 网页登录、微信/抖音/H5 授权、分享
游戏/手柄 GameKit、GameController(weak) Game Center、外接手柄
安全 Security Keychain / 证书 / 加密原语
系统配置 SystemConfiguration、MobileCoreServices、CoreServices、UniformTypeIdentifiers(weak) 网络可达性、通用类型
账户/日历 Accounts、EventKit 系统账户、日历(一般由统计/推送 SDK 引入)
图形/计算 Accelerate(weak)、Metal、OpenGLES、CoreGraphics、QuartzCore、CoreImage、CoreText 渲染与信号处理
地图 MapKit(weak) 定位/地图展示
崩溃监控 MetricKit(weak) 系统级崩溃/性能指标
通知 UserNotifications(weak) 本地/远程通知
音频 AudioToolbox、OpenAL 音频引擎

配套 PrivacyInfo.xcprivacy:声明访问 SystemBootTime、DiskSpace、UserDefaults、FileTimestamp;收集 DeviceID(linked=true,用途 Analytics/Other)与 PhotosorVideos;NSPrivacyTracking = false(但实际链接了 AdSupport/ATT,声明与能力存在张力)。Info.plist 中 NSAdvertisingAttributionReportEndpoint = "https://adjust-skadnetwork.com"(注意字符串尾部含一个零宽空格 U+200B)。


2. 反篡改 / 反调试 / 反作弊证据(字符串 + 符号)#

说明:游戏字符串主要存在于 IL2CPP 元数据(已解密到 artifacts/out_literals.txt / out_identifiers.txt / out_types.txt)以及 UnityFramework 的 Mach-O 字符串表中。以下均给出精确命中串 + 来源文件。

2.1 越狱检测(jailbreak / Cydia / Substrate)

精确字符串 来源 上下文 / 含义
/Applications/Cydia.app unity.strings:58268 经典越狱路径探测
/Library/MobileSubstrate/MobileSubstrate.dylib unity.strings:58269 Substrate 注入框架探测
/usr/lib/libsubstrate.dylib unity.strings:58273 Substrate 库探测
/private/var/lib/apt/ unity.strings:58267 Cydia/APT 包管理残留
/etc/apt unity.strings:58270 同上
cydia:// unity.strings:58271 Cydia URL scheme 探测
/bin/bash、/usr/sbin/sshd unity.strings:64097-64098 越狱环境常见可执行文件
MobileSubstrate unity.strings:60232 名称匹配
cydiaSubstrate; / cYDIAsUBSTRATE unity.strings:26109 / 26123 变体/混淆匹配
isJailBreak unity.strings:46323 ObjC 方法或 IL2CPP 包装方法 isJailBreak
jailbrokenStatus / _jailbrokenStatus / setJailbrokenStatus: unity.strings:46495 / 40847 / 50796 ObjC 属性(TQ,N,V_jailbrokenStatus,unity.strings:60255)
/var/lib/dpkg/info/mobilesubstrate.md5sums fw_UnionOpenPlatformCore.strings:1773 字节跳动 UnionOpenPlatform SDK 内部的越狱检测

JailbrokenStatus 以 ObjC 属性/IL2CPP 符号形式存在(_jailbrokenStatus + setJailbrokenStatus: + 类型编码 TQ,N,V_jailbrokenStatus),说明越狱状态被读取并在 C#/ObjC 层保存。

2.2 反调试

精确字符串 来源 含义
isDebuggerAttached unity.strings:46262 调试器附加探测
isDebuggerAttachedToConsole unity.strings:57275 调试器/控制台探测
sysctl.proc_native unity.strings:83068 sysctl 环境探测
未定义符号 _ptrace、_sysctl、_sysctlbyname nm -u UnityFramework 反调试系统调用依赖
SRDebugger / SRDebuggerInit / OpenSRDebugger out_types.txt / out_literals.txt 内置调试面板(正式包默认关闭,但代码在)
OpenZbsDebugger、openLuaDebugger、LuaInterface.Debugger out_literals.txt:14663 等 Lua 调试器入口(潜在攻击面)

2.3 反作弊(核心为网易 NetEase NetSec / 易盾体系)

精确字符串 / 符号 来源 含义
NetEase.AntiCheatResult(类型) out_types.txt:1219 反作弊结果对象
NetEase_AntiCheatResultWrap / _CreateNetEase_AntiCheatResult out_identifiers.txt:11591 IL2CPP↔C# 桥接
NetEase.SafeCommResult / NetEase.NetSecProtect / NetEase.HTProtectConfig / NetEase.HTPCallback / NetEase.GetTokenCallback out_types.txt NetSec 加固/安全通信类型
InitNetSecProtect、NetSecGetToken、NetSecGetTokenAsync、NetSecSetConfigData、NetSecSetResponseData out_literals.txt:5342,6672-6675 反作弊初始化与令牌获取
NetSecGetCollectDataHelper、NetSecGetEmulatorName out_literals.txt:6670-6671 采集设备指纹 + 模拟器探测
safeComm / safeCommFromServer / safeCommToServerV30 / safeCommToServerByteV30 out_literals.txt:17414-17418 与服务端的安全(防篡改)通信通道
get_SC_DATA_TAMPERED / set_SC_DATA_TAMPERED out_identifiers.txt:11681,11700 数据篡改标志位
SC_DATA_TAMPERED out_identifiers.txt:87651, out_literals.txt:8104 篡改判定常量
AntiCheatResult、v16@?0@"AntiCheatResult"8 unity.strings:55367,91731 ObjC 方法类型编码(返回 AntiCheatResult)

关键文件 Data/Managed/Metadata/gm_NTESCSLLVMPASSKEY.dat:文件名直指 NetEase(NTES)+ IL2CPP LLVM 混淆 pass key,与 global-metadata.dat 同尺寸(9,902,340 B)。其 SHA-256 与 artifacts/global-metadata.dec.dat 完全相同(10257396bf…6097e),说明该文件内容即解密后的元数据(可能是分析过程回写产物,也可能是 NetEase 元数据解密/校验所需的密钥流),两种可能均指向 NetEase 对 IL2CPP 元数据做了自定义加密/混淆(原始 global-metadata.dat 哈希 edb4a80e…86e98 ≠ 解密后 2997a109…6c3b9)。同目录另有 key612.bin / key612_mode.bin(各 612 B,内容呈 XOR 混淆字节)。

2.4 未命中的探测(重要结论)

在本包中未发现下列常见安卓侧/PC 侧作弊工具的直接特征串:frida、xposed、libhooker、cycript、gameguardian、speedhack、mudfish,也未发现中文字面串 模拟器、外挂、作弊。iOS 侧的反作弊由 NetEase NetSec(原生/托管混合) 承担,检测逻辑多在 IL2CPP 元数据混淆后,字符串层仅暴露 API 名称。


3. 文件 / 资源完整性校验#

精确字符串 来源 上下文 / 判定
Invalid MAC - file may have been tampered with! out_literals.txt:5458 并非游戏资源校验。其前后紧邻 Invalid DHValidationParms、Invalid DSA parameters、Invalid Julian day、Invalid OID 等,属 BouncyCastle 加密库(CMS/OpenPGP MAC 校验)文案。此处 MAC = Message Authentication Code,不是资产完整性提示,属"误报诱饵"。
SC_DATA_TAMPERED / get_SC_DATA_TAMPERED / set_SC_DATA_TAMPERED out_literals.txt:8104、out_identifiers.txt:11681/11700/87651 真正的篡改标志,属 NetEase SafeCommResult(NetEase_SafeCommResultWrap-*)。
VersionManifestChecker(类型) out_identifiers.txt:21240 资源版本清单校验器
GetManifestMd5PrefsKey、GetSaveMd5、SetSaveMd5、OnGetManifestCompleted、Run out_identifiers.txt:29022-29026 以 MD5 比对清单、结果落盘到 Prefs
CheckVersionManifest、GetVersionManifestName、GetVersionManifestPath out_identifiers.txt:7287,23306,23307 清单检查入口
fileMd5、_fileMd5、_requestResourceMd5、cg_request_resource_md5、resource md5 = %@ unity.strings:36378,40474,41482,62149,62201 下载资源逐个 MD5 校验
Bad CRC32 in GZIP trailer. (actual({0:X8})!=expected({1:X8})) out_literals.txt:2374 GZIP 解压完整性
Mono.Security.*(ASN1、PKCS1、RSAManaged…) out_types.txt:2797-2813 托管加密栈

判定:资源完整性采用 MD5 清单校验(VersionManifestChecker)+ 单文件 MD5,属"完整性/防损坏"级别(MD5 可碰撞,非抗攻击的密码学防篡改)。真正具备运行时防篡改语义的是 NetEase SafeComm 通道与 SC_DATA_TAMPERED 标志。


4. 证书固定 / TLS#

检索项 结果 判定
pinning / SSLPinningMode / AFSecurityPolicy(在 UnityFramework 字符串) 仅 policyWithPinningMode:(unity.strings:48015),无 AFSecurityPolicy、SSLPinningMode、pinnedCertificates 等类/属性可打印名 AFNetworking 被链接且具备 pinning 能力,但二进制字符串层面无配置痕迹
pin / SPKI / public-key-pin / sha256/ / TrustKit / pin-set 全部未命中(out_literals.txt / out_identifiers.txt 仅命中无关的 thread_pinning_ref) 无真实 HPKP/SPKI 固定实现
AFSecurityPolicy 符号 在 AFNetworking 二进制中作为局部符号存在:+[AFSecurityPolicy policyWithPinningMode:]、certificatesInBundle:、keyPathsForValuesAffectingPinnedPublicKeys、-[AFSecurityPolicy SSLPinningMode] 能力存在,但无内嵌证书/公钥指纹,默认模式为 None
TLS 栈 mono_btls_x509_*(Mono/BoringSSL)、mbedtls_x509_crt_parse_der、Best.HTTP.SecureProtocol.Org.BouncyCastle.* 使用系统信任链(BoringSSL/mbedTLS),BouncyCastle 仅作密码学原语(含 X509.Allow_Non-DER_TBSCert、Rsa.MaxSize 等开关)

结论:该包未实现真正的证书固定(certificate pinning)。TLS 完全依赖系统信任链;AFNetworking 的 AFSecurityPolicy 仅作为未配置的通用能力存在,未见硬编码 pin/cert。所谓 "pinning/SPKI" 命中均为第三方网络库样板(Mono/BoringSSL/BouncyCastle),非游戏自研防中间人实现。


5. IFix 热更新(HotFix)#

证据 来源 含义
IFix.Core.dll Data/ScriptingAssemblies.json(汇编清单内) IFix 运行时热更新程序集确实随包分发
##### IFix.Core.dll (41 types) + IFix.Core.*(PatchManager、VirtualMachine、ILFixDynamicMethodWrapper、WrappersManager、SimpleVirtualMachineBuilder、Instruction、EvaluationStackOperation、ExternInvoker…) out_types.txt / out_identifiers.txt:24491 等 一个可用于运行时替换 IL 方法的虚拟机
IFix.IDMAP、IFix.ILFixInterfaceBridge、IFix.RedirectTo. out_literals.txt:5210-5212 补丁重定向与桥接
./Assets/Temp/ilpatch/{0}.patch.bytes、{0}.patch、iluapatch、luapatch、toluapatch out_literals.txt:733,18939,16380,18238,17019 IL 补丁文件下载/加载路径
EnableHotFix、CheckHotFix、DownloadHotFixVersion、GetHotFixUrl、HotFixConfig、HotFixAll、HotFixDirName、DownloadHotFix、ShowHotFixTip out_identifiers.txt / out_literals.txt 完整的热更新流水线(配置→检查→下载→应用)
curHotFixPackageMD5、curHotFixPackageSize out_literals.txt:13703-13704 补丁包 MD5/大小校验

运行时风险: 1. 动态代码注入:IFix 在运行时下载 .patch.bytes 并由 VirtualMachine 执行/替换已编译的 IL 方法,等于可远程更新游戏逻辑,绕过 App Store 静态审核与签名保险。 2. 远程任意行为面:热更通道一旦被劫持/中间人(结合第 4 节无 pinning),可向客户端注入任意逻辑。 3. 与反作弊协同:EnableHotFix/HotFixAll 受服务端配置控制;官方借此快速修补逻辑,但也放大了"补丁完整性校验"的重要性(当前仅 MD5 校验,防篡改强度有限)。 4. Data/Managed/Metadata/ 下存在 global-metadata.dat(加密)与 gm_NTESCSLLVMPASSKEY.dat,说明 IL2CPP 元数据本身被 NetEase 二次加密,静态分析须先解密元数据(本包已提供解密产物)。


6. 第三方 SDK 二进制:内嵌密钥 / 端点 / 签名校验#

SDK 框架 大小 显著字符串 / 密钥 / 端点 签名/校验能力
CrashSight 1.86 MB startWithAppId:、secretID/secretKey/token、cscos_HMACHexsha1:secret:、q-sign-algorithm=sha1&q-ak=…&q-signature=…、%@.%@.%@.amazonaws.com、CSCOSAuthentationCreator signatureForData:withCredential:err:、com.crashsight.persistent.*.errorsignature 有:腾讯云 COS 上传使用 HMAC-SHA1 签名(secretID/secretKey 运行时下发,tmpSecretId/tmpSecretKey/sessionToken)
AdjustSdk 887 KB https://analytics.adjust.com、https://consent.adjust.com、https://gdpr.adjust.com、https://subscription.adjust.com、https://ssrv.adjust.com、appToken、environment、Missing signature library, SDK can't be initialised 依赖 AdjustSigSdk
AdjustSigSdk 581 KB ADJSigner、sign:withActivityKind:withSdkVersion:、sign:withExtraParams:withOutputParams:、Signature %@,%@,%@,%@,%@ 有:专门做 Adjust 请求签名
UnionOpenPlatformCore(字节跳动) 3.46 MB btd_HMACMD5WithKey:andData:、btd_md5String、TTMD5SumGetter、UnionOpenPlatformDouyin、DouyinOpenSDK、douyin_key、webcast-open.douyin.com、http://toblog.ctobsnssdk.com…device_register/、RangersAPM…、device_id、/var/lib/dpkg/info/mobilesubstrate.md5sums 有:HMAC-MD5 请求签名;含越狱检测(dpkg/mobilesubstrate)
UnionOpenPlatformDataLink 90 KB 数据链路桥接 —
BDASignalSDK 118 KB https://analytics.oceanengine.com/sdk/app、https://dig.bdurl.net/q?host=analytics.oceanengine.com…、kBDASignalClickid、BDASignalHeader 设备信号采集
ThinkingSDK 942 KB appid=%@&source=client&dryRun=%d&deviceId=%@&data=%@、TDSecretKey、customSecretKey、innerSecretKey、instanceToken 埋点上报(含秘钥字段)
ThinkingDataCore 164 KB 核心工具 —
AFNetworking 460 KB AFSecurityPolicy(policyWithPinningMode: 等局部符号) 标准网络库,未见 pin 配置
Protobuf 934 KB GPBMessageSignatureProtocol 仅 protobuf
FirebaseNIMessInstallation 2.98 MB Firebase Installation / FID —

appex CGPushServerExtension:https://logagent-wf.centurygame.com/log(推送投递日志上报)、CenturyGamePushData、sdk.push.eventhook、caffeinePushEventReport:event:。

App 级明文配置中的内嵌秘密(非二进制,但同属二进制外泄面) ddCommon.json: - adjust(长 hex token)、constants、secret、secret_android_*、rum.production/sandbox、smarthelp.*、tga、umbra_gateway.*(均为超长 hex 串,疑为加密后的密钥/开关); - helpshift: 8c855fd7c4cc6b899e2c64f37ecc65b3(32-hex); - 明文 ID:game_id 20173、bugly_id 341c16d88c、wechat_app_id wx32374c9038cf9759、douyin_client_key awebivvetg90lv93、access_id 1580019064、access_key AQC2K08T7CLS; - UOPSDKConfig.json:app_id 789841(UnionOpenPlatform)。 - Info.plist 中的 URL scheme 亦暴露微信 AppID(wx32374c9038cf9759)与抖音 key(awebivvetg90lv93)。


7. 风险结论#

  1. 壳/加密:三个主二进制 cryptid=0(已解密),但 IL2CPP 元数据被 NetEase 二次加密/混淆(global-metadata.dat 原始哈希 ≠ 解密后;gm_NTESCSLLVMPASSKEY.dat / key612*.bin 佐证),静态分析必须依赖解密产物。
  2. 反作弊=网易 NetSec/易盾:反篡改核心是 NetEase.NetSecProtect + SafeComm(V30 加密信道)+ SC_DATA_TAMPERED 标志;具备设备指纹采集(NetSecGetCollectDataHelper)与模拟器探测(NetSecGetEmulatorName)。
  3. 越狱/调试检测齐备:完整 Cydia/Substrate 路径集、isJailBreak、jailbrokenStatus 属性、isDebuggerAttached/isDebuggerAttachedToConsole,并在 UnityFramework 依赖 ptrace/sysctl。
  4. 完整性校验偏弱:VersionManifestChecker 与资源校验使用 MD5(非抗攻击),"Invalid MAC…tampered with" 实为 BouncyCastle 库文案,非真实资产防篡改。
  5. 无真实证书固定:TLS 依赖系统信任链,AFNetworking 的 pinning 能力未被配置;结合 IFix 运行时 IL 热更(./Assets/Temp/ilpatch/{0}.patch.bytes),存在热更通道被中间人劫持后注入代码的残余风险面。
  6. 内嵌凭据面广:ddCommon.json、Info.plist 明文暴露微信/抖音/UnionOpenPlatform/COS 等标识与密钥密文;CrashSight 的 COS 上传、Adjust/字节 SDK 的 HMAC 签名在运行时下发密钥。

05 · 网络端点、配置文件与硬编码密钥分析#

本章基于已脱壳的 com.gof.china 1.15.6(无尽冬日 / Whiteout Survival CN)IPA 及其预抽取产物,梳理对外网络端点、配置内嵌字段、密钥/标识符定性、构建与供应链残留四类信息。

数据来源(只读、离线):

来源 路径 说明
IL2CPP 字面量 artifacts/out_literals.txt 19,293 行字符串常量(含 C# 层 URL)
IL2CPP 标识符 artifacts/out_identifiers.txt 88,084 个符号名
应用包 extracted/Payload/whiteoutsurvivalcn.app/ ddCommon.json / UOPSDKConfig.json / Info.plist / install/
Lua 热更包 Data/Raw/data/luapackage_{32,64}_*.unity3d 游戏逻辑层(运行时拼接)URL 片段

说明:C#/原生层端点来自 out_literals.txt;Lua 层端点在热更包中以字符串拼接模板形式出现(如 https://gofcn-gm-%s-api-prod.campfiregames.cn),本文按其在字节码中的确切片段(fragment)记录,不做臆测补全。


5.1 端点清单(按用途分类)#

5.1.1 游戏资源 / CDN(全部 HTTPS)

# 端点(原文) 用途 备注
1 https://gofcn-prod-cdn.campfiregames.cn/RELEASE/{0}/{1}/ 生产 CDN 资源根 占位符 {0}{1} 为版本/分包
2 https://gofcn-prod-cdn.campfiregames.cn/RELEASE/WebUrl_2/Web{0}.txt 生产 WebUrl 清单 网页/活动资源清单
3 https://gofcn-prod-cdn.centurygames.cn/RELEASE/{0}/{1}/ 生产 CDN 备用域 世纪游戏主域 centurygames.cn
4 https://gofcn-qa-cdn.campfiregames.cn/RELEASE/{0}/{1}/ QA CDN 随包发布,测试环境
5 https://gofcn-qa-cdn.campfiregames.cn/TEST/{0}/ QA CDN 测试
6 https://gofcn-qa-cdn-1322302784.cos.ap-shanghai.myqcloud.com/RELEASE/{0}/{1}/ 腾讯云 COS 生产镜像 桶 ID 1322302784,上海
7 https://gofcn-qa-cdn-1322302784.cos.ap-shanghai.myqcloud.com/TEST/WebUrl/Web{0}.txt COS 测试清单
8 https://gofcn-qa-cdn-1322302784.cos.ap-shanghai.myqcloud.com/TEST/{0}/ COS 测试资源
9 https://gofcn-qa-cdn-1322302784.cos.ap-shanghai.myqcloud.com/INNER/WebUrl/Web{0}.txt COS INNER(内部)清单 ⚠ 内部环境标识 INNER
10 https://gofcn-prod-avatar-cdn.campfiregames.cn/static/app/...(Lua 片段) 生产头像 CDN
11 https://gof-s3-user-avatar.s3.us-west-2.amazonaws.com/(Lua 片段) 用户头像 S3 桶 美西 us-west-2
12 https://1254330885.cos.ap-guangzhou.myqcloud.com/...(Lua 片段) 另一腾讯云 COS 桶 桶 1254330885,广州
13 ac192625a0e1c417b8e09811b9449245-50cb9e3108c40714.elb.us-west-2.amazonaws.com(Lua 片段) AWS Classic ELB(后端服务) 名称含 ELB ID,非 CDN

5.1.2 配置 / 版本 / 设备(全部 HTTPS)

# 端点(原文) 用途 备注
14 https://platform-config-prod.centurygame.com/config.json 平台配置下发(生产) 与 ddCommon.json 同名基线配置
15 https://platform-config-sandbox.centurygame.com/config.json 平台配置下发(沙箱)
16 https://clientversion.diandian.info/snapshot/ 客户端版本 / 快照 接口 ⚠ 见 5.1.7
17 https://devcenter.campfiregames.cn/api/devices 设备注册 / 开发者中心 API 采集设备指纹相关

5.1.3 GM / 运营 / 后台 API(⚠ 重点标记)

# 端点(原文) 环境 备注
18 https://gofcn-gm-api-prod.campfiregames.cn 生产 GM API 根
19 https://gofcn-gm-api-test-out.campfiregames.cn 测试(外网) 测试环境地址随生产包发布
20 https://gofcn-gm-api.diandian.info 内部/历史域名 旧域名 diandian.info
21 https://gofcn-gm-api-staging.campfiregames.cn(Lua) Staging 灰度环境地址
22 https://gofcn-gm-{h\|r}*-api-prod.campfiregames.cn/api/...(Lua 片段) 生产 拼接模板:/api/.../record、/api/user/...
23 https://gof-ru-f*-api-formal.echofungames.com/api/.../record(Lua 片段) 俄区正式 关联域 echofungames.com
24 https://{?}-list-api.100topia.cn/api/g...rSetting(Lua 片段) — 关联域 100topia.cn

为何值得关注: GM/运营 API 域名(gofcn-gm-api-*)出现在 C# 字面量与 Lua 字节码中,意味着客户端具备调用 GM 接口的能力;同时生产、测试(-test-out)、staging 三套地址全部随线上包发布,任意一套被盗用即可作为横向探测入口。diandian.info(旧法人域)与 echofungames.com、100topia.cn(关联域)暴露了基础设施的历史与关联资产。

5.1.4 第三方 SDK / 社交 / 广告(HTTPS)

# 端点(原文) 归属 备注
25 NSAdvertisingAttributionReportEndpoint = https://adjust-skadnetwork.com Adjust ⚠ 末尾含 零宽空格 U+200B(e2 80 8b)
26 https://srdebugger.stompyrobot.uk/report/submit SRDebugger 运行时调试面板上报端点
27 https://mp.weixin.qq.com/mp/homepage?__biz=MzkwMDY3NDc4MQ==&hid=1&sn=78c72e284740ab05a4441398910e3b4e 微信 公众号主页
28 https://tieba.baidu.com/f?ie=utf-8&kw=%E6%97%A0%E5%B0%BD%E5%86%AC%E6%97%A5 百度贴吧 “无尽冬日”吧
29 https://www.xiaohongshu.com/user/profile/5ea676d500000000010065f3?... 小红书 官方账号
30 https://l.taptap.cn/tIZHXGwE?...(Lua 片段) TapTap 渠道短链
31 https://posts.tenpay.com(Lua 片段) 财付通 支付相关
32 https://www.toponad.com/(Lua 片段) TopOn 广告聚合
33 https://legal.*centurygames.cn/privacy_wjdr.html(Lua 片段) 世纪游戏 隐私政策(CN)
34 https://www.centurygames.com/privacy-policy/(Lua 片段) 世纪游戏 隐私政策(国际)
35 https://...gg/mKKJemAD5a(Lua 片段,前缀为 https://d) Discord 社区邀请链接
36 https://mmoc.qpic.cn/wechat...(Lua 片段) 腾讯 微信图片 CDN(mmoc + .qpic.cn/wechat)
37 tpns.sh.tencent.com(ddCommon.json 的 XG_SERVER_SUFFIX) 腾讯 TPNS 推送 主域无 scheme

LSApplicationQueriesSchemes 另声明了 fb / fb-messenger / whatsapp / weixin / weixinULAPI / weixinURLParamsAPI / douyinopensdk / douyinliteopensdk / douyinshare / snssdk1128 / weibosdk,印证集成了微信、抖音、微博等分享/登录 SDK。

5.1.5 框架 / 文档噪声(HTTP 明文,非运行端点)

以下均为第三方库内嵌注释/命名空间,与本游戏业务无关,且多为 HTTP 明文:

  • http://www.w3.org/2000/09/xmldsig#*、http://www.w3.org/2001/04/xmldsig-more#*、http://www.w3.org/2001/04/xmlenc#*(XML 签名/加密命名空间)
  • http://www.root-motion.com/finalikdox/html/*(Final IK 文档)
  • http://forum.unity3d.com/threads/final-ik-...222685/
  • https://docs.unity3d.com/Manual/LogFiles.html、https://groups.google.com/forum/#!forum/final-ik
  • https://github.com/mono/mono/issues/12880
  • https://bitbucket.org/sirenix/odin-inspector/issues/526(Odin)
  • https://apps.apple.com/cn/app/.../id6478492012(本作 App Store 页)
  • https://localhost/(占位)
  • https://bestdocshub.pages.dev/HTTP/getting-started/downloads/
  • http://www.apple.com/DTDs/PropertyList-1.0.dtd(各 Info.plist DTD)

5.1.6 HTTP 明文 vs HTTPS 汇总

  • 业务/配置/GM/第三方 SDK 端点:100% 为 HTTPS。
  • 明文 http:// 仅出现在框架文档噪声与 plist DTD 中,不构成运行期明文传输。
  • 值得注意:Info.plist 未声明 NSAppTransportSecurity 例外(grep -c = 0),即系统 ATS 默认拦截明文 HTTP——与“真实端点全部 HTTPS”一致。

5.1.7 snapshot 端点专项

https://clientversion.diandian.info/snapshot/
  • 同时存在字面量 /snapshot(out_literals.txt:841,无 scheme 的路径片段)。
  • 语义为客户端版本/资源快照(版本比对与增量更新入口)。以旧法人域 diandian.info 承载,说明该更新链路沿用较早基础设施;/snapshot/ 未带签名参数,若服务端鉴权不足,可能成为版本枚举/降级攻击的探测面(仅从端点形态判断,未做验证)。

5.2 ddCommon.json 全量分析#

路径:extracted/Payload/whiteoutsurvivalcn.app/ddCommon.json(应用根目录随包发布,MD5 7cef956efab74190b927f30952cc5b40)。该文件是明文 JSON,含有大量标识符与加密配置块。

5.2.1 顶层字段

字段 值(精确引用) 定性
id 3281 平台/应用内部 ID(非密钥)
adjust 208 字节 hex(见 5.3) 加密块
constants 1792 字节 hex 加密块(最大,含常量/地址)
helpshift / helpshift_ios 8c855fd7c4cc6b899e2c64f37ecc65b3(32 hex) Helpshift 应用 Key(半公开,实为 SDK 标识)
secret 208 字节 hex 加密块
secret_android_game 80 字节 hex 加密块
secret_android_production 48 字节 hex 加密块
secret_android_sandbox 48 字节 hex 加密块
tga 224 字节 hex 加密块(TGA 数据上报配置)
rum.production / rum.sandbox 各 704 字节 hex 加密块(RUM 监控)
smarthelp.production / smarthelp.sandbox 各 288 字节 hex 加密块(智能客服)
umbra_gateway.production / sandbox 各 496 字节 hex 加密块(Unity Umbra 网关配置)
unity_config 1324 字符 Base64 加密块

5.2.2 platform.ios(与 android / oh 并列)

字段 值(精确引用) 定性
bugly_id 341c16d88c 公开标识(腾讯 Bugly AppID,android 侧为 1ea45351f9)
china true 环境标志
game_id 20173 公开标识(世纪游戏统一 game_id;URL Scheme、appex 均复用)
is_offline_games false 环境标志
douyin_client_key awebivvetg90lv93 半公开标识(抖音开放平台 Client Key;同时作为 URL Scheme)
wechat_app_id wx32374c9038cf9759 半公开标识(微信开放平台 AppID;同时作为 URL Scheme)
tga_inited_early true 开关
tga_encryption_info 432 字节 hex(与 android / oh 完全一致) 加密块(TGA 上报加密材料)

5.2.3 platform.android / platform.oh 额外字段

字段 值(精确引用) 定性
android_package_name / oh_package_name com.gof.china 包名
XG_SERVER_SUFFIX tpns.sh.tencent.com 腾讯 TPNS 推送主域
access_id 1580019064 推送凭据 ID(腾讯 TPNS AccessID)
access_key AQC2K08T7CLS ⚠ 推送密钥(真密钥),明文 12 字符

关于“admin keys”:ddCommon.json 中不存在名为 admin 的字段。与“管理/服务端凭据”语义最接近的是腾讯 TPNS 推送的 access_id / access_key,其中 access_key = AQC2K08T7CLS 属应保密的密钥(虽为推送通道,泄露可被用于伪造推送/盗刷配额)。

5.2.4 明文评述

game_id(20173)、bugly_id、wechat_app_id、douyin_client_key 均为客户端公开/半公开标识,本身泄露风险低(受平台侧签名与服务端校验约束)。真正的敏感点是腾讯推送 access_key 与全部 hex/base64 加密块中的对称配置。


5.3 不透明字段(hex / base64)的格式与熵评估#

所有 hex 块均为偶数字节长度的十六进制串(首字节均为 cfab7bf2.../995ea76d... 等固定前缀),Base64 块 unity_config 以 B19cZy+w... 开头,末尾以 = 填充。逐字段字节熵(Shannon,bits/byte)如下:

字段 编码 字节长度 首 8 字节 hex 字节熵 (bits/byte)
secret_android_production hex 48 5970f990f745e2af 5.335
secret_android_sandbox hex 48 5970f990f745e2af 5.418
secret_android_game hex 80 2564594dae877f8a 5.953
smarthelp.production hex 288 89ca80f5e27dc345 7.162
smarthelp.sandbox hex 288 011c999e7ae87462 7.240
adjust hex 208 c1540cc8f7854eef 7.036
secret hex 208 2564594dae877f8a 7.003
tga hex 224 387bf285c58ec55b 7.163
platform.*.tga_encryption_info hex 432 cfab7bf27c7e5a0d 7.474
umbra_gateway.production hex 496 995ea76dc7199427 7.606
umbra_gateway.sandbox hex 496 995ea76dc7199427 7.591
rum.production hex 704 cf542ca2130eae44 7.734
rum.sandbox hex 704 80e4a71af79b0119 7.752
constants hex 1792 8169e58dcbbf1a5a 7.902
unity_config base64 992 B19cZy+wVkuCtJNY(解码后) 7.766

格式判定(只做结构描述,不尝试破解):

  1. 高熵块(≥7.0 bits/byte)符合 AES/分组加密密文或高熵密钥材料 的特征;uint8 分布均匀,无可见明文结构。
  2. 低-中熵块(secret_android_* 5.3–6.0)熵偏低,提示其内部包含重复的固定前缀/版本段(例如 secret_android_production 与 sandbox 前 8 字节完全相同),可能是“加密后的字符串 + 固定元数据”的混合体。
  3. 多组字段共享相同前缀,说明它们是同一密钥体系/同一序列化器产出(例如 secret 与 secret_android_game 均以 2564594d... 开头;umbra_gateway 两环境前缀相同、仅尾部不同)。
  4. tga_encryption_info 在 android/ios/oh 三平台字节完全一致,且与被引用为顶层的 tga(224B)不同——说明 tga 存在平台无关的公共加密材料。
  5. unity_config 为 Base64 包裹的密文/二进制配置(含 + / =,解码后 992 字节、熵 7.77)。

这些块预计由世纪游戏 DD SDK(Unity.dd.sdk.scripts.*)在运行时解密使用;本报告不对其做密码学破解,仅记录编码、长度、前缀与熵,作为“存在加密配置”的客观证据。


5.4 UOPSDKConfig.json#

路径:extracted/Payload/whiteoutsurvivalcn.app/UOPSDKConfig.json(MD5 c85fe6aa0a1d58aeb9c6a80b9f1379c0),全文:

{
  "app_id": "789841",
  "osdk_type": "Omnichannel_ActivityLink",
  "client_key": {
    "douyin_key": ""
  },
  "debug_mode": false
}
字段 值 定性
app_id 789841 抖音“UOP/巨量”渠道 AppID(公开标识)
osdk_type Omnichannel_ActivityLink 全渠道活动链接能力开关
client_key.douyin_key 空字符串 客户端未内嵌密钥(服务端配置,良好实践)
debug_mode false 生产关闭

结论:UOPSDK 的敏感 douyin_key 为空,未在包内泄露;此为正确做法,可作为对照项。


5.5 密钥定性汇总:真密钥 vs 公开标识#

类型 字段 / 值 判定 依据
✅ 公开标识 game_id=20173、bugly_id=341c16d88c、wechat_app_id=wx32374c9038cf9759、douyin_client_key=awebivvetg90lv93、app_id=789841 公开/半公开 需配合 AppSecret/签名并由服务端校验,单独泄露风险低
✅ 公开标识 helpshift=8c855fd7c4cc6b899e2c64f37ecc65b3、id=3281 SDK/应用标识 Helpshift Key 属 SDK 侧公开字段
⚠ 真密钥 platform.android/oh.access_key = AQC2K08T7CLS 应保密 腾讯 TPNS 推送密钥,明文内嵌
⚠ 真密钥(不透明) adjust / constants / secret / secret_android_* / tga / tga_encryption_info / rum.* / smarthelp.* / umbra_gateway.* / unity_config 加密的对称配置 高熵密文/Base64,运行时解密,内容不可直接读取
⚠ 敏感地址 gofcn-gm-api-prod/-test-out/.diandian.info、gofcn-gm-api-staging 内部/后台入口 生产包内同时暴露 prod/test/staging

要点:唯一明文真密钥是腾讯 TPNS 的 access_key;其余敏感材料均被加密包裹,属于“有防护但仍随包分发”的配置。


5.6 构建 / 供应链残留(随生产 IPA 发布)#

以下文件被打包进了线上 IPA,属于典型的“开发/CI 产物泄漏”。

5.6.1 install/buildIpa.sh

projName=$1
projPath=$2
codeSignType=$3
provision=$4
#provision="60a0e608-4a3b-42cb-8191-ae06c24af1e2"
...
xcodebuild archive -project $projName.xcodeproj -scheme $projName -configuration Release \
  -archivePath $projPath/output/$projName.xcarchive \
  CODE_SIGN_IDENTITY="$codeSign" PROVISIONING_PROFILE="$provision" > output/archiveLog.txt
  • 泄露CI 打包流程与签名方式(iPhone Distribution)。
  • 注释中残留配置描述文件 UUID:60a0e608-4a3b-42cb-8191-ae06c24af1e2。

5.6.2 install/autoUpdateRepoPublic.sh

CGSRepo="bitbucket.org/funplus/centurygamesdkpodspec.git"
...
sourcePath=$(grep -E 'source.*oauth2:' $podfilePath | awk '{print $NF}' | sed ...)
addRepoCommand="pod repo add CenturyGameSDKPodSpecPublic ${sourcePath}"
  • 泄露内部 Bitbucket 仓库:bitbucket.org/funplus/centurygamesdkpodspec.git(组织 funplus,与世纪游戏/点点同源)。
  • 脚本从 Podfile 的 source ... oauth2: 行提取 CocoaPods 私有源地址(含 oauth2 令牌位)——即私有 spec 源使用带令牌的 oauth2: 形式,令牌不在此脚本内但指明其存在。
  • 涉及缓存清理对象:CenturyGameiOSCGIDWebResource(CGID Web 资源 Pod)。

5.6.3 CenturyGameResources.bundle/merge.sh + merge_infoplist.py

  • merge.sh:构建期脚本,调用 python .../CenturyGameResources.bundle/merge_infoplist.py $projectName $config_path
  • merge_infoplist.py:读 ddCommon.json 的 platform.ios 段,在打包时动态改写 Info.plist,写入 CFBundleURLSchemes(centurygame=com.diandian.logger.<game_id>、wechat、QQ、Facebook、Google、Twitter、Naver 等)与 LSApplicationQueriesSchemes。
  • 代码为 Python 2 语法(print 语句、has_key),说明构建链较旧。
  • 依赖 mopub-sdk-id.json(SKAdNetwork 列表)注入 SKAdNetworkItems。

同一对脚本在 CenturyGameResources.bundle/ 与 Frameworks/UnityFramework.framework/CenturyGameResources.bundle/ 各存一份(重复随包发布)。

5.6.4 SC_Info/ 内容

文件 大小 说明
Manifest.plist 1744 B SinfPaths + 16 条 SinfReplicationPaths(列出所有 Frameworks/appex 的签名副本路径)
whiteoutsurvivalcn.sinf 1056 B 主二进制签名封装,头 sinf/frma=game/schm=itun(FairPlay 结构)
whiteoutsurvivalcn.supf / .v5.supf 1020 / 1000 B 公平游戏签名记录
whiteoutsurvivalcn.supp / .v4.supp 1636 / 1616 B 签名属性
whiteoutsurvivalcn.supx 80 B 签名扩展
  • 主二进制与 UnityFramework 的 cryptid 均为 0(已脱壳),因此 SC_Info 仅为 App Store 加密时代的残留容器,本身不含可解密密钥。
  • Manifest.plist 完整暴露了内部 framework 构成(Adjust、CrashSight、ThinkingSDK、BDASignalSDK、UnionOpenPlatform、Firebase 等)。

5.6.5 Payload/decrypt.day

und3fined
  • 内容为 9 字节 ASCII und3fined,位于 Payload/decrypt.day。
  • 这是第三方脱壳/解密工具(“und3fined”)在重打包时留下的标记文件,证明该 IPA 已被第三方工具处理过,并非官方发布产物。此文件本身不携带密钥,但标记了供应链中间环节。

综合 5.6.1–5.6.5:构建脚本、CI 凭据线索、私有 repo 地址、签名残留与脱壳标记均随生产 IPA 一同分发,属于可被攻击者直接利用的“信息泄露面”。


5.7 主机 / 格式清单(IP、端口、ws/wss)#

5.7.1 硬编码 IP 与端口

  • 未发现真实业务 IP 或端口。out_literals.txt 中形如 1.1.3.1、1.2.643.2 的均为 ASN.1/X.509 OID;:1987、:1988、:1991、:13321 分别来自字符集名(ISO_8859-3:1988 等)与版本号,非网络端口。
  • 仅见占位值 0.0.0.0 与 https://localhost/(框架占位)。
  • 游戏服务器地址显然不硬编码于可读字面量,而是经 platform-config / clientversion / 加密 umbra_gateway / constants 在运行时下发。

5.7.2 ws:// / wss://(实时通信)

  • 字面量中不存在硬编码的 ws:///wss:// 端点(对 out_literals.txt 全文匹配 wss?:// 仅得 scheme 常量)。
  • 存在的仅是协议相关常量/报错文本:
  • 字面量:Only Uris starting with 'ws://' or 'wss://' are supported.
  • Lua 字节码片段:在 IsWebSocket 附近出现 ws:// 与 ws(属 UnityWebSocket/Mono 的 scheme 判定,非端点)。
  • 实时通信能力确实存在,由以下证据确认:
  • Data/ScriptingAssemblies.json 含 UnityWebSocket.Runtime.dll;
  • 类型:CenturyGame.GameFramework.WebSocketProxy(Open/SendBinary/SendMessage/SetOpenHandler...)及 Lua 包装 CenturyGame_GameFramework_WebSocketProxyWrap;
  • 加密配置 umbra_gateway(production/sandbox) 即网关(Gateway)配置块,实时网关地址被加密隐藏,无法在不解密的前提下读出。

5.7.3 其他主机格式

  • dd_sdk_unity_version = 8.0.5.0-GOFCN-1(Info.plist),dd_sdk_environment_production = true——两平台环境标志。
  • 腾讯推送主域 tpns.sh.tencent.com(无 scheme,ddCommon.json)。

5.8 风险定级与结论#

风险项 等级 说明
明文真密钥 access_key=AQC2K08T7CLS 内嵌 中 腾讯 TPNS 推送密钥随包分发
GM/运营 API(prod/test/staging)随包发布 中-高 后台入口暴露,利于横向探测
构建/供应链残留(Bitbucket 私有 repo、oauth2 线索、CI 脚本、脱壳标记) 中 泄露组织与基础设施结构,可用于社工/供应链攻击
大量 hex/Base64 加密配置(secret/adjust/tga/umbra_gateway 等) 低-中 有加密保护,构成“信息防御”但仍是攻击面
snapshot 版本接口(旧域、无签名迹象) 低-中 可能被用于版本枚举/降级探测(未验证)
明文 HTTP 业务端点 无 业务端点全 HTTPS,且无 ATS 例外
硬编码 IP / 端口 / ws 端点 无 未发现

结论: 该版本没有在可读字面量中硬编码业务服务器地址、IP 或端口,实时网关被加密(umbra_gateway)保护,基础网络传输(HTTPS + ATS 默认)较为规范;主要问题不在“网络层”,而在配置与供应链层——GM/运营多环境地址外泄、唯一明文推送密钥内嵌,以及构建脚本/私有仓库线索随 IPA 发布。建议:移除 install/、merge*.py/sh、decrypt.day 等非运行产物;将 TPNS access_key 移至服务端签发;对 gofcn-gm-api-* 与 snapshot 加强服务端鉴权与限流。


06 · IL2CPP 元数据加密还原(核心技术章节)#

本章记录本次逆向中最具技术含量的部分:绕过 global-metadata.dat 的加密保护,并从中还原出该 Unity 游戏的完整符号体系。


6.1 背景:IL2CPP 与元数据#

Unity 使用 IL2CPP 后端时,C# 程序集会被 AOT 编译为原生代码,同时把"反射所需的元数据"(类型、方法、字段、字符串字面量、程序集清单等)集中写入:

Data/Managed/Metadata/global-metadata.dat

其结构以一个固定头开始(magic 0xFAB11BAF),随后是各数据区(字符串表、方法表、字段表、类型定义表、程序集映像表……)的偏移与大小。只要能读出该文件,就能恢复出游戏的全部 C# 符号(类名/方法名/字符串常量),因此厂商常对它做加密。

标准头签名(little-endian):

AF 1B B1 FA | version(int32) | stringLiteralOffset | stringLiteralSize | ...

本样本原始文件头却是:

00000000: e14f f4a9 5c53 4c4c 564c 5041 a309 4945   .O..\SLLVLPA..IE

原始 magic 已被破坏,且整个文件呈现异常高的"可打印 ASCII"比例(73.3%)——这是周期 XOR 的典型特征(明文多为小值/0,XOR 上 ASCII 密钥后落入可打印区)。


6.2 破译过程#

步骤 1 · 自相关定位密钥周期

对密文做逐 lag 的字节自相关 P(ct[i] == ct[i+L])(numpy,采样加速)。若密文由周期密钥 XOR 生成,则当 L 为周期整数倍时,相同明文位置会重复出现相同密文,匹配率显著抬升。

结果(Top 峰值):

lag(L) 匹配率
612 0.384
1224 0.380
1836 0.374
3672 0.373
2448 0.370

所有峰值均为 612 的倍数,故真实周期整除 612。612 = 36 × 17,提示周期可能远短于 612。

步骤 2 · 相位众数恢复密钥

对每个相位 i mod 612 统计密文字节众数(明文 0x00 占主导时,密文=密钥):

key[0..15] = 4E 54 45 53 EE 6E 4C 4C 56 4D 50 41 AC AC 4B 45
             N  T  E  S  .  n  L  L  V  M  P  A  .  .  K  E

可见其高度重复,呈现 17 字节模式(NTES…LLVMPA…KEY)。结合步骤 1 的 612=36×17,判定真实周期为 17。

步骤 3 · 用已知明文校验并定钥

密钥前 4 字节 XOR 密文头应等于标准 magic AF 1B B1 FA:

E1 4F F4 A9  XOR  key[0..3] = AF 1B B1 FA
=> key[0..3] = "NTES"    (0x4E 0x54 0x45 0x53)

再以版本字段(应为小整数)反推 key[4..],最终得到完整 17 字节周期密钥:

NTESCSLLVMPASSKEY
( 4E 54 45 53 43 53 4C 4C 56 4D 50 41 53 53 4B 45 59 )

步骤 4 · 解密验证

以该密钥对整文件循环 XOR:

明文头: AF 1B B1 FA | 1F 00 00 00 | ...
        magic 正确   version = 31
  • version = 31 → 合法的 IL2CPP 元数据版本;
  • 字符串区可完整读出(The exception contained the following message:、Lua 运行时源码片段等);
  • 全文件任意位置均可检出 UnityEngine.MonoBehaviour、mscorlib、Assembly-CSharp、get_DeviceID、AntiCheatResult、DecryptLuaBytecode 等符号。

结论:解密完全正确且可复现(脚本见附录)。

步骤 5 · 保护方案归因(NetEase 易盾)

密钥串前缀 NTES 与元数据中还原出的符号高度吻合,指向 网易易盾 NetSec(NetEase.NetSecProtect) 加固方案:

NetEase.NetSecProtect / NetEase.AntiCheatResult / NetEase.SafeCommResult
NetEase.HTProtectConfig / NetEase.GetTokenCallback / NetEase.RequestCmdID
InitNetSecProtect / NetSecGetEmulatorName / NetSecGetToken / NetSecGetCollectDataHelper

NTES 恰为 NetEase 的股票代码/缩写。可判定该游戏的 IL2CPP 元数据加密 + 反作弊/设备指纹 均由网易易盾 SDK 提供(NTES…PASSKEY 很可能为易盾生成的一次性/固定口令)。

⚠️ 保护强度评估:这是一处"隐藏式安全"(security by obscurity)。固定、可打印、可自相关定位的周期 XOR 密钥,在数分钟内即可离线还原,不构成有效防护,仅略微提高自动化工具(如 Il2CppDumper 直接读取)的门槛。易盾的真正价值在于其运行时反作弊(设备指纹/模拟器识别/token),而非静态加密本身。


6.3 还原结果#

解密后文件:artifacts/global-metadata.dec.dat(9,902,340 B,version 31)。

6.3.1 元数据结构统计(由文件头直接解析)

数据区 偏移 大小(字节) 条目数
字符串字面量索引 stringLiteral 0x00000100 154,352 19,294 条字面量
字符串字面量数据 stringLiteralData 0x00025BF0 547,416 —
标识符字符串堆 string 0x000AB648 2,170,332 约 88,084 个标识符
事件 events 0x002BD424 5,280 220(÷24)
属性 properties 0x002BE8C4 151,760 7,588(÷20)
方法 methods 0x002E3994 2,616,048 36,334(÷72)
参数字段默认值 parameterDefaultValues 0x00562484 13,428 —
字段默认值 fieldDefaultValues 0x005658F8 370,032 —
参数 parameters 0x00609800 1,031,784 —
字段 fields 0x00705668 663,672 55,306(÷12)
泛型参数/约束/容器 … … —
类型定义 typeDefinitions 0x0081394C 748,968 8,511(÷88)
映像 images 0x008CA6F4 2,760 69 个程序集/映像
程序集 assemblies 0x008CB1BC 4,416 69
属性数据 attributeData / range … … —
导出类型 exportedTypeDefinitions 0x0097066C 4,760 —

6.3.2 程序集(Images)清单(69 个)

按类型数量排序的、值得关注的自研/第三方程序集:

程序集 类型数 说明
Assembly-CSharp.dll 2,731 游戏主程序集(C# 侧:框架、UI、桥接)
mscorlib.dll 1,287 .NET 基础库
com.Tivadar.Best.HTTP.dll 1,228 Best HTTP/2(含 BouncyCastle 加密库)
OdinSerializer 215 序列化
spine-unity 161 2D 骨骼动画
CriMw.CriWare.Runtime 193 CRI 音视频中间件
IFix.Core.dll 41 热更新(IL 热补丁)框架
Unity.dd.sdk.scripts.*(多枚) — Century Games 自研 SDK:core/account/accountcn/payment/adjust/tga/advertising/wechat/push/rate/smartHelp/helpshift/wjx/report/tools/bugly
CenturyGame.GameFramework 24 自研游戏框架(资源/Lua/AssetBundle/网络)
UnityWebSocket.Runtime 15 实时 WebSocket
CString / FastString.Runtime — 字符串处理优化
Debugger.dll / HdgRemoteDebugRuntime — 远程调试运行时

其余为 Unity 各模块(UnityEngine.*)与系统库(System.*、Mono.Security、System.IO.Compression 等)。

6.3.3 业务与技术栈画像(标识符挖掘)

从 artifacts/out_identifiers.txt(88,084 个标识符)与 artifacts/out_types.txt 可还原出游戏技术栈:

① 脚本层:Lua(XLua / LuaInterface)

CenturyGame.GameFramework.LuaModule     (Init/CallLua/ExecuteStringCode/…)
CenturyGame.GameFramework.LuaLoader     (AddLuaBundle/GetLuaFromBundle/ReadZipFile)
CenturyGame.GameFramework.Helper.DecryptLuaBytecode / EncryptLuaBytecode / CheckLuaBytecodeHeader
LuaInterface (50 个类型)

→ 游戏玩法逻辑以 Lua 字节码形式承载,资源包内 luapackage_32/64_*.unity3d(各约 20 MB)即其容器,运行时解密执行。这意味着"上层玩法可被反编译/篡改",是关键攻击面。

② 资源层:AssetBundle + XOR 加密

CenturyGame.GameFramework.Helper.EncryptXOR / EncryptXOR1 / EncryptXOR2
CenturyGame.GameFramework.Helper.CalcEncryptKeyFromString
CenturyGame.GameFramework.AssetDataInfo.BundleEncryptOffset
CenturyGame.GameFramework.AssetBundleMgr / AssetBundleDownloadHandler / AssetHelper
CenturyGame.GameFramework.VersionManifestChecker.GetManifestMd5PrefsKey

→ 资源包采用偏移/异或加密 + MD5 清单保护。

③ 自研框架能力

CenturyGame.GameFramework.AssetModule / AtlasModule / CacheModule / AudioModule
CenturyGame.GameFramework.WebSocketProxy / BestHttpGetWork / HttpRequestWork / HttpGetAppVersion
CenturyGame.GameFramework.SDKModule.OnRequestIDFATrackingAuthorization
centurygame.IOS.*   (18 个类型, iOS 原生桥接)

④ 安全与风控相关符号

AntiCheatResult
isJailbreak / isJailbroken / _jailbrokenStatus / setJailbrokenStatus:
isDebuggerAttached / isDebuggerAttachedToConsole
SC_DATA_TAMPERED  ("Invalid MAC - file may have tampered with!")
Cmd_GetDeviceId / DeviceID / GetIDFA / GetIDFV / CGIDFAAuthorizationStatus
ConstDefine.DeviceID / GameConfig.DeviceID
GetManifestMd5 / CalcMd5StringFromHash / CRC32

⑤ 实时通信 / 协议

com.fpnn.rtm / com.fpnn.msgpack / com.fpnn.proto   (FNNS RTM 即时通讯协议栈)
UnityWebSocket.Runtime
Protobuf (Google Protocol Buffers 3.29.5)
CenturyGame.GameFramework.BytePackHelper

6.3.4 网络端点(由字符串字面量还原,详见第 5 章)

从 19,294 条字面量中提取出的真实业务域名示例:

https://gofcn-prod-cdn.campfiregames.cn/RELEASE/          # 生产 CDN
https://gofcn-prod-cdn.centurygames.cn/RELEASE/
https://gofcn-qa-cdn.campfiregames.cn/{RELEASE,TEST}/     # QA CDN
https://gofcn-qa-cdn-1322302784.cos.ap-shanghai.myqcloud.com/...  # 腾讯云 COS QA
https://platform-config-prod.centurygame.com/config.json  # 平台配置
https://platform-config-sandbox.centurygame.com/config.json
https://clientversion.diandian.info/snapshot/             # 版本快照
https://devcenter.campfiregames.cn/api/devices            # 设备中心
https://gofcn-gm-api-prod.campfiregames.cn                # ★ GM/运营后台 API
https://gofcn-gm-api-test-out.campfiregames.cn
https://gofcn-gm-api.diandian.info

→ 其中 gofcn-gm-api*(GM 接口) 与 devcenter 属管理面域名,出现在客户端包内值得关注(虽通常另有鉴权,但域名与路径暴露扩大了攻击面)。


6.4 还原价值与影响#

  1. 符号级可读:还原后可直接得到所有类/方法/字段名,Unity 反编译工具(Il2CppDumper + IDA/Ghidra/Il2CppInspector)可无缝加载 global-metadata.dat,将原生代码函数与 C# 符号对应。
  2. 攻击面外扩:结合 DecryptLuaBytecode 与 BundleEncryptOffset 的还原,攻击者可进一步解密资源包与 Lua 字节码,从而修改玩法数值、资源或逻辑。
  3. 风控可描述:AntiCheatResult、越狱/调试检测、MD5 清单校验等机制被完整枚举,便于评估其绕过成本(多为客户端本地检测,绕过成本低)。

6.5 可复现命令#

# 1) 解包
unzip com.gof.china_1.15.6_und3fined.ipa -d extracted

# 2) 解密 global-metadata.dat(使用附录脚本,密钥 NTESCSLLVMPASSKEY)
python3 artifacts/decrypt_global_metadata.py \
    extracted/Payload/whiteoutsurvivalcn.app/Data/Managed/Metadata/global-metadata.dat \
    artifacts/global-metadata.dec.dat

# 3) 校验
xxd artifacts/global-metadata.dec.dat | head -1    # 期望: af1b b1fa 1f00 0000 ...
strings artifacts/global-metadata.dec.dat | grep -m1 UnityEngine.MonoBehaviour

自相关复现代码(关键片段)

import numpy as np
data = np.frombuffer(open("global-metadata.dat", "rb").read(), np.uint8)
sub = data[::7]
for L in range(1, 8193):
    print(L, np.mean(sub[:-L] == sub[L:]))   # 观察 612 及其倍数处的峰值

密钥恢复(众数法)

from collections import Counter
P = 612
key = bytes(Counter(data[i::P].tolist()).most_common(1)[0][0] for i in range(P))
# key 呈 17 字节周期 -> 取前 17: b"NTESCSLLVMPASSKEY"

07 · 风险汇总、攻击面与加固建议#

本章综合第 02–06 章的发现给出结论。风险等级:严重 / 高 / 中 / 低 / 信息。


7.1 描述性风险清单#

# 风险 等级 证据 影响
R1 global-metadata.dat 采用固定 17 字节周期 XOR(NTESCSLLVMPASSKEY)保护 中 第 6 章;两小时即可离线还原 全量 C# 符号泄露,IL2CPP 逆向门槛大幅降低
R2 玩法逻辑为加密 Lua 字节码,且解密方法名(DecryptLuaBytecode)与密钥派生(CalcEncryptKeyFromString)均暴露 高 luapackage_32/64_*.unity3d;CenturyGame.GameFramework.Helper.* 客户端逻辑与数值可被篡改,易催生作弊/私服/破解
R3 资源包仅用 XOR/偏移加密 + MD5 清单 高 EncryptXOR/1/2、BundleEncryptOffset、GetManifestMd5 资源可被替换/解包,皮肤与地图等资产泄露
R4 通知扩展 NSAllowsArbitraryLoads=true 高 PlugIns/.../Info.plist 扩展内任意 HTTP 明文流量,可被中间人劫持/注入
R5 主 App 未声明 NSAppTransportSecurity、未见证书固定 中 Info.plist 无 ATS 键;二进制无 SPKI pin 实现 依赖系统默认 ATS;对企业代理/证书场景缺乏二次防护
R6 生产包残留构建/发布脚本,含内网 Bitbucket 仓库与私有 Pod 源 oauth2: 引用 高 install/autoUpdateRepoPublic.sh、CenturyGameResources.bundle/merge.sh 供应链信息泄露,暴露内部命名/仓库/CI 结构,可能被用于投毒或社工
R7 大量可逆编码的密钥/配置硬编码于 ddCommon.json 中 secret*、tga、rum、adjust、constants、unity_config 密钥可逆 → 可伪造/解密对应 SDK 通道数据
R8 归因/广告/追踪 SDK 覆盖面大且声明与行为不一致 中 AdjustSdk/UnionOpenPlatformCore 隐私清单 NSPrivacyTracking=true,主清单 false 合规(审核/法律)风险
R9 客户端本地风控(网易易盾 NetSec:越狱/调试/模拟器/完整性检测)易被绕过 中 NetEase.NetSecProtect、AntiCheatResult、NetSecGetEmulatorName、isJailbreak、SC_DATA_TAMPERED 检测逻辑在客户端,绕过成本低,风控有效性有限
R10 管理面域名(GM API)出现在客户端 中 gofcn-gm-api-prod.campfiregames.cn 等 扩大攻击面,若鉴权薄弱可被探测
R11 存在 IFix 热更新 与 远程调试运行时 中 IFix.Core.dll(ilpatch/{0}.patch.bytes)、Debugger.dll、HdgRemoteDebugRuntime 动态补丁/调试通道若在生产可用,可被滥用篡改逻辑
R12 NSLocationWhenInUseUsageDescription = "empty" 等文案瑕疵 低 Info.plist 审核风险/用户体验
R13 NSAdvertisingAttributionReportEndpoint 尾部含零宽空格 U+200B 低/信息 已复现 'https://adjust-skadnetwork.com\u200b' 可能为拷贝失误,属质量缺陷
R14 mopub-sdk-id.json 含 154 条 SKAdNetwork ID 未合并进主 Info.plist 低/信息 第 2 章 归因测量可能不完整
R15 UnityFramework 内硬编码大量第三方 App 的 Bundle ID / 名称清单(微信、抖音、淘宝、竞品等) 中 二进制字符串中约 200+ 条 com.tencent.xin/com.ss.iphone.ugc.Aweme/com.tencent.mqq 等 疑似用于已安装应用探测/归因/竞品识别,涉及隐私与合规
R16 客户端内置完整 GM/作弊指令面(req_cheat_* 约 1,500+ 标识符) 高 req_cheat_add/recharge/query_database/change_sys_time/set_hero_level/finish_chapter/...、notify_cheat_record_info 若服务端未严格鉴权/白名单,可加道具/改数值/改系统时间/热更,属最高危越权面
R17 网络协议 schema 与全量配置以明文存于客户端(Lua 字节码常量) 中 request { owner 0 : integer } 等 2,635 条 op 定义 大幅降低协议逆向/伪造成本,利于中间人、重放与自动化脚本

7.2 攻击面总结#

                       ┌──────────────────────────────────────────────┐
   静态逆向 ─────────► │ ① global-metadata XOR  →  全量 C# 符号         │
                       │ ② AssetBundle XOR      →  资源/贴图/配置        │
                       │ ③ Lua 字节码加密        →  玩法逻辑            │
                       └──────────────────────────────────────────────┘
                       ┌──────────────────────────────────────────────┐
   运行时攻击 ───────► │ ④ 明文 HTTP(扩展)     →  MITM 注入            │
                       │ ⑤ 本地风控绕过          →  越狱/调试/内存修改    │
                       │ ⑥ 热更新/调试通道       →  动态代码加载          │
                       └──────────────────────────────────────────────┘
                       ┌──────────────────────────────────────────────┐
   供应链 ───────────► │ ⑦ 残留构建脚本/内网仓库 →  情报泄露             │
                       └──────────────────────────────────────────────┘

7.3 加固建议#

A. 数据与逻辑保护 1. IL2CPP 元数据改用强加密 + 完整性方案:如运行时密钥派生(结合设备/签名指纹)的 AES-GCM/ChaCha20,并校验 MAC;避免固定、可打印、可自相关的周期密钥。 2. Lua 字节码:自定义 VM/指令集 + 逐包密钥,密钥不落盘(由服务端下发或 KDF 派生),杜绝 CalcEncryptKeyFromString 这类静态可推导方式。 3. AssetBundle:在 XOR 之上叠加逐资源密钥 + 签名校验,并将关键数值/配置改为服务端权威。

B. 传输安全 4. 移除扩展的 NSAllowsArbitraryLoads,全站 HTTPS 并在主 App 明确声明 ATS 例外(如确需)。 5. 引入 证书/公钥固定(SSL Pinning) 或 mTLS,并对关键业务(登录、支付、下发配置)做端到端签名。

C. 风控 6. 将关键风控判断上移到服务端(行为序列、协议校验、回包签名),客户端检测仅作辅助。 7. 对客户端完整性(代码段/资源/Lua 包)做签名校验而非仅 MD5。

D. 供应链与合规 8. 从发布包中移除所有构建脚本、Podfile 片段、内网仓库引用与 OAuth token;发布流水线做产物白名单。 9. 统一 SDK 隐私清单与实际行为(NSPrivacyTracking),修正文案与 URL 转义(去除零宽字符),合并 SKAdNetwork 清单。 10. 管理面(GM/DevCenter)与客户端网络隔离,限制域名/接口可见性并强化鉴权与审计。


7.4 结论#

该样本的客户端加固属于"混淆型"而非"密码学型":核心保护(元数据、Lua、资源)均为可离线还原的可逆变换,其设计目标是提高自动化逆向的门槛,而非提供真正的机密性。配合未固定的传输信道、客户端本地风控与发布包内的供应链残留,整体呈现中高风险画像。

对于防守方,优先级排序为:R6(供应链泄露)> R2/R3(逻辑/资源可篡改)> R4(明文 HTTP)> R1/R7(元数据与配置可逆)> R8–R11(合规与风控)。


08 · 内购 / 充值系统(IAP)逆向分析#

目标样本:com.gof.china_1.15.6(无尽冬日 / Whiteout Survival 国服,Century Games) 引擎:Unity 2022.3.52f1 + IL2CPP + LuaJIT(XXLua 脚本层) 分析性质:授权安全研究 / 移动应用安全评估 证据来源(均只读):out_types.txt、out_identifiers.txt、out_literals.txt、lua/tokens.txt、lua/config_tables.txt、lua/ui_views.txt、lua/protocol_ops.txt、lua/lua_strings_32.txt、extracted/Payload/whiteoutsurvivalcn.app/ddCommon.json

取证说明(重要):lua_strings_32.txt 与 protocol_ops.txt 是从 Lua 字节码中按固定窗口抽取的常量/标识符,存在两类已知伪影: ① 标识符被左截断(如 notify_recharge_init 抽成 tify_recharge_init); ② 相邻字符串粘连。 因此本报告对每条 opcode 均以 lua_strings_32.txt 中带中文注释的原始记录为准,截断处如实标注为 …,不做补全臆测。凡是无法确证完整名称的,只给 opcode。


8.0 结论摘要(TL;DR)#

维度 结论
支付 SDK 自研 Unity.dd.sdk.scripts.payment.dll(Century Games DD SDK 8.0.5.0-GOFCN,cg 命名空间),仅 12 个类型,全部为原生插件薄包装
结算渠道 Apple IAP、Google IAB、Adyen、Amazon IAP、CN Media(国内媒体/渠道支付)、小游戏、官网 WebShop;CGPayment 是统一门面
StoreKit 未出现在 IL2CPP 托管元数据中(无 SKPayment/SKProduct/StoreKit 符号);SK/logic 位于原生插件,C# 侧仅通过 com_sdk_payment_appleiap_* 桥接
商品 ID 客户端未见任何硬编码 SKU/ProductId 字符串;配置层只用整数 payment_id / pay_id 索引,实际 productId 由 服务端下发(Lua PayRead:GetProductIds)
收据校验 由服务端承担(CGPaymentError.ErrorNotMatchUid / ErrorOriginalResponse / ErrorProviderOrderId、paymentServerApi、com_sdk_payment_getThroughCargo)
充值模块族 Lua 侧至少 20+ 个内购模块族(首充、活跃/每日、累计、累充抽奖、充值抽奖、连续、五日、月卡、月度、基金、充值商店、代币/代金券、多选礼包、可选礼包、活动礼包、订阅礼包、每日特惠、无限宝箱、宠物充值、尊享 VIP 累充、返利、网页商城等)
协议面 充值核心 op 段 6701–6708 / 6791;活动充值 11401–11427;连续充值 9951–9983;累充抽奖 20281–20292;月卡 9401 / 9451 / 9452;充值商店 20601
总体风险 中:客户端不下发可信价格/商品,主信任落在服务端;但协议与配置全明文、订单回执字段外露、req_cheat_* 含充值类作弊接口,仍存在篡改/重放/私服面

8.1 支付 SDK 面(Unity.dd.sdk.scripts.payment)#

8.1.1 程序集类型清单

在 out_types.txt 中该 DLL 仅导出 12 个类型(行 ##### Unity.dd.sdk.scripts.payment.dll (12 types)):

<Module>
centurygame.CGCnMediaOrderParam
IDelegate
<>c__DisplayClass50_0
centurygame.CGPayment
centurygame.CGUnFetchedProduct
centurygame.CGProduct
centurygame.CGSubscriptProduct
ResultHandler
centurygame.IOS.CGAppleIapIOS
centurygame.Abstract.BasePaymentWrapper
<PrivateImplementationDetails>

关联类型(定义在 CenturyGame.GameFramework.dll 区域,由 IL2CPP 生成的 ifix 包装): centurygame.CGPaymentError、CGPaymentDelegate、CGPaymentDelegateWrap、centurygame_CGPaymentWrap、centurygame_CGProductWrap、centurygame_CGSubscriptProductWrap、SDKEvent_SDKListProductEventWrap、SDKEvent_SDKListSubscriptProductEventWrap。

8.1.2 CGPayment 主要方法(init / pay / restore / query)

以下标识符来自 out_identifiers.txt(centurygame_CGPaymentWrap 及内部包装区域):

分类 标识符 说明
初始化 SetDelegate(com_sdk_payment_appleiap_setDelegate)、StartHelper、Trying to start payment helper.(字面量) 初始化支付助手
初始化回调 OnInitializeSuccess / OnInitializeError;Lua 事件 SDK_PAY_INIT_SUCCESS / SDK_PAY_INIT_ERROR 初始化结果
购买 Buy、BuyWithServerId、com_sdk_payment_appleiap_buy、com_sdk_payment_appleiap_buy_with_serverId、com_sdk_payment_server_buy 下单/支付;带 serverId 变体用于关单/归属
商品查询 RequestProductDetailsWithCurrency、ObtainProductDetailsWithCurrency、GetSupportCurrencyList、GetAdyenSupportCurrencyList、RequestProductDetailsWithCurrency 按币种拉取商品
未获取商品 OnUnfetchedProductResponseCallback、CGUnFetchedProduct、OnFetchStoreCountryCodeComplete / FetchStoreCountryCode 拉取失败/商店国家码
恢复/补单 checkOngoingSubscriptOrders / getOngoingSubscriptOrders、TryCompleteUnPayOrder、CompleteUnFinishPay(com_sdk_payment_completeunfinishpay)、SetThroughCargoForOngoingPurchases、get_NonPreOrderPurchasesCallback 恢复订阅、补发未完成订单(掉单补偿)
穿透/直购 RequestGetThroughCargoWithProviderOrderId / GetThroughCargoWithProviderOrderId(com_sdk_payment_getThroughCargo) 以第三方订单号穿透发奖
国内媒体支付 SetAndroidCnMediaPayOrderParam、centurygame.CGCnMediaOrderParam 安卓国内媒体渠道参数
Offer Code EnableOfferCodeOrderHandling、IsInAppOfferCodeRedemptionSupported、PresentOfferCodeRedemptionUI、SetOfferCodeThroughCargoForOngoingPurchases Apple Offer Code 兑换码
非消耗品 SetNonConsumptionProductIds / setNonConsumptionProductIds、CanMakePurchases 非消耗型商品与可购状态
服务端接口字段 paymentServerApi、PaymentServerApi、purchaseDataJson 指向服务端校验 API 的配置

CGPayment 内部原生桥方法名(out_identifiers.txt 连续区块,最直接的渠道证据):

CGAppleIapIOS
PaymentServerApi
getOngoingSubscriptOrders
setNonConsumptionProductIds
CompleteUnFinishPay
GetAdyenSupportCurrencyList
ObtainProductDetailsWithCurrency
GetThroughCargoWithProviderOrderId
com_sdk_payment_appleiap_setDelegate
com_sdk_payment_appleiap_canMakePurchases
com_sdk_payment_appleiap_startHelperWithProductIDs
com_sdk_payment_appleiap_buy
com_sdk_payment_appleiap_buy_with_serverId
com_sdk_payment_server_buy
com_sdk_payment_getOngoingSubscriptOrders
com_sdk_payment_completeunfinishpay
com_sdk_payment_getThroughCargo
com_sdk_payment_fetchStoreCountryCode
com_sdk_payment_enableOfferCodeOrderHandling
com_sdk_payment_isInAppOfferCodeRedemptionSupported
com_sdk_payment_presentOfferCodeRedemptionUI
com_sdk_payment_setOfferCodeThroughCargoForOngoingPurchases
BasePaymentWrapper

8.1.3 回调委托 CGPaymentDelegate

out_identifiers.txt 中 CGPaymentDelegate 的成员(含 *Event 的 UnityEvent 版本):

回调 语义
OnInitializeSuccess / OnInitializeError 支付初始化
OnPurchaseSuccess / OnPurchaseSuccessWithOrderId / OnPurchaseError 购买成功/带订单号成功/失败
OnCheckOngoingSubscriptOrders / OnCheckOngoingSubscriptOrdersError 订阅检查
OnCreateOrderIdComplete 订单号创建完成
OnGetThroughCargoWithProviderIdSuccess / ...Error 穿透发货
OnFetchAppleStoreFrontCountryCodeComplete 苹果商店国家码
OnCommonCallBack 通用回调

字段:products、productId、throughCargo、orderId、countryCode。

8.1.4 商品对象 CGProduct / CGSubscriptProduct

centurygame_CGProductWrap 暴露:

成员 说明
ProductId / GetProductId 商品 ID(运行时从商店/服务端获得)
Title / Description 标题/描述
PriceCurrencyCode / GetPriceCurrencyCode 币种代码
FormattedPrice / GetFormattedPrice 本地化价格字符串
Price / GetPrice 原始价格
Icon / currencyLable 图标与币种标签
FromGoogleIabMessage Google IAB 来源解析
FromAdyenPayMessage Adyen 来源解析
FromAmazonIapMessage Amazon IAP 来源解析
FromAppleIapMessage Apple IAP 来源解析
FromMiniGameMessage 小游戏来源解析

CGSubscriptProduct 额外含 <productId>k__BackingField、<createTs>k__BackingField(订阅创建时间)。

结论:CGPayment 是一个多渠道聚合门面,日常维护面覆盖 Apple / Google / Adyen / Amazon / 小游戏 / 国内媒体(CN Media)。Android 国服主渠道 = CN Media(SetAndroidCnMediaPayOrderParam + CGCnMediaOrderParam)。

8.1.5 支付错误对象 CGPaymentError

centurygame_CGPaymentErrorWrap 字段(out_literals.txt 同步可见 ErrorProductId / ErrorProviderOrderId / ErrorNotMatchUid / ErrorOriginalResponse、not_match_uid):

字段 含义
ErrorProductId 出错商品 ID
ErrorProviderOrderId 第三方(渠道)订单号
ErrorNotMatchUid 订单归属 UID 不匹配(关键的防串单/防重放字段,对应字面量 not_match_uid)
ErrorOriginalResponse 渠道原始回执(收据原文)
ErrorThroughCargo 穿透发货标记

以及 LogPayment / LogPayment productId is null 日志点。

8.1.6 StoreKit 证据

  • out_types.txt、out_identifiers.txt、out_literals.txt 中 检索不到 StoreKit、SKPayment、SKProduct、SKMutablePayment、SKPaymentQueue 等符号。
  • 只有 centurygame.IOS.CGAppleIapIOS 与 com_sdk_payment_appleiap_* 桥接名,以及日志 CGAppleIapIOSCommon called. iosDelegate = / CGAppleIapIOSCommon failed: {0}.。

结论:iOS 的 StoreKit 调用发生在原生插件内(CGAppleIapIOSCommon),IL2CPP 托管层只做薄包装,因此 StoreKit 逻辑不在 global-metadata.dat 可达范围内,需转向原生二进制分析。

8.1.7 Lua 侧 SDK 桥与事件

标识符 来源 说明
SDKHelper lua_strings_32.txt(SDKHelper、SDKHelper Buy、SDKHelper Init 等) Lua 调用 C# SDK 的统一入口
SDK_PAY_INIT_SUCCESS / SDK_PAY_INIT_ERROR lua_strings_32.txt 支付初始化事件
SDK_PAY_BUY_SUCCESS / SDK_PAY_BUY_ERROR lua_strings_32.txt 支付购买事件
OnPayInitSuccess / OnPayInitError / OnPayBuySuccess / OnPayBuyError lua_strings_32.txt 对应处理函数
OnPaymentInitializeSuccess / OnPaymentInitializeError / OnPaymentPurchaseSuccess / OnPaymentPurchaseError / OnPaymentPurchaseSuccessWithOrderId out_literals.txt C# 回调名
CGWebShop / centurygame.CGWebShop lua_strings_32.txt、out_identifiers.txt 官网网页商城
SDK_WEB_SHOP_QRCODE_SCAN_RESULT、SDK_WEB_SHOP_USER_AUTHORIZATION_RESULT、SDK_WEB_SHOP_USER_CANCEL_AUTHORIZATION_RESULT lua_strings_32.txt WebShop 授权/扫码事件
OnAppWebShopUserAuthorizationRequestReceived、ParseSDKPayloadJson lua_strings_32.txt 授权结果解析

Lua 侧还出现 pay.PayCtrl、PayCtrl、PayRead、GiftCtrl、GiftRead、payment_config、TraceData_Pay 等业务层符号。

8.1.8 支付错误码(Lua 内置,CGError*)

从 lua_strings_32.txt 完整抽取(这是客户端支付错误文案/码的权威集合):

错误码 标识符 语义
3000 CGErrorFailedToConnectToPaymentServer_3000 无法连接支付服务器
3001 CGErrorInvalidPaymentRequestData_3001 支付请求数据非法
3002 CGErrorFailedToParsePaymentResponse_3002 支付响应解析失败
3003 CGErrorPaymentResponseError_3003 支付响应错误
3004 CGErrorPaymentRequestError_3004 支付请求错误
3005 CGErrorAppleVerificationFailed_3005 苹果凭据校验失败
3006 CGErrorAppleVerificationTimeout_3006 苹果凭据校验超时
3007 CGErrorPaymentUninitialized_3007 支付未初始化
3008 CGErrorPaymentUserNotLogged_3008 用户未登录
3009 CGErrorPaymentPurchasing_3009 支付进行中
3200 CGErrorPurchaseFailed_3200 购买失败
3201 CGErrorProductsInfoInvalid_3201 商品信息非法
3202 CGErrorBuyProductIdInvalid_3202 无效的商品
3203 CGErrorNoLocalReceipt_3203 无本地收据
3204 CGErrorBuyCurrencyCodeInvalid_3204 币种代码非法
3205 CGErrorProductsIsError_3205 商品信息错误
3206 CGErrorProductsIsEmpty_3206 商品为空
3207 CGErrorPaymentCanceled_3207 支付取消
3208 CGErrorPaymentInvalid_3208 支付非法
3209 CGErrorPayment…NotAllowed_3209 用户不允许授权付款
3210 CGErrorStoreProductNotAvailable_3210 商店商品不可用
3211 CGErrorCloudServicePermissionDenied_3211 云服务权限拒绝
3212 CGErrorCloudServiceNetworkConnectionFailed_3212 云服务网络失败
3213 CGErrorCloudServiceRevoked_3213 云服务撤销
3220 CGErrorClientInvalid_3220 客户端非法
— err_payment_initialize_de… “支付初始化失败,请尝试重新登录或者联系客服”
— recharge_ui_022 “商品购买失败,请联系客服解决!”
— web_shop_err_1207 / 1201 / 121 / 2233 / 2234 / 2235 网页商城错误码

备注:CGErrorPayment…NotAllowed_3209 在抽取中出现左截断,但同源中可见完整文案“用户不允许授权付款”,码值 3209 可靠。


8.2 充值配置与模块(Lua 侧)#

8.2.1 内购相关配置表(config_tables.txt / game_config_default_*)

config_tables.txt 收录 1,599 个表名(抽取窗口 ~40 字符,长名被截断)。内购/礼包/商店相关表如下(原样引用):

表名(原样) 归属模块
game_config_default_recharge_shop_c…、game_config_default_recharge_shop_i… 充值商店(conf / item)
game_config_default_recharge_lo…、…recharge_lottery_c…、…recharge_lottery_guarant…、…recharge_lottery_rew…、…recharge_lottery_s… 充值抽奖
game_config_default_active_recharge_acti…、…active_recharge_activity_t…、…active_recharge_coll… 活跃/每日充值
game_config_default_month_recharge_c… 月度充值
game_config_default_month_integral_battle_p…、…month_integral_bp_rew… 月度积分战令
game_config_default_pet__recharge_c…、…pet_recharge_conf… 宠物充值
game_config_default_payment_frost_s… 支付(霜冻主题)
game_config_default_gift_activity_…、…gift_activity_gr…、…gift_activity_mod… 活动礼包
game_config_default_activity_gift_po… 活动礼包弹窗
game_config_default_optional_gift_p…、…optional_gift_pack_cont… 可选礼包
game_config_default_multiple_choice_p…、…multiple_choice_pack…、…multiple_choice_pack_cont…、…push_multiple_choice_* 多选礼包(含推送)
game_config_default_subscription_gift_con…、…subscription_gift_confi… 订阅礼包
game_config_default_daily_specials_g…、…daily_specials_gift…、…daily_specials_gr…、…daily_specials_hero_g…、…daily_specials_paym… 每日特惠
game_config_default_personal_gift_gr… 个人礼包
game_config_default_mobilization_gift_con…、…mobilization_gift_config… 动员礼包
game_config_default_birthday_gift_pre…、…sup_vip_birthday_g… 生日礼包
game_config_default_stove_skin_gift_c…、…stove_skin_gift_cli… 炉灶皮肤礼包
game_config_default_three_tiles_gift… 三消礼包
game_config_default_threedays_shop_c…/g…/i…/rew…/st… 三日商店
game_config_default_store_item_buy_li…、…store_item_sp_c…、…store_quick_buy_con…/confi… 商店通用购买
game_config_default_garden_token_shop_c…、…lord_skin_shop_c…、…lordskin_shop_cli…、…puzzle_shop_item… 各类主题商店
game_config_default_midasbuy_gift_cont… MidasBuy 商城礼包
game_config_default_red_packet_config…、…truck_escort_diamond_c…、…vip_extra_rewa…、…sup_vip_info_con… 红包/钻石/VIP
game_config_default_fes_battlepass_*、…battlepass…、…bp_* 战令(付费通道)

lua_strings_32.txt 直接出现 payment_config(支付配置表,运行时由 GConfig 读取)。

8.2.2 内购模块族枚举(≥20 族)

下表由 ui_views.txt(6,976 项)+ lua_strings_32.txt + tokens.txt 交叉确认(模块路径前缀亦可见于 ui_views.txt,如 game_module_ui_item_firstrecharge_FirstRechargePanel、game_module_logic_module_continuousrecharge_ContinuousRechargeCtrl、game_module_logic_module_welfare_MonthCardCtrl):

# 模块族 代表符号(证据)
1 基础充值 / 支付 RechargeCtrl、PayCtrl、PayRead、GiftCtrl、GiftRead、payment_config、pay.PayCtrl
2 首充 FirstRechargePanel、FirstRechargePopPanel/PopView、FirstRechargeHelper、first_recharge、GameConfig 字段 first_recharge_award、first_recharge_ts
3 活跃/每日充值 ActiveRechargeCtrl/Panel/Item、active_recharge_init、ACTIVE_RECHARGE_INIT
4 累计充值 AccumulativeRechargePanel、AccumulativeRechargeView、AccumulativeRechargePopupView、AccumulativeRechargeTierClaim、Accumulative_Recharge_Main_View
5 累充抽奖 AccRechargeLotteryCtrl、AccRechargeLotterySubView、AccRechargeLotteryTipView、AccRechargeLotteryGetMorePopupView、AccRecharge_Lottery
6 充值抽奖 RechargeMainView、recharge_lottery_*(配置)、REQ_RECHARGE_LOTTERY_DRAW_SUCCESS
7 连续充值 ContinuousRechargeCtrl/Panel、ContinuousRechargeValentinesDayPanel、continuous_recharge_info
8 五日充值 FiveDaysRechargeCtrl、FiveDaysRechargeMainSubView、FiveDaysRechargeRewardChoosePanel、FiveDaysRechargeGiftItem
9 月卡 MonthCardCtrl、MonthCardPanel、MonthCardRewardPopupView、WelfareMonthCardPanel、MonthCardDefine/Read、month_card
10 月度充值 month_recharge 配置、month_integral_bp_*
11 充值基金 FundCtrl、SnowFundCtrl、WelfareFundPanel、fx_recharge_fund_diamond_jxm、charge_fund_equip
12 充值商店 RechargeShopCtrl、RechargeShopSubPanel、RechargeShopItem、RechargeShopHelper/Define、recharge_shop_conf、recharge_shop_item
13 代币/代金券充值 GiftRechargeTokenPanel、IsShowRechargeTokenPanel、voucher_id、pay_id/pay_type/num/name/tokenPrice
14 多选礼包 MultipleChoicePackCtrl/Panel/PopupView、PushMultipleChoicePackCtrl/Panel
15 可选礼包 OptionalGiftCtrl/Panel、optional_gift_pack_*、OptionalGiftItem、gift_subgroup
16 活动礼包 ActivityGiftCtrl、ActivityGiftLinkageMonopolySlapFacePopupView、gift_activity_*
17 订阅礼包 subscription_gift_con/confi
18 每日特惠 daily_specials_*(含 daily_specials_payment)
19 无限/无双宝箱 InfiniteBoxCtrl、InfiniteBoxPopupItem、InfiniteBoxPopUpView、GetInfiniteBoxPayCfg
20 尊享 VIP 累充 svip_recharge_reward_info、SupVipBirthday、get_recharge_reward
21 返利/回馈 PaybackCtrl/PaybackView、OpenPaybackView、Payback_Gift
22 网页商城 CGWebShop、SettingsWebShopLoginAuthorizationView、OpenAppWebShopLoginAuthorizationView
23 通用礼包系统 GiftPanel、GiftSubPanel、GiftBagSinglePanel、GiftTrigger*、MoreGiftView、CommonGetMoreGiftView

计数:ui_views.txt 中含 Recharge 37 项、Gift 157 项、Shop 20 项、Store 84 项、MonthCard 9 项;tokens.txt 中 Recharge 相关 937 条、Gift 2,804 条。模块族按 母功能 归纳为 23 族(含通用礼包系统)。

8.2.3 关键数据结构(协议 schema,含中文注释)

从 lua_strings_32.txt 抽取到的充值/礼包相关字段定义(原样):

payment_id            4 : integer
ori_price             11 : integer
cur_order             4 : integer
total_recharge_diamond  4 : integer          # 累计充值钻石
total_recharge_times    3 : integer
first_recharge_award    2 : *boolean          # 首充奖励情况
first_recharge_ts       2 : integer           # 首充时间
total_recharge_amount   0 : integer(0)        # 累计充值金额(美[元])
recharge_amount         ? : integer           # 首充金额(nil 设为非首…)
buy_gift_mark           6 : *mark()           # 购买标记, key=or…
conf_map                0 : *gift_config
card_info               0 : month_card         # 月卡数据
cardList                0 : *month_card       # 月卡列表
data                    0 : recharge_data
gift_order              ? : …
recharge_idx            ? : …
ori_diamonds_price      ? : …
index                   1 : integer           # 档位,对应配置表 index

充值商店配置注释:index 1: integer # 物品组在 recharge_shop_item 表中的下标;cost_currency(recharge_shop_conf 的消耗货币字段)。

代币/代金券礼包配置(pay_id 维度):Parent _giftPrice _giftPayId TxtTokenPrice GetResIcon ImgToken pay_id pay_type num name。


8.3 服务端 / 协议流程#

8.3.1 相关 opcode(来自 protocol_ops.txt + lua_strings_32.txt 中文注释)

下列 opcode 与名称已在 lua_strings_32.txt 的带注释记录中交叉验证;被左截断的记录以 … 标注。

opcode 名称 中文注释/语义
6701 notify_recharge_init 充值系统初始化/同步
6702 notify_buy_diamond_success 购买钻石成功
6704 notify_recharge_fail 充值失败
6705 req_recharge_get_first_reward 领取首充
6706 …ative_reward(截断) 领取累充奖励
6707 req_recharge_by_voucher 代金券充值
6708 req_recharge_by_token 代币充值
6791 req_beta_test_recharge 内测充值(测试/作弊口)
7405 req_remove_gift_group 移除礼包组
7406 notify_gift_config(gift_config) 通知礼包配置
7431 req_gift_buy_free_gift 购买免费礼包
9401 req_month_card_get_daily_reward(_month_card_get_daily_reaward) 领取月卡每日奖励
9451 notify_month_card_info 月卡数据通知
9452 notify_month_card_active 月卡开放或购买通知
9951 req_continuous_recharge_daily_reward 连续充值领取每日奖励
9981 notify_continuous_recharge_info 连续充值同步活动信息
9982 notify_continuous_recharge_update(…ous_recharge_update) 更新充值金额
2001 req_store_quick_buy(…uick_buy) 商店快捷购买
2003 req_shop_buy 商店购买
2004 req_shop_refresh 商店刷新
11401 req_get_active_recharge_quest_reward 活跃充值任务领奖
11402 active_recharge_score_reward 领取宝箱奖励
11426 active_recharge_init 同步数据
11427 notify_update_active_recharge_quest 活跃充值任务更新
11451 multiple_choice_pack_get_free_box 多选礼包免费盒
11476 notify_multiple_choice_pack_init 多选礼包初始化
11477 notify_multiple_choice_pack_buy_success 多选礼包购买成功
13629 req_vip_customize_buy_success VIP 自选购买成功通知
13631 svip_recharge_reward_info 尊享 VIP 累充奖励
17126 notify_snow_fund_purchase 购买通行证(基金)通知
17602 notify_pick_one_gift_recharge_success 自选礼包充值成功
20281 req_recharge_lottery_draw 充值抽奖
20282 req_recharge_lottery_acc_box 领取积分进度奖励
20291 notify_recharge_lottery_info 抽奖活动数据
20292 recharge_lottery_point_update(…harge_lottery_point_update) 抽奖积分更新
20601 req_recharge_shop_buy_item 购买充值商店物品
20896 notify_daily_claim_pay_success 购买特权成功
21131 req_activity_gift_popup_claim 活动礼包弹窗领取

其他相关:notify_recharge_new_token_success、notify_recharge_shop_update_integral、REQ_FIVEDAYS_RECHARGE_*、notify_fes_bp_purchase(11683)、notify_fes_bp_dailytask_purchase(13782)、notify_fishing_bp_purchase(13482)、notify_back_bp_purchase(15212)、notify_frozen_soil_purchase(13232)、notify_lost_treasure_purchase(12912)、_gift_by_diamond(12301, 钻石购买礼包)、req_super_vip_get_free_reward(13603)、req_vip_birthday_reward_push(13630)。

8.3.2 客户端 → 服务端 购买/校验流程(推断)

综合 CGPayment 回调链、Lua 事件与协议面,典型流程为:

[客户端]
  1. 玩家点击购买(PayCtrl:Buy / OnClickBuy)
  2. 客户端仅持有整数 payment_id / pay_id(来自 payment_config / 礼包配置)
  3. 向服务端请求“下单/取商品” ──► op 6701 notify_recharge_init / 充值初始化
                                     (PayRead:GetProductIds 取得 productId 列表)
  4. 服务端返回 productId + ServerId/orderId,客户端调 SDK:
        CGPayment.Buy(productId) / BuyWithServerId(productId, serverId)
        └─ iOS: com_sdk_payment_appleiap_buy[_with_serverId](原生 StoreKit)
        └─ Android 国服: SetAndroidCnMediaPayOrderParam + CN Media 渠道支付
  5. 渠道回调 → OnPurchaseSuccessWithOrderId(orderId) / OnPurchaseError
        Lua 事件:SDK_PAY_BUY_SUCCESS / SDK_PAY_BUY_ERROR
[服务端]
  6. 客户端携带 purchaseDataJson / receipt 调 paymentServerApi
        └─ com_sdk_payment_getThroughCargo(以 providerOrderId 穿透发货)
  7. 服务端向渠道(Apple/Adyen/…)校验收据,比对 uid
        └─ 失败字段:ErrorNotMatchUid / ErrorOriginalResponse / ErrorProviderOrderId
  8. 发货 → notify_buy_diamond_success(6702) / notify_recharge_fail(6704)
        + notify_total_recharge_amount / notify_month_card_active / 各活动 notify_*
[补偿]
  checkOngoingSubscriptOrders / TryCompleteUnPayOrder / CompleteUnFinishPay
        (订阅恢复、掉单补发)

结论:真正的发货决策在服务端(比对 uid、校验渠道回执)。客户端的 CGPayment 仅负责“唤起渠道收银台 + 回传凭据”,符合业界做法,但也意味着所有信任锚点在服务端的收据校验实现质量上。


8.4 商品 / SKU / 价格证据#

8.4.1 是否存在硬编码 Product ID?

  • out_literals.txt / out_identifiers.txt 中没有任何 com.gof.china.* 形式的商品 SKU;com.gof.china 只作为 GlobalDefine 的包名出现(与 OpenAppStore、SDKHelper 同区)。
  • 唯一与商品相关的字符串是运行时字段与错误:productId、product_id、ProductId、`productId must not be empty.、LogPayment productId is null`。
  • 配置层以整数 payment_id(payment_id 4 : integer)与 pay_id / pay_type 索引,而非字符串 SKU。

明确结论:商品 ID(ProductId/SKU)由服务端下发(Lua PayRead:GetProductIds;CGPayment.paymentServerApi 指向服务端支付 API)。客户端不内置可信商品表,属正向设计。

8.4.2 价格 / 档位方案

证据 说明
ori_price 11 : integer 礼包配置的原价(整数,非浮点,疑似最小货币单位/角分)
ori_diamonds_price 钻石礼包原价(与 reward_group、gift_order 同区,见 activities_infinite_box_* 配置常量)
tokenPrice / _giftPrice / TxtTokenPrice 代币/代金券礼包价格
discount / TxtPrice / TxtOriginalPrice 折扣与现价展示
total_recharge_amount 0 : integer(0) # 累计充值金额(美…) 累计充值金额(注释指向“美元”,单位疑为分)
recharge_amount # 首充金额(nil 设为非首…) 首充金额字段
index 1 : integer # 档位,对应配置表 index、id 0 : integer # 奖励档位 “档位”以配置表 index/奖励组表达
0%、30%、50%、70%、90%五个档位 某活动档位示例(一档多奖励)
# 已购买到的档位序号 累充档位购买状态
1265 # 设置首充金额账号(req_cheat_set_bind_account_1265) 服务端/作弊口可设置首充金额

首充/月卡中文文案证据:首充(10 处)、月卡(16 处)、礼包(285 处)、档位(40 处)、充值(76 处)、代金券(3 处)、钻石(162 处)、订单(9 处)、支付(24 处)。例如: - 首充:_name}</color>通过首充豪礼,获得传说级英雄…、完成首充后开启、首充奖励 - 月卡:已购买的周卡/月卡奖励、超值月卡优惠券(%{num1})、情报月卡-充值奖励、月卡奖励可在… - 代金券:req_recharge_by_voucher 6707 { # 代金券充值、…档位的礼包时,可消耗该代金券进行全额抵扣。

8.4.3 币种 / 本地化价格

  • GetSupportCurrencyList / GetAdyenSupportCurrencyList(CGPayment)
  • GetPriceByCurrencyCode、GetPriceCurrencyCode、FormattedPrice(CGProduct)
  • 字面量 GetPriceByCurrencyCode->Error:{0}、Currency2CultureDic、Currency2CultureListDic、CurrencyHelper、InitCurrencyCodeToCulture

即:多币种由 SDK 向渠道查询(RequestProductDetailsWithCurrency),客户端用 FormattedPrice 展示;因此本地展示价不等于服务端发货依据。

8.4.4 渠道/账号类型(FPAccountType*)

out_identifiers.txt 中支付相关账号类型:FPAccountTypeApple、FPAccountTypeAlipay、FPAccountTypeCnMedia、CGAccountTypeUtils、AuthorizeVipMallUserBean。

ddCommon.json(应用级配置,部分值为可逆编码/加密 blob):

键 值
platform.android.android_package_name com.gof.china
platform.*.game_id 20173
platform.*.china True
platform.android.wechat_app_id wx32374c9038cf9759
platform.ios.douyin_client_key awebivvetg90lv93
platform.android.bugly_id / platform.ios.bugly_id 1ea45351f9 / 341c16d88c
adjust / secret* / tga / rum / umbra_gateway / unity_config 均为 16 进制 blob(可逆编码/加密,详见第 02/05 章)

App Store 链接(out_literals.txt):apps.apple.com/cn/app/…/id6478492012;支付文档残留:官网链接:https://docs.open.alipay.com/。


8.5 商店 / 礼包 UI(ui_views.txt)#

功能 关键 View / Panel / Ctrl
主充值入口 RechargeMainView、RechargeCtrl、RechargeShopSubPanel、CanSeeInRechargeView、GiftRechargeTokenPanel
首充 FirstRechargePanel、FirstRechargePopPanel、FirstRechargePopView
活跃/累计 ActiveRechargeCtrl/Panel、AccumulativeRechargePanel、AccumulativeRechargePopupView、Accumulative_Recharge_Main_View
累充抽奖 AccRechargeLotteryCtrl、AccRechargeLotterySubView、AccRechargeLotteryTipView、AccRechargeLotteryGetMorePopupView
连续/五日 ContinuousRechargeCtrl/Panel、FiveDaysRechargeCtrl、FiveDaysRechargeMainSubView、FiveDaysRechargeRewardChoosePanel
月卡 MonthCardCtrl、MonthCardPanel、MonthCardRewardPopupView、WelfareMonthCardPanel、WelfareMonthCardDiscountPopupView
基金 FundCtrl、SnowFundCtrl、WelfareFundPanel、OpenBuyFundView
商店 StoreMainView、StoreCtrl、AllianceShopView、LordSkinStorePanel、GardenStoreMainView、PuzzleStorePopupView、CommonExchangeStoreView
礼包 GiftPanel、GiftSubPanel、GiftBagSinglePanel、MoreGiftView、OptionalGiftPanel、MultipleChoicePackPanel、PushMultipleChoicePackPanel、CommonGetMoreGiftView
活动礼包 ActivityGiftCtrl、ActivityGiftLinkageMonopolySlapFacePopupView、HeroTurntablePackageDetailView、PolarExpeditionPackageDetailView
VIP 相关 VipPrivilegeStoreSubView、VipExclusiveGiftPackageSubPanel、SuperVip*
网页商城 SettingsWebShopLoginAuthorizationView、OpenAppWebShopLoginAuthorizationView、ShowStoreView、ShowPackageDetailView
返利 PaybackCtrl、PaybackView、OpenPaybackView
钻石相关 DiamondView、ActivityDiamondStorePanel、BuyItemUseLargeDiamondSurePopView、OpenDiamondBuyRewardView

顶部模块路径证据(ui_views.txt 原样,证明模块归属):

game_module_logic_module_continuousrecharge_ContinuousRechargeCtrl
game_module_logic_module_welfare_MonthCardCtrl
game_module_ui_item_firstrecharge_FirstRechargePanel
game_module_ui_item_gift_GiftBagFishingSinglePanel
game_module_ui_view_chat_ChatGifEmojiGiftPopupView

8.6 风险分析(内购专章)#

8.6.1 风险清单

# 风险 等级 证据 影响
IAP-R1 协议与配置全明文:充值 op、字段、错误码、礼包配置均可从 Lua 字节码还原 中 本报告 8.2–8.3;req_recharge_by_token 6708、payment_id 等 大幅降低伪造成本,利于自动化脚本/中间人
IAP-R2 订单回执链路过客户端:purchaseDataJson、receipt、orderId 经客户端回传服务端 中高 purchaseDataJson、OnPurchaseSuccessWithOrderId、com_sdk_payment_getThroughCargo 若服务端校验不严(仅信任客户端字段),可伪造/重放过期收据
IAP-R3 客户端存在充值类作弊接口 高 …_cheat_recharge(1211, “礼包测试接口”)、req_beta_test_recharge(6791)、req_cheat_add_total_recharge_diamond(14169)、…_cheat_set_bind_account(1265, 设置首充金额) 若服务端未按权限白名单拦截,可直接刷累充/首充金额,绕过真实支付
IAP-R4 价格/商品非客户端可信(正向设计,但依赖服务端) 中 price/FormattedPrice 仅展示;productId 服务端下发 客户端改价无效;但服务端若回退信任客户端上报金额,则可低价购高价值礼包
IAP-R5 UID 串单/重放防护仅见字段名 中 ErrorNotMatchUid、not_match_uid、ErrorOriginalResponse 需在服务端验证“订单↔UID↔商品↔金额”四元绑定;仅靠字段存在不能证明已实现
IAP-R6 StoreKit 逻辑在原生插件,托管层不可见 信息 CGAppleIapIOSCommon、com_sdk_payment_appleiap_*;无 SKPayment 符号 常规 IL2CPP 审计无法覆盖 iOS 收银台细节,需原生逆向
IAP-R7 重打包(repack)后仍可通过 CN Media/渠道复位 中 SetAndroidCnMediaPayOrderParam、FPAccountTypeCnMedia、FPAccountTypeAlipay 第三方渠道回调的签名/来源校验若薄弱,可被中间人伪造回调
IAP-R8 官网 WebShop 授权链路暴露 中 CGWebShop、SDK_WEB_SHOP_USER_AUTHORIZATION_RESULT、AuthorizeUserWithParam/CancelAuthorizeUser WebShop 授权 token 若在客户端生成/校验,可被复用或劫持
IAP-R9 多币种/跨区价格由 SDK 查询,若服务端以本地展示价结算 低中 RequestProductDetailsWithCurrency、GetPriceByCurrencyCode->Error:{0} 跨区套利/价格错配风险

8.6.2 攻击者视角(可做什么)

  1. 协议重放/伪单:抓取 purchaseDataJson / orderId,若服务端对同一 providerOrderId 未做幂等或 uid 绑定校验,可重复提交(→ 依赖 ErrorNotMatchUid 的实际实现)。
  2. 作弊接口越权:直接构造 …_cheat_recharge(1211) / req_cheat_add_total_recharge_diamond(14169) / …_cheat_set_bind_account(1265),若缺少服务端权限判定,可凭空获得累充/首充权益(最高危)。
  3. 假渠道回调:针对 CN Media / Alipay 回调,若未强校验渠道签名与商户号,可伪造“支付成功”。
  4. 补单滥用:滥用 CompleteUnFinishPay / TryCompleteUnPayOrder / checkOngoingSubscriptOrders 触发重复发货。
  5. 改价展示欺骗:本地改 FormattedPrice 仅影响 UI,无法直接获益(除非服务端信任客户端上报金额)。
  6. 私服:既然商品 ID 由服务端下发且协议明文,搭建私服可自定义 payment_config 与发货逻辑,绕开官方计费。

8.6.3 加固建议(面向厂商)

  • 收据校验全部服务端化:校验 Apple/渠道收据签名链、providerOrderId 唯一性、uid↔商品↔金额 四元绑定,落实 ErrorNotMatchUid 语义。
  • req_cheat_* / req_beta_test_recharge 在生产环境禁用或强制 GM 白名单+审计。
  • 客户端 payment_id 仅作索引,服务端按 ID 查表定价;永不信任客户端上报金额。
  • CN Media/Alipay 回调强制渠道签名验签 + 商户号/应用号比对 + 时间戳防重放。
  • 补单接口加幂等键(providerOrderId)与频率限制。
  • WebShop 授权 token 使用服务端签发的一次性授权码,绑定 UID 与有效期。
  • 对关键支付事件(6701/6702/6704/6705)做完整性校验与异常告警(数量、金额、UID 维度)。

8.7 附录:证据文件与关键符号对照#

类别 文件 关键符号
支付 DLL 类型 artifacts/out_types.txt Unity.dd.sdk.scripts.payment.dll、centurygame.CGPayment、CGAppleIapIOS、CGCnMediaOrderParam
支付方法/回调 artifacts/out_identifiers.txt Buy、BuyWithServerId、CompleteUnFinishPay、com_sdk_payment_*、CGPaymentDelegate
字面量/日志 artifacts/out_literals.txt `productId` must not be empty.、Trying to start payment helper.、paymentDict:、GetSupportCurrencyList
Lua 配置表 artifacts/lua/config_tables.txt game_config_default_recharge_shop_*、…gift_activity_*、…month_recharge_c*
Lua UI artifacts/lua/ui_views.txt FirstRechargePanel、MonthCardCtrl、RechargeShopSubPanel、AccRechargeLotteryCtrl
Lua 协议 artifacts/lua/protocol_ops.txt + lua_strings_32.txt 6701..6708、9401/9451/9452、20281..20292、20601
App 配置 extracted/.../ddCommon.json com.gof.china、game_id=20173、wechat_app_id、secret*

免责声明:本报告依据已脱壳样本的静态证据撰写,仅用于授权的移动应用安全评估与防护改进,不含任何可直接用于非法牟利的具体攻击载荷。所有标识符/opcode 均来自上述只读证据文件,截断处已以 … 标注,未作补全臆测。


09 · 玩法 / 系统架构分析(Gameplay / Systems Architecture)#

目标:com.gof.china 无尽冬日(Whiteout Survival 国服)1.15.6 引擎:Unity 2022.3.52f1 + IL2CPP;游戏业务逻辑位于 LuaJIT 字节码(luapackage_32/64),已还原为 Lua 文本后抽取符号 数据来源(只读证据,均位于 artifacts/lua/):

证据文件 规模 说明
tokens.txt 252,026 行 Lua 标识符(含 game_module_* 模块路径、方法名、视图名)
protocol_ops.txt 2,635 条 操作码<TAB>协议名(网络消息路由表)
ui_views.txt 6,977 个 View / Panel / Ctrl 类名
config_tables.txt 1,600 张 配置表名(game_config_*)
lua_strings_32.txt 386,532 行(~602k 可打印串) 原始常量;内含协议 DSL 文本
../../artifacts/out_types.txt 8,649 行 IL2CPP 各程序集类型(C# 侧)

数据质量说明:LuaJIT 字符串池抽取时存在定长截断,部分 token / 协议名首尾被截(如 req_ → eq_/q_,alliance → lliance)。因此下文所有计数均为证据内可见值,关键结论附原始条目。


1. 模块架构:game_module_logic_module_* 家族#

1.1 命名规范

一套 game_module_<层>_<系统>_<子模块>_<类名> 的路径式命名,层级为内嵌 Lua 模块树:

前缀 token 数 含义
game_module_logic_module_ 1,367 业务逻辑模块(Controller / Data / Model)
game_module_logic_proxy_ 18 逻辑代理(跨模块/跨服桥接)
game_module_scene_ 1,726 场景/表现层(世界地图、雪场、战斗、花园…)
game_module_ui_ 8,143 UI 层(view=3,222 / item=4,892 / component=12)
game_module_btree_ 122 行为树 / 引导(action / precondition / ctrl / base)
game_module_hfsm_state_ 53 分层状态机-状态(怪物/花园/钓鱼/塔防 AI)
game_module_hfsm_condition_ 46 分层状态机-条件
game_module_httpdownload_ / game_module_load_ 11 / 4 资源下载与加载

game_module_logic_module_ 下共有 196 个顶层系统家族(按第 3 段去重)。

1.2 家族规模(token 数 Top,去截断后)

家族 token 家族 token 家族 token
activity 323 arsenalleague 19 hero / dress / buff 6 each
world 220 pitchpot 18 kingdomcard / mail 6
alliance 50 chat 17 linkagemonopoly / soldier 6
arsenalwar 32 trianglewar 15 truck / icefieldhunter 5
overview 31 city 14 digtreasure / firecrystalscience 5
supremacywar 30 slg3league / pet / gift 12 favorites 11
minewar 25 player / findinggame / equip 10 garden 20
expert / brawlwar 22 thanksgiving / supremacywaractivity / slotmatrix 8 settings 7

1.3 按系统分组(含代表类名与 moduleDefine)

系统域 家族 代表类(证据原文 token)
城市 / 建造 city, cityfield, citygain, homeland city_CityC, city_GateC, city_SurvivorC, city_SnowGuideCtrl, city_PivotFightCtrl;ConstructDef/FurnitureDef/DecorationDef/CityGainDef
资源 / 背包 / 队列 backpack, queue, store, valueexchange backpack_BackpackC, queue_QueueC, store_StoreC/StoreGoodsI/StoreI;BackpackDef
英雄 / 招募 / 装备 / 宠物 / 专家 hero, hero_train, equip, recruite, pet, expert, lordcollection hero_HeroC/HeroD, equip_heroequipc, recruite_RecruitC, pet_PetC/PetAdventureC, expert_ExpertC;HeroEquipDef/RecruitDef/LordEquipmentDef/LordCollectionDef/ExpertTravelDef
战斗 / 军队 / 兵种 soldier, arena, brawlarena, climbtower, worldboss, purifying soldier_SoldierC/SoldierD/BarrackC, arena_ArenaC, climbtower_ClimbTowerC, worldboss_WorldBossC, purifying_PurifyC;SoldierDef/BarrackDef/AttributeDef
联盟 / 军团 / 军械库 alliance, allianceinfo, alliancescience, alliancedevelopment, alliancewhitelist, arsenalleague, arsenalwar, arsenalleaguehonour alliance_AllianceC/AllianceBuildingC/AllianceChestC/AllianceDuelC/AllianceHelpC/AllianceMemberC/AllianceMobilizationC, arsenalleague_ArsenalLeagueTaskC;AllianceDef/AllianceBossDef/AllianceDuelDef/AllianceScienceDef/AllianceVoteDef/ArsenalWarDef/ArsenalLeagueCompetitionDef
世界地图 / 行军 (March) world, world_march, world_mapobj, capitalwar world_WorldMapC/WorldMapCapitalC/WorldMapFogC/WorldMapFortC/WorldPlayerC/WorldAutoAttackMonsterCtrl;world_march_WorldMarchC,WorldMarchDataFactory,WorldBaseMarchD;world_march_map_MapAttackCityMarchD,MapCollectMarchD;world_mapobj_data_MapMonsterD/MapResourceD/MapCapitalD;CapitalPresident;WorldMarchDef/WorldMarchDefine/SupremacyWarMapDef/WorldBossDef/MineWarMapDef/BrawlWarMapDef/TriangleWarMapDef/ArsenalWarMapDef
活动 / 运营(最大域) activity + 129 个 activity_data_*(activity_data_ 前缀下 129 个去重关键词) activity_ActivityC, activity__eventcalendar, activity_DivinationRoomCtrl, activity_PinballC, activity_MineWarC, activityaccumulative_AccumulativeActivityC;ActivityDef/CalendarDef/PolarExpeditionDef/PickDef/TrialOfSurvivalDef/DigTreasureDef
社交 / 聊天 / 邮件 / 好友 chat, mail, friend, favorites, playercard, opinion chat_ChatC/ChatD/ChatCtrl/ChatProxyC/ChatGroupVoteC, mail_MailC/MailD/MailShareD, friend_FriendC, favorites_FavoritesC;ChatDef/OpinionDef/PresetEmojiDef
抽卡 / 转盘 / 扭蛋 heroturntable, festivalturntable, slotmatrix, pitchpot, monopoly heroturntable_HeroTurntableC, slotmatrix_SlotMatrixC/SlotMatrixBroadcastD, pitchpot_PitchPotGameC, monopoly_MonopolyC;HeroTurntableDef/FestivalTurntableDef/SlotMatrixDef/MonopolyDef
任务 / 引导(BTree) guide, mission, radar, todo, development + game_module_btree_* guide_GuideC, mission_MissionCtrl/MissionData, radar_RadarQuestC, todo_ToDoListC, BTreeNodeCtrl;RadarDefineF/ToDoListDef;545 张 game_config_btree_guide_* 表
小游戏 / 休闲 fishing, garden, gardenguide, knifehit, findinggame, puzzle, minigame, snowclean, duckmarket, pitchpot fishing_FishingCompetitionC/FishingRankC, garden_GardenC/GardenGodownBaseC/LifeTreeD/LogCampD/SawmileD, snowclean_SnowCleanC, duckmarket_DuckMarketC;FishingCompetitionDef/SnowCleanDef/SnowFundDef/FindingGameDef/KnifeHitDef
科技 / 养成 / 数值 science, refinescience, firecrystalscience, research, buff, splitasset science_ScienceC, purifying_PurifyC, buff_BuffC, splitasset_SplitAssetCtrl;RefineScienceDef/FireCrystalLeakDef/AttributeDef
经济 / 商业化 pay, recharge, rechargeshop, fivedaysrecharge, continuousrecharge, bank, welfare, vip, supervip, gift, customgift, dailydeal pay_PayC, bank_BankC, vip_VipPrivilegeC, supervip_SuperVipC;VipPrivilegeDefine/RechargeDefin/RechargeShopDef/MonthCardDefine/CustomGiftDef/OptionalGiftDef
系统底座 system, login, settings, abtest, versionup, translate, unlock, rank, overview, cheat system_HeartbeatC/OnlineC/SubHeartbeatC, login_LoginC/LoginUnlockC, settings_RecordHttpManager/LikeC, abtest_ABTestC, translate_TranslateCtrl, rank_RankC/RankD, overview_OverviewWorldMap…(31 个 overview 家族), cheat_CheatC/SimulationNet…;SettingsDef/LockConditionDef/ViewHelperDef

逻辑代理层(game_module_logic_proxy_,共 7 组):activity_ArsenalLeagueGuessProxy / MagicPotionProxy / MineWarProxy、fishing_FishingProxy、minewar_MineWarMapProxy、pet_PetAdventureProxy、redpacket_RedPacketProxy、thanksgiving_ThanksgivingProxy、trianglewar_TriangleWarMapProxy —— 说明存在跨服/跨活动数据桥接的独立代理层。


2. 网络协议地图(protocol_ops.txt,2,635 条)#

消息名前缀规范:req_*(请求)/ notify_*(服务端推送)/ 少量 res_*、ack_*、rsp_*、push_*、sync_*。操作码(opcode)分布于多个区间段(如 1xxx 基础、5xxx 联盟/世界、9xxx–1xxxx 活动/王城、2xxxx–3xxxx 新版运营)。

方向统计(受定长截断影响,为可见值):req_* ≈ 1,083,notify_* ≈ 514,其余为前缀被截断条目。

2.1 域统计表(关键词匹配;跨域可能重叠)

域 #op 代表 op(操作码)
alliance 联盟 292 notify_alliance_member_pos_update(5179)、req_alliance_whitelist_add(5147)、req_alliance_showdown_invite_apply(9810)、req_alliance_change_leader(5113)
arsenal 军械库/联盟战争 123–140 req_alliance_arsenal_war_dispatch(11905)、req_arsenal_league_wall_outfire(11854)、req_alliance_arsenal_league_sign_up(30524)、req_arsenal_league_guess_bet_champion(30474)
supremacy 霸权战 121 notify_supremacy_war_alliance_info_update(20651)、req_supremacy_war_task_reward(16571)、req_supremacy_war_extra_situation_info(16629)
world / march 世界·行军 157 req_world_march(5701)、req_world_march_speedup(5703)、req_world_mass_master_detail(5708)、notify_world_player_init(5651)
quest 任务 85 req_mobilization_get_quest(10151)、req_back_quest_get_score_reward(15152)、req_get_chapter_award(3901)
rank 排行 74 req_most_lords_rank(10502)、req_cross_most_lords_rank(12803)、req_frostfire_war_center_rank(13316)
sign / 战令(BP) 66 req_general_bp_get_all_reward(15472)、req_back_bp_get_all_reward(15202)、req_thanksgiving_bp_get_all_reward(15682)
spectator 观战 63 req_spectator_supremacy_war_enter(17001)、rsp_watch_capital_war_info(10914)
capital 王城战 62 req_capital_war_add_schedule_task(10932)、req_capital_war_set_office_mode(10940)、notify_capital_war_president_data(10957)
chat 聊天/群 48 req_chat_players_info_by_key(3418)、req_chat_group_agree_member(13565)、req_chat_group_vote_select(17575)
battle 战斗 47 req_slg_3_league_get_battle_report(17623)、notify_arsenal_league_battlefield_result(17263)
fort 要塞 35 req_fortwar_goal_data(10716)、req_fortwar_apply_data(10715)、notify_fortwar_activity_init(10761)
triangle 三角战 46 req_triangle_war_enter_warzone(15981)、req_triangle_war_march_rush(15992)、req_alliance_triangle_war_match_score(15936)
brawl 乱斗 42 req_brawl_war_player_record(17503)、req_brawl_war_move_city(17433)、req_brawl_war_wall_outfire(17442)
monopoly / linkage 大富翁·联动 42 req_monopoly_play_gold_dice(13652)、req_linkage_monopoly_get_apply_list(30752)、notify_linkage_monopoly_play_dice_info(30786)
frostfire 霜火战 28 notify_frostfire_war_player_num(13374)、notify_frostfire_hero_injured(13377)
mail 邮件 27 req_mail_collect(2504)、req_mail_cover_list(2501)
expert 专家 25 req_expert_send_gift(30432)、req_expert_skill_research(30435)
hero 英雄 24 req_hero_promote_star(1812)、req_hero_debris_exchange(1814)、req_hero_search_times(4701)
monster siege 怪物攻城 12–24 req_monster_siege_personal_history(10214)、notify_monster_siege_wave(10206)、notify_monster_siege_endtime(10205)
recharge / pay 充值 22–23 req_recharge_lottery_draw(20281)、notify_recharge_lottery_info(20291)、notify_recharge_fail(6704)
vip 特权 22 req_vip_privilege_get_red_packet_reward(16174)、req_vip_get_daily_exp(4651)
showdown 联盟对决 20 req_alliance_showdown_reorganize(9807)、req_alliance_showdown_battle_wave_report(9841)
pet 宠物 19 req_pet_break(15322)、req_pet_adventure_dispatch(15541)
truck escort 卡车护送 19 req_truck_escort_plunder_fight(16426)、req_truck_escort_refresh_enemy_list(16440)
migrant 移民 19 req_migrant_set_power_limit(15851)、req_migrant_get_act_history(15863)
snow 除雪/基金 18 req_snow_clean_handbook_draw(30238)、notify_snow_fund_purchase(17126)
fishing 钓鱼 16 req_fishing_gear_upgrade(13502)、req_fishing_get_free_gift(13507)
arena 竞技场 14 req_arena_get_opponent(8460)、req_arena_rank_top(8483)
recruit 招募 12 req_recruit_hero(1813)、notify_recruitment_loyalty(4203)
red packet 红包 6 req_red_packet_send(17171)、req_red_packet_get(17173)、req_red_packet_refresh(17174)
cheat 作弊/调试 218 notify_cheat_record_info(1300)、req_cheat_inject_lua_script(14094)…

2.2 值得关注的协议

主题 op(操作码) 说明
充值抽奖 req_recharge_lottery_draw(20281) / notify_recharge_lottery_info(20291) 累计充值抽取型付费玩法
作弊记录上报 notify_cheat_record_info(1300)、req_get_cheat_record_info(1261) 服务端向客户端下发“作弊记录”
作弊/调试指令 req_cheat_inject_lua_script(14094)、req_cheat_query_database(1205)、req_cheat_query_player_data(14101)、req_cheat_add_total_recharge_diamond(14169)、req_cheat_change_sys_time(1223)、req_cheat_switch_wormhole(1284)、req_cheat_uproot_all_multiverse_city(1296)、req_cheat_hotfix_config(14163)、req_cheat_publish_kingdom_channel(14044)、req_cheat_send_mail(14027) 名为 cheat_ 的完整 GM 指令集(218 条),覆盖改数值、跳关、发邮件、切时间、注入脚本
联盟对决 req_alliance_showdown_invite_apply(9810)、…reorganize(9807)、…battle_wave_report(9841)、req_cheat_alliance_showdown_set_grade(14133) 联盟 PvP 赛制
军械库联盟战 req_alliance_arsenal_send_request_mail(11912)、req_alliance_arsenal_war_dispatch(11905)、req_arsenal_league_honor_mvp_info(30633)、req_cheat_arsenal_league_rematch(14160) 跨服军械库联赛
王城战 req_capital_war_add_schedule_task(10932)、req_capital_war_set_office_mode(10940)、req_capital_war_appoint(10903)、notify_capital_war_president_data(10957) 总统/官职体系
怪物攻城 req_monster_siege_personal_history(10214)、req_monster_siege_get_score_reward(10213)、notify_monster_siege_wave(10206)、req_cheat_monster_siege_set_diff(14048) 波次攻城
挖宝 notify_dig_treasure_info(20660)、req_dig_treasure_start_level(20652)、req_cheat_dig_treasure_jump_level(14083) 挖宝关卡
红包 req_red_packet_send/get/refresh/get_detail(17171/17173/17174/17175) 联盟/世界红包
老虎机广播 notify_slot_matrix_broadcast_records(30658)、req_cheat_slot_matrix_add_broadcast(14207)、rsp_slot_matrix_watch_records(30657) 抽奖广播 + 观战
霸权战 notify_supremacy_war_alliance_info_update(20651)、req_spectator_supremacy_war_enter(17001)、req_cheat_supremacy_war_gov_global_test(14075) 全服争霸 + 观战
找货/场景寻宝 req_find_goods_scene_mark(20933)、notify_find_goods_room_member_join(20972) 房间制寻宝玩法
魔法药水 req_magic_potion_submit(21032)、notify_magic_potion_init(21031) 拼图/合成类活动

3. UI / 视图分类(ui_views.txt,6,977 个)#

3.1 类型后缀分布

后缀 数量 后缀 数量
View 3,244 SubPanel 710
Panel 1,976 Ctrl 618
SubView 386 其它(PopPanel/PopUp…) 40
合计 6,977

3.2 功能分类(关键词归类,存在跨类重叠)

类别 约数 代表视图名
Battle 战斗 ~1,436 AllianceDuelBattlePanel、AllianceDuelBattleSubPanel、BattleStartCountdownPanel、ArsenalWarMapCtrl
Activity 活动 ~1,312 AccumulativeActivityCtrl、AccumulativeBigPanel、ActivityDropHalloweenSubPanel、FestivalTurntable…
World / March 世界行军 ~902 AllianceMassMarchInviteView、AllianceSituationMarchCtrl、WorldMapStaticExpressionShowView、WorldPersonalSituationMarchListBaseView
Alliance 联盟 ~592 AllianceAnnouncementOverviewView、AllianceMemberBatchOperateView、AllianceListAddRelationshipView
Hero / 英雄装备宠物 ~482 ArenaDefenseHeroDetailPopUpView、AllianceHonorLeagueStarDetailTipView
Treasure / 休闲玩法 ~417 Anniversary2025FrozenTreasureTaskPanel、BalloonDetailPopupView、DigTreasure…
Shop / 商业化 ~400 AccRechargeLotteryGetMorePopupView、AccumulativeRechargePanel、RechargeShop…
City / 城市建造 ~322 AllianceBuildingCtrl、AllianceCityMovePromptView、ArsenalWarFreeCityMoveView
Settings / 账号系统 ~198 AccountBindSubPanel、AccountCommunityPanel、ABTestCtrl、AllianceHelpView
Chat / 社交消息 ~160 ChatAllianceContentPanel、ChatAllianceSetPopupView、AllianceWarMailView
Login / 选择服务器 ~148 AllianceLanguageSelectView、CapitalWarFlagSelectView、BoxSelectBoxView

架构观察:以 Panel / View / SubPanel / SubView 的四级组合为主,配合 Ctrl 控制器(618 个)——典型 View(表现)+ Ctrl(逻辑)+ Data/Model(数据) 分层;SubPanel/SubView 说明大量复合视图采用父子嵌套。


4. 客户端架构说明#

4.1 分层模型(Lua MVVM/ Ctrl)

从命名可确认的分层:

  • Controller / Ctrl:如 WorldMapCapitalCtrl、ChatProxyCtrl、GardenCtrl、BTreeNodeCtrl、AllianceBriefInfoCtrl;tokens.txt 中 Ctrl 型类共 21+ 处,且存在 DataMgr(58)、Proxy(39)、Mgr 等管理类。
  • Data / Model(*D / *Data):如 world_march_WorldMarchDataFactory、hero_HeroD、soldier_SoldierD、garden_GardenD/GardenSceneryD/LifeTreeD、rank_RankD、chat_ChatD。数据与表现分离,*D 为纯数据,*C/Ctrl 为逻辑。
  • Interface(*I):queue_QueueI、store_StoreI/StoreGoodsI、alliance_AlliancePlayerI、AllianceMobilizationI、world_march_IWorldMarchD——接口/契约定义。
  • Proxy(代理):chat_ChatProxyC/ChatProxyCtrl、game_module_logic_proxy_*——跨模块通信与跨服桥接。
  • View 层:game_module_ui_view_*(3,222) + game_module_ui_item_*(4,892) + game_module_ui_component_*(12),由 ViewHelperDef 统一。
  • 事件/消息:常量中出现 SendMsg/SendMessage/OnRes…/Request…(如 WorldMapCapitalCtrl:ReqWatch、WorldMapExpressionCtrl:RequestSendMarchExpression、AllianceMemberBatchOperateView:_RequestPlayerPointAsyncByPlayerIds),即 Ctrl 内以 Req*/OnRes* 方法收发协议。

4.2 模块定义(game_define_moduleDefine_*)

game_define_moduleDefine_* 共 128 条(如 ActivityDef、AllianceDef、AllianceDuelDef、ArsenalWarDef、WorldMarchDef、ConstructDef、HeroEquipDef、RecruitDef、SoldierDef、ChatDef、VipPrivilegeDefine、SettingsDef)。这与 game_module_logic_module_* 家族一一映射,构成模块注册/解耦表——游戏按模块装配,模块即玩法单元。

4.3 配置表(config_tables.txt,1,600 张)

前缀 数量 用途
game_config_default_* 999 数值/静态配置:construct_*、building_*、alliance_duel_*、alliance_building_attr/cost、active_recharge_* 等
game_config_btree_guide_* 545 行为树引导脚本(Guide_Animal_Attack、Guide_Construct_Furnace_Accelerate、Guide_DigTreasure_Plan…);分 Guide_* / weakguide / weakguide_jump 三系
game_config_custom_* 47 关卡/场景自定义数据(custom_findinggame_find_level_scene_08、custom_garden_layout、custom_snowclean_*)

配置与逻辑分离,game_config_btree_* 表明新手引导 = 数据驱动行为树(对应 game_module_btree_action/precondition/ctrl_* 的 Guide/AI 节点)。

4.4 内嵌协议 DSL(文本)

lua_strings_32.txt 中直接包含可读的协议字段定义 DSL(request { … } / response { … }),形如:

notify_player_city_update 5656 { #
    request { # …
def 1 : owner       #
owner 0 : integer #
owner_kid 30 : integer #
owner_uid 5 : integer #

字段语法为 <字段名> <编号> : <类型>,支持 *类型()(嵌套/数组)、integer(N)(定长)、boolean、string,并可带 # 注释;request / response 分块对应请求与应答。该 DSL 是运行期按文本解析生成的协议编解码表(与 protocol_ops.txt 的操作码表互补),说明网络层为自研文本化 protocol schema(非 protobuf .proto,但语义等价)。

4.5 AI / 表现层

  • 分层状态机 HFSM:game_module_hfsm_state_*(monster_attack/pursue/flee/guard、garden_sawwood/choptree/goSaw、fishing_cast/hole、towerdefence_attack/face/gotarget、pet_action)+ hfsm_condition_*——世界地图单位与场景小游戏的行为由 HFSM 驱动。
  • 行为树 BTree:game_module_btree_ctrl_*(BTreeNodeSequence/Selector/PrioritySelect/Parallel)、btree_action_guide_*(FrameClick、ScenePlay、Bubble、JumpToConstruction…)、btree_precondition_guide_* / ai_*。引导与 AI 共用同一行为树框架。
  • 场景模块:game_module_scene_world(413)、snowclean(389)、battle(195)、arsenalwar(101)、towerdefence(70)、minewar(70) 等,负责地图/单位/摄像机表现。

5. 风险与攻击面#

风险项 证据 评估
客户端权威逻辑(Client-Authoritative) 存在 game_module_ui_view 3k+ 表现类与大量 *C/Ctrl 逻辑类同处 Lua 层;WorldMarchDataFactory、WorldMapObjDataCls 等在地图/行军中承担推演 关键战斗/行军结算若在客户端预演,前线进程易被篡改;需服务端二次校验(存在 battle_report/record 协议,倾向服务端裁决,但客户端仍持有完整规则与配置)
内置 GM/作弊指令集(218 条 cheat_ 协议) req_cheat_inject_lua_script(14094)、req_cheat_query_database(1205)、req_cheat_query_player_data(14101)、req_cheat_add_total_recharge_diamond(14169)、req_cheat_change_sys_time(1223)、req_cheat_send_mail(14027)、req_cheat_publish_kingdom_channel(14044)、req_cheat_hotfix_config(14163) 最高危面:完整改数值/发资源/按 UID 查询/注入 Lua/热更配置入口全在客户端可达(是否服务端二次鉴权未知)。攻击者可尝试伪造这些 req_cheat_* 包越权
作弊记录通道 notify_cheat_record_info(1300)、req_get_cheat_record_info(1261)、req_cheat_* 中大量“端到端记录”(…op_privacy_policy、…record) 服务端有反作弊检测与下发机制,但检测规则与 cheat_ 指令同客户端,攻击者可解析上报逻辑进行规避
回放 / 观战 / Botting req_spectator_supremacy_war_enter(17001)、rsp_slot_matrix_watch_records(30657)、notify_slot_matrix_broadcast_records(30658)、req_brawl_war_player_record(17503)、req_alliance_showdown_battle_wave_report(9841)、req_slg_3_league_get_battle_report(17623) 完整的 replay/观战/战斗报告 数据链路 → 可录制→重放/脚本化,或用于自动挂机(botting)
概率玩法(抽奖类) req_recharge_lottery_draw(20281)、req_hero_turntable_*(10352/10353/10354)、req_duck_market_gacha(21001)、req_sign_draw_lottery(16132)、req_festival_turntable_shop_buy(20645)、slotmatrix 系列 转盘/扭蛋/老虎机集中在客户端触发,需确认掉率与结果由服务端决定;客户端可见 game_config_* 概率表(若配置在客户端则可被读取)
经济与付费完整性 req_cheat_add_total_recharge_diamond(14169)、req_beta_test_recharge(6791)、notify_recharge_fail(6704)、game_config_active_recharge_* 付费/赠送路径存在可测协议;cheat_add_total_recharge_diamond 若鉴权不严可刷充值额度
定时/时钟依赖 req_cheat_change_sys_time(1223)、notify_activity_calendar_data(9925)、notify_monster_siege_endtime(10205)、大量 *_cd_endtime / *end_time 字段 客户端存在基于本地时间的 CD/活动判定(有 change_sys_time 调试口),需确认关键时间由服务端时间戳约束
跨服/赛季状态 req_cheat_merge_kingdom(14061)、req_cheat_switch_wormhole(1284)、req_cross_capital_*、req_mergekingdom_*、notify_merge_milestone_preview_info(20233) 合服/跨服/赛季迁移逻辑复杂,是状态一致性攻击面
协议 schema 客户端可见 lua_strings_32.txt 中明文 request/response DSL + protocol_ops.txt 操作码表 攻击者可完整重建协议编解码,构造任意报文(含 cheat_ 报文),降低协议逆向门槛

结论:游戏采用 「Lua MVVM/Ctrl + 自研文本协议 DSL + 数据驱动配置(含 BTree 引导/HFSM AI)」 的清晰分层架构,玩法模块化程度高(196 个逻辑家族 / 128 个模块定义 / 1600 张配置)。安全上最突出的特征是:完整的 218 条 cheat_ GM 指令集直接存在于客户端可达的协议表中,连同 notify_cheat_record_info 反作弊通道与完整的观战/回放链路,构成主要的越权与自动化(botting)风险面。玩家侧权威边界需依赖服务端对 req_*(尤其非 req_cheat_* 的正常请求与 req_cheat_*)做严格二次校验,否则客户端可凭借可见的协议 schema 与配置表大幅降低攻击成本。


本分析仅基于脱壳样本内的只读符号/字符串证据,未对服务器发起任何真实请求;所有 opcode 与类名均为证据原文,未做推测性命名。


10 · 数值 / 配表(CONFIG / NUMERIC DATA)分析#

目标:com.gof.china 1.15.6(Whiteout Survival CN /《无尽冬日》,Unity 2022.3.52f1 + IL2CPP + ToLua)。 证据(全部只读): - artifacts/lua/config_tables.txt — 1,600 个 game_config_* 表名 - artifacts/lua/tokens.txt — 252,026 条 Lua 标识符(前缀树展开) - artifacts/lua/lua_strings_32.txt — 386,532 行原始常量(含大量 Lua 源码片段) - artifacts/out_types.txt / out_identifiers.txt / out_literals.txt — IL2CPP 元数据 - extracted/Payload/whiteoutsurvivalcn.app/Data/Raw/ — 随包资源

本文所有数字 / ID 均直接来自上述文件;无法确证的推断已明确标注「推断」。


0. 结论速览#

问题 结论
配表如何组织 以 Lua 表名 game_config_<命名空间>_<表> 引用;三大命名空间 default / btree_guide / custom
表名是否随包 是。1,658 处 game_config_* 作为 Lua 字符串常量出现在本地加密的 luapackage_32/64 内
真实数值是否随包 没有以明文形式随包。本地 5,316 个 .unity3d 中仅 14 个 config_*,且全是「映射类」配置(图集/音效/语言/登录),不含英雄/建筑/士兵数值表;Data/Raw/world/*.bytes 只有大地图配置
数值去向 远程版本化资源管线(CDN https://gofcn-prod-cdn.campfiregames.cn/RELEASE/{0}/{1}/)+ 二进制常量(嵌在加密 Lua 字节码/远程资源中);见 §4、§5
属性系统 data_map[id] 聚合公式(id∈40001..40028)+ attr_type 描述键(attr_type_desc_10101..10616、40022..40026、60001/60002)
可否被攻击者篡改 可以:表名与公式在本地且容器明文,仅首块 XOR + EncryptLuaBytecode;但服务端数值不在本地,纯本地改表只会与服务端不一致(见 §5.3)

1. 配置表分类(Config Taxonomy)#

1.1 命名方案

表名统一格式:game_config_<Namespace>_<Table>,其中 <Namespace> 只有三类:

命名空间 语义 数量(含前缀重复)
game_config_default_* 主数据配表(玩法/经济/养成/活动) 1,000
game_config_btree_guide_* 行为树(BTree)新手引导配表 547
game_config_custom_* 场景/关卡自定义地图配表 47
game_config_(裸前缀)+ 少量截断 提取噪声 6

game_config_btree_guide_* 的证据:在 lua_strings_32.txt 中可读到编辑器源路径

Assets/Scripts/editor/modules/ai/BTreeEditor/Config/guide/Guide_Test_1.json
Assets/Scripts/editor/modules/ai/BTreeEditor/Config/guide/Guide_Monopoly*.json
Assets/Scripts/editor/modules/ai/BTreeEditor/Config/ai/Hunter.json
Assets/Scripts/editor/modules/ai/BTreeEditor/Config/ai/Cooker_Idle.json
Assets/Scripts/editor/modules/ai/BTreeEditor/Config/ai/Hero_Patrol.json
Assets/Scripts/editor/modules/ai/BTreeEditor/Config/gui/*.json

即这些是 AI 行为树编辑器导出的 JSON,表名即 BT 入口节点名,前缀 Guide_* / WeakGuide_*(弱引导)。目录 ai/ 放 NPC AI(Hunter/Cooker/Hero_Patrol),guide/ 放引导,gui/ 放 UI 流程。bundle 内可见前缀树节点如 btree_precondition_guide_guide_istrigger_condition、btree_preconditionlogicopt_btreenodepreconditionand。

game_config_custom_* 的 19 个叶子名(场景级数据):

game_config_custom_findinggame_find_level_scene_{9,19,08,105,110}
game_config_custom_garden_lay…
game_config_custom_snowclean_snowclean_{cu…,entity_con…,map_20,map_10021,map_10032,map_10043,map_10111,map_10115,map_10122,map_101148,map_10125n}
game_config_custom_trianglewar_map_build…

1.2 前缀树 / 截断说明(重要)

config_tables.txt 的 1,600 个名字中,440 个是另一个名字的严格前缀,例如 game_config_default_al → game_config_default_alliance。这是 tokens.txt 采用前缀树展开(每个标识符的每一段前缀都作为独立 token 输出)造成的提取产物,不是游戏里真有多张短名表。

因此:

  • 名义表名 1,600;
  • 去重后的「叶子」完整表名 1,160(其中 default 708、btree 434、custom 18)。

下文计数同时给出 总数 / 叶子数。

1.3 家族分类计数

按表名关键字归族(一条表名归入首个命中的家族,故各家族互不重叠,合计 = 1,600 / 1,160):

家族 总/叶子 可能治理的内容
btree_guide 新手引导行为树 547 / 434 引导触发条件、章节解锁、引导跳转、AI 行为树
gift/recharge/pack 充值礼包 56 / 42 充值档位、礼包、通行证(BP)、限时特惠
snow 冰雪/铲雪 50 / 28 暴风雪、铲雪小游戏、雪灾参数
arsenal 军备/兵工厂 43 / 25 军备联赛(3v3 车战)、兵工厂战场
sdk/network/系统 41 / 26 SDK 错误、推送、屏蔽词、语言翻译、账号删除、服务器流程
supremacy 霸权战 39 / 28 霸权战阶段/奖励/官职
frozen/icefield/冰原 39 / 26 冰原狩猎、极地远征、寻宝
arena/pvp 竞技 36 / 28 竞技场、爬塔、矿战、决斗、跨服联赛
task/activity 任务活动 35 / 30 任务、章节、活动
fishing 钓鱼 29 / 18 钓鱼小游戏、鱼种、积分
expert/travel 专家旅行 29 / 21 专家系统、旅行玩法、专家技能
festival 节日/通行证 28 / 22 万圣节/情人节/春节/圣诞/龙舟/中秋等节日
item/equipment 物品装备 25 / 16 物品、领主装备、圣物、材料
capital/fort 首都/要塞 24 / 17 首都战、要塞战、赛季目标
monopoly 大富翁联动 23 / 17 联动大富翁关卡
cross 跨服 23 / 16 跨服战、跨服王者
world 大世界 23 / 18 SLG 大地图、城市交互、宠物捕捉
thanksgiving 感恩节 23 / 15 火鸡大餐、烹饪
hero 英雄 22 / 18 英雄品质/技能/专武/招募转盘
garden 花园 21 / 10 花园建造、繁荣度、建筑属性
gacha/lottery 抽奖 28 / 19 老虎机、弹珠、转盘、福卡、魔法药水、签到抽奖
anniversary 周年庆 18 / 13 周年回顾、周年展示
daily 每日 18 / 12 每日任务/礼包/积分
frostfire 霜火 17 / 12 霜火之战
monster/pve 怪物 16 / 13 怪物攻城、PvE Boss、赏金
brawl 混战 14 / 11 混战战场、空投、地形
strongest 最强 14 / 9 最强领主
tech/research 科技 13 / 8 科技树、精炼科学、火晶科学
intel 情报 11 / 9 情报任务、雷达、赏金
building/city 建筑城市 10 / 8 建筑、炉子、使馆、城内交互
chat/social 社交 9 / 8 聊天、表情、社交
map/terrain 地图 10 / 8 地图、地形、场景
pet 宠物 7 / 6 宠物捕获/喂养/洗炼
survivor/status 幸存者状态 6 / 6 幸存者状态、忠诚度
mercenary 佣兵 3 / 3 佣兵副本
soldier/army 士兵 2 / 2 兵营训练
misc/其他 181 / 107 其余小系统(见下)

misc/其他 内含若干独立小玩法与系统,例如:duckmarket_*(鸭子市场)、fortune_card_*(福卡)、pitchpot_*(投壶)、puzzle_*(拼图)、treasure_hunt_*(寻宝)、truck_escort_*(卡车护送)、slot_matrix_*、pachinko_*、three_tiles_*、magic_potion_*、monster_siege_*、most_lords_*、mobilization_*、popular_star_*、showdown_*、slg_3_league_*、spar_laboratory_*、fire_crystal_*、mercenary_*、spring_couplets_*、shengdan_*、knockdoors_*、wheel_fortune_*。

代表性 default 表名举例:game_config_default_hero_skill_upgr…、game_config_default_hero_equipment_stren…、game_config_default_lords_equipment_config_、game_config_default_lords_gem_config、game_config_default_technology_tree_con…、game_config_default_skill_config_mapp…、game_config_default_alliance_building_cost、game_config_default_fishing_level_con…。

说明:表名在 config_tables.txt 中被截断(如 _con… / _gr… / _rew…),这是提取层的前缀/截断产物,不是游戏真实命名。


2. 数值结构:内嵌的 Lua 属性聚合公式#

lua_strings_32.txt 中直接包含多段属性取值函数源码。经原始字节解析(键后紧跟一个长度字节 + UTF‑8/ASCII 值),可还原为:

local s = function(data_map) return (data_map[40002] or 0) + (data_map[40014] or 0) end return s   -- → EventDuring
local s = function(data_map) return (data_map[40003] or 0) + (data_map[40015] or 0) end return s   -- → Sleep
local s = function(data_map) return (data_map[40004] or 0) + (data_map[40016] or 0) end return s   -- → Comfort
local s = function(data_map) return (data_map[40005] or 0) + (data_map[40017] or 0) end return s   -- → Mood
local s = function(data_map) return (data_map[40006] or 0) + (data_map[40018] or 0) end return s   -- → Satiety
local s = function(data_map) return (data_map[40007] or 0) + (data_map[40019] or 0) end return s   -- → Health
local s = function(data_map) return (data_map[40008] or 0) + (data_map[40020] or 0) end return s   -- → CureRate
local s = function(data_map) return data_map[40010] or 0 end return s                              -- → MEAT_SAFE
local s = function(data_map) return data_map[40028] or 0 end return s                              -- → LawToken

2.1 幸存者/城镇属性公式表(14 个具体 ID)

# 属性名 data_map key 组合 公式(原文)
1 EventDuring 40002 + 40014 (data_map[40002] or 0)+(data_map[40014] or 0)
2 Sleep 40003 + 40015 (data_map[40003] or 0)+(data_map[40015] or 0)
3 Comfort 40004 + 40016 (data_map[40004] or 0)+(data_map[40016] or 0)
4 Mood 40005 + 40017 (data_map[40005] or 0)+(data_map[40017] or 0)
5 Satiety 40006 + 40018 (data_map[40006] or 0)+(data_map[40018] or 0)
6 Health 40007 + 40019 (data_map[40007] or 0)+(data_map[40019] or 0)
7 CureRate 40008 + 40020 (data_map[40008] or 0)+(data_map[40020] or 0)
8 MEAT_SAFE 40010 data_map[40010] or 0
9 (未命名,dump 丢失) 40011 data_map[40011] or 0
10 (未命名,dump 丢失) 40012 data_map[40012] or 0
11 (未命名,dump 丢失) 40013 data_map[40013] or 0
12 (未命名,dump 丢失) 40027 data_map[40027] or 0
13 LawToken 40028 data_map[40028] or 0
14 IRON_SAFE / COAL_SAFE / WOOD_SAFE (与 MEAT_SAFE 同区常量) 仅见常量名,未见函数体(推断为 40011–40013 一类)

关键结构:第 1–7 项构成 7 组「基础项 + 加成项」求和,偏移恒为 +12:40002↔40014 … 40008↔40020。这对应「基础属性 + 额外/加成属性」两套数值;40001(对应 40013)在公式中未成对出现,40009(对应 40021)亦未见。MEAT_SAFE 等属「被保护资源量」类(肉/铁/煤/木的保鲜/保护上限)。

名称 EventDuring 在 tokens.txt 中亦独立存在(另有 SetEventDuringAndRemainingMti、GetEventDuring 等),确认为幸存者「事件持续」类属性。

2.2 部队/士兵战斗属性(*_increase / *_reduce)

tokens.txt 中存在一套战斗属性键(作为表列名/加成类型名),同一命名模式:

soldier_atk_increase / soldier_def_increase / soldier_hp_increase / soldier_dmg_increase
infantry_atk_increase / archer_hp_increase / garrison_def_increase
enemy_soldier_atk_reduce / enemy_infantry_hp_reduce / enemy_cavalry_dmg_reduce
soldier_atk_increase_by_duty / soldier_atk_increase_by_pet / soldier_atk_increase_by_supremacy_title
soldier_atk_increase_by_supremacy_skill / soldier_hp_increase_by_supremacy_tower
garrison_atk_increase_in_territory / soldier_monster_atk_increase

主力计算函数:GetSoldiersPower、GetFormationSoldierFightingCapacity、GetFormationHeroFight…、PowerBuffStatistics、PowerValue、CalculationFormulaMMMD、CalculationFormula、CalculationValue、StatisticalMagnitudeSold…、StatisticalMagnitudePowerValue。即战力(Power)由公式类动态计算,而非纯静态值。


3. 属性与 ID 命名空间#

3.1 attr_type 描述键(属性类型枚举)

tokens.txt 中 attr_type_desc_* 共 155 个不同 ID(154 个前缀 token),分块如下:

段 范围 用途(由同现中文/同现键推断)
10xxx 主段 10101–10616(多段连续) 战斗/养成/联盟/采集等属性类型
40xxx 40022–40026 城镇/幸存者属性
60xxx 60001–60002 城镇(含跨服/二次城)相关
特殊 103462 单例(水晶相关)

实际连续段(用于判断子系统划分):10101–10108、10110–10116、10121–10125、10201–10216、10221–10229、10301–10348、10403–10448、10501–10531、10600–10616、40022–40026、60001–60002。可见 10200 与 10300 段明显是 10100 段的「敌方 / 守城」镜像。

可可靠还原中文描述的属性类型(示例):

attr_type ID 描述(原文,来自 lua_strings_32)
10105 矛兵攻击力
10110 射手防御力
10203 敌方盾兵穿透力
10207 敌方矛兵穿透力
10213 敌方所有部队攻击力
10221 敌方攻击力减益(宠物技能)
10228 生命值增益(宠物技能)
10304 守城部队生命值
10310 敌方守城部队防御力
10311 敌方守城部队穿透力
10341 群兽洞窟专属全属性提升
10344 水晶技能
10404 研究速度
10417 铁矿产量
10420 木材采集速度
10422 铁矿采集速度
10436 常规情报任务奖励增加
10521 部队编组
10525 集结栏位
10615 挑战城镇:士兵损失比例上升 15%
40022 幸存者持续工作

(其余大量 attr_type_desc_* 在字符串表中被截断为 1–2 字,未纳入本表,避免臆测。)

3.2 ID 命名空间总览(推断的编号体系)

命名空间 形式 证据
配置表 game_config_{default,btree_guide,custom}_* 1,600 名字,§1
城镇/幸存者属性 data_map[40001..40028] §2.1 公式
属性类型 attr_type_desc_10101..10616 / 40022..40026 / 60001..60002 / 103462 §3.1
物品 item_name_<id>(如 610101、502105、100025),item_icon_<id>、item_desc_<id> 前缀分布:30xxxx(608)、50xxxx(219)、62xxxx(197)、23xxxx、60xxxx、10xxxx、20xxxx 等
类型枚举 FurnitureType、InteractionType、GItemShowHideType、FurnitureDefine、CityDefine、ActivityDefine、EntityWorkStatusServer tokens.txt 精确匹配
协议号 请求/通知号(如 req_survivor_sick、notify_dig_treasure_info) protocol_ops.txt

3.3 数据驱动设计

  • 表 → 表现的解耦:业务逻辑(Lua)只引用表名 game_config_default_*,行数据按 ConfigReadHelper / ConfigMeta / ConfigName / ConfigPath 读取;ConfigReadHelper 提供 ConvertConfigToMapWithKey、GetConfigById、GetConfigByType、GetConfigByItemId、GetConfigByLinkStr 等访问器。
  • 属性聚合数据驱动:属性不写死在代码,而是以「函数表」形式按 data_map[id] 组合(§2.1),新增属性只改表/公式。
  • 枚举驱动表现:FurnitureType、InteractionType、CityDefine、ActivityDefine 等 C# 枚举由 Lua 侧同名 *Define 镜像。

4. 配置加载路径#

4.1 Lua 侧加载链

lua_strings_32.txt 中出现加载链字符串:

IndexCacheCenter . GameConfig . config.ConfigMeta   需要 require
OnConfigLoadCompleted   GetConfigVersion   CheckConfigVersion
ConfigReadHelper   ConfigMeta   ConfigName   ConfigPath   ConfigData

含义:ConfigMeta(配置元数据)→ ConfigReadHelper(读取/转换)→ IndexCacheCenter(索引缓存)→ GameConfig(全局配置门面);并有版本校验 CheckConfigVersion / GetConfigVersion。配置值由表名索引,运行时从资源层读取。

4.2 资源 / 下载管线(C# 侧)

IL2CPP 元数据中的 CenturyGame.GameFramework.ConfigData 暴露完整远程资源参数:

Version, VersionCode, Release, UpdatePlatform, PackageCode, PackageType,
BundleId, Language, LuaArch, UseLuaJit, LuaAssetBundleMode,
DownloadThread, LoadThread, EnableAssetSplit, ResourceSplit, AssetBundleMode,
AssetCacheTime, AssetClearTime, AssetSkipPattern, TestServerList,
EnableHotFix, IsInnerTest, IsDeveloper

即客户端按 Version/VersionCode 从服务器拉取差异化资源(分片/多线程下载、热更)。

4.3 CDN 根(来自 out_literals.txt)

https://gofcn-prod-cdn.campfiregames.cn/RELEASE/{0}/{1}/
https://gofcn-prod-cdn.centurygames.cn/RELEASE/{0}/{1}/
https://gofcn-prod-cdn.campfiregames.cn/RELEASE/WebUrl_2/Web{0}.txt
https://gofcn-qa-cdn-1322302784.cos.ap-shanghai.myqcloud.com/INNER/WebUrl/Web{0}.txt
lua.unity3d

{0}{1} 为版本/分包占位符;另有平台配置下发 https://platform-config-prod.centurygame.com/config.json 与 https://clientversion.diandian.info/snapshot/。推断:数值配表随 RELEASE/{版本}/{分包}/ 的资源包下发。

4.4 本地 config_* bundle 清单(仅 14 个,全部是映射类)

Data/Raw/data/ 共 5,316 个 .unity3d(715 MB),其中以 config_ 开头的 恰好 14 个:

config_ab_mapping_6f3a862d…unity3d            配置映射(AB 分组)
config_animation2d_aee394a6…unity3d           2D 动画映射
config_atlas_mapping_b583fdba…unity3d         图集映射
config_cache_config_b0002f28…unity3d          缓存策略
config_emojiconfig_2dcd1406…unity3d           表情配置
config_game_setting_06cea4a9…unity3d          全局设置
config_language_zh_cn_7bcb37c4…unity3d        中文语言表
config_launch_prefab_809223ac…unity3d         启动 Prefab
config_login_login_logo_default_9b3a7b34…   登录 Logo
config_login_logo_01381e84…unity3d            登录 Logo
config_shadowconfig_833dbb47…unity3d          阴影配置
config_sound_mapping_5952320f…unity3d         音效映射
config_substitute_mapping_825374bd…unity3d    替代映射
config_vfxtexturelibrary_0d9e5465…unity3d     特效贴图库

→ 这些是资源/表现映射,不是数值配表。

Data/Raw/ 下唯一的非 unity3d 二进制配置是大地图 4 件套:

map_world_config_item_72ad90ca…bytes     32,942 B
map_world_config_mask_6d8d1979…bytes    720,004 B
map_world_config_setting_29d541c1…bytes     248 B
map_world_config_terrain_5199904f…bytes  526,137 B

对应 C# MapConfigHelper.LoadTerrainConfig / ReadItemData / ReadMaskData / ReadSetting / ReadTerrainChunk 与 MapItemConfig.Load、GardenConfig.Load(自研紧凑二进制 + IEEE‑754 小端浮点,非 UnityFS)。


5. 真实数值到底在哪里#

5.1 本地随包内容(确证)

项 事实
表名/公式 在本地加密 luapackage_32/64_*.unity3d(20 MB,406 块,仅首块 XOR 加密)内
14 个本地 config_* 全部为映射类,无英雄/建筑/士兵数值
Data/Raw/world/*.bytes 仅大地图(SLG)配置
5,316 个 .unity3d 名称首段统计:ui_panel 2,403、scene_battle 687、scene_city 559、art_*、atlas_*、actor_battle 133……无任何 hero_/soldier_/building_ 数值表 bundle

5.2 明文数值扫描结果(确证)

  • lua_strings_32.txt 中找不到任何长数字表块(正则 [0-9]+(,[0-9]+){15,} 无命中);
  • 战斗/建筑数值未以文本形式出现。

结论(明确表述):本版本(1.15.6)没有把英雄/建筑/士兵的成表数值以明文随 IPA 分发。数值只有两条可能来源:

  1. 远程下发:随 https://gofcn-prod-cdn.campfiregames.cn/RELEASE/{0}/{1}/ + ConfigData.Version/VersionCode 拉取(强证据:CDN 根、ConfigData 下载参数、CheckConfigVersion);
  2. 二进制常量:若部分表在 Lua 侧,则数值以 LuaJIT 的双精度常量表形式存在于加密字节码中(字符串 dump 不可见,符合「无文本数值」的观察)。

两种来源可以并存;本文基于现有证据无法进一步区分某一具体数值表走哪条路径。

5.3 对攻击者的含义(可篡改性)

层面 现状 影响
表名 / 公式 本地 Lua 包,仅首块 XOR + EncryptLuaBytecode / CheckLuaBytecodeHeader 逆向可读,可本地改公式
容器 明文 UnityFS,仅 block[0] 加密 解出首块密钥即 100% 还原资源
数值真值 服务端/CDN 版本化,且战力由服务端参与的公式计算 纯本地改表效果有限:服务端结算不一致会被检出/回滚
校验 CheckConfigVersion、Cmd_SetConfigData、网易易盾 Enable_Encrypt_NHP 网络加密 改包后 ConfigVersion/校验失败风险

攻击面小结:客户端能改的是「表名映射、聚合公式、UI 呈现、单机小游戏参数」;核心养成/战斗数值的权威来源在服务端,静态改包无法直接刷战力,但可用于信息收集(枚举全部表名/属性 ID/公式)与本地作弊面定位。


6. 局限与后续#

  1. 表名被前缀树展开,1,600 名中 440 个为前缀噪声;已按 1,160 叶子统计,但个别真实长名仍可能被截断(§1.2)。
  2. game_config_btree_guide_* 为编辑器 JSON 导出,本文据源路径确认语义,未逐表解析节点。
  3. data_map[40011/40012/40013/40027] 的属性名在本 dump 中丢失,仅确认 ID 存在,未臆测命名。
  4. 属性中文描述在字符串表中部分截断,仅列出可完整还原者;完整列表需完整的 LuaJIT 常量表 dump 或台中字符串资源。
  5. 区分「远程下发」与「加密字节码内常量」需进一步解密并解析 luapackage 的 LuaJIT 常量表(artifacts/decrypt / parse2.py 方向)。

11 · 活动 / EVENTS(活动系统)分析#

目标:com.gof.china 无尽冬日(Whiteout Survival 国服)1.15.6 引擎:Unity 2022.3.52f1 + IL2CPP;业务逻辑位于 LuaJIT 字节码(luapackage_32/64),还原为 Lua 文本后抽取符号 数据来源(只读证据):

证据 规模 说明
artifacts/lua/activity_tokens.txt 128 行 活动/节日标识符速览表
artifacts/lua/tokens.txt 252,026 行 Lua 标识符(含 game_module_logic_module_activity_*)
artifacts/lua/protocol_ops.txt 2,635 条 操作码<TAB>协议名(网络消息路由表)
artifacts/lua/config_tables.txt 1,600 张 配置表名(game_config_*)
artifacts/lua/lua_strings_32.txt 386,532 行 原始常量;内含协议 DSL 文本(req_/notify_ .. 操作码 { # 中文注释)
Data/Raw/data/*.unity3d 资源包清单 活动 UI / 横幅 / 加载 Spine 资源(ls | grep 得到)

数据质量说明:LuaJIT 字符串池抽取存在定长截断,部分 token / 配置名首尾被截(如 req_→eq_/_,BackFestival_ActivityData→BackFestival_Acti,配置名常在 40 字符处截断)。故下文配置家族名按证据内可见形式引用,已被截断者加 … 或括号注明。所有结论均来自上述证据,无推测性内容。


1. 活动控制器清单(Activity Controller Inventory)#

活动系统的逻辑层统一挂在 game_module_logic_module_activity_ 命名空间下。顶层模块 token 块位于 tokens.txt:164797–165121。其架构为三件套:

层 类后缀 代表
控制器 *C / *Ctrl ActivityC、ActivityGiftC、MineWarC
数据 *_ActivityData DivinationRoom_ActivityData、PinBall_ActivityData
事件/日历 activity_Event / eventcalendarc game_module_logic_module_activity_Event、..._eventcalendarc

基础类型:ActivityDataBase、ActivityData、ActivityInfo、ActivityStage、ActivityState、ActivityType、ActivityGift/ActivityGiftInfo、ActivityDrop/DropEvent/DropEventId(见 tokens.txt 与 lua_strings_32.txt)。

下表为要求核对的活动控制器(均在 tokens.txt:164798–165119 命中),括号内为同名瞬时数据类:

控制器 数据类 一句话说明 关联配置家族(证据原文,截断照录)
ActivityC ActivityDataB…/ActivityData 活动总控/入口与红点,管理日历与开启状态 game_config_default_activity_center_s…、..._activity_main_icon_…、..._activity_exchange_go…
ActivityGiftC ActivityGiftInfo 活动礼包(含触发/弹窗/自定义礼包)发放与领取 game_config_default_activity_gift_po…、..._gift_activity_…、..._optional_gift_p…、..._birthday_gift_pre…
ActivityDropC ActivityDrop_ActivityD…、DropEvent_Activity 打怪/采集掉落活动(节日换皮:Children/Easter/Halloween/Valentine/DragonBoat/Lantern) game_config_default_drop_activity_…;notify_activity_drop_direct 2103
DailyTaskC DailyTa…_ActivityD 活动日常任务 + 节日战令日常 game_config_default_fes_bp_dailytask…、..._daily_activity_t…/..._reward…
AllianceTrapC AllianceTrap_ActivityD 联盟巨兽陷阱(个人/联盟积分与排行奖励) game_config_default_alliance_trap_c…、..._trap_damage_rew…、..._trap_strengt…
BackFestivalC BackFestival_Acti… 回归/回流活动(七日任务+积分+签到) game_config_default_back_fivedays_task_c…/_m…/_rew…
ChristmasFindC ChristmasFind_ActivityD 圣诞寻宝类玩法控制器 未抽到独立 christmas_find_* 配置表;数据由协议下发
DivinationRoomC DivinationRoom_ActivityD 占卜屋(设奖/开奖/记录) 引导表 guide_weakguide_divination_…;玩法数据由协议下发
FireCrystalLabC FireCrystalLab_ActivityD 火晶实验室(科技/周任务宝箱) game_config_default_fire_crystal_man…、..._firecrystal_technology_c…、..._firecrystal_mission_r…
FireCrystalLeakC FireCrystalLeak_ActivityD 火晶泄漏事件(雷达/修复) 引导 guide_weakguide_radar_fire_crystal_leak_…
FrozenTreasureC FrozenTreasure_ActivityD 冰冻宝箱(节日换皮主推玩法之一) game_config_default_frozen_treasure_c…、..._lott…、..._rew…
HuntTreasureC HuntTreasure_Activity… 寻宝棋盘(格子/任务/兑换) game_config_default_treasure_hunt_c…、..._chessbo…、..._rew…
InteractiveC Interactive_ActivityD 互动/装扮交互(周年互动等) game_config_default_interactive_dress_con…
LuckyCardC LuckyCard…(数据类被截断) 幸运卡/抽卡 game_config_default_fortune_card_r…/_choose_rew…/_extra_rew…
MineWarC MineWa…_ActivityD 矿战(报名/战斗/占领/排行奖励) game_config_default_mine_war_gather_r…/_t…/..._rule_…
PetFestivalC PetFestival_ActivityD 宠物节(宠物玩法换皮活动) game_config_default_pet_recharge_conf…、..._pet__recharge_c…
PinBallC/PinBallD PinBall_ActivityD 弹珠机(含儿童节换皮) 引导 Guide_Pinball_Teach_Children202…;req_pin_game_task 20251
SevenFestivalC SevenFestival_ActivityD 节日七日任务/积分 game_config_default_festival_sevendays_c…/_rew…、..._sevendays_task_c…
SocialMediaC (数据类未在证据中单独出现) 社交/媒体分享类活动 无独立配置前缀命中;由协议下发
TrialOfSurvivalC HeroicTrials_ActivityD(推测同族) 生存试炼 game_config_default_heroic_trials_r…/_s…

旁证:同目录另有大量非 activity 命名空间的活动控制器,功能等价:game_module_logic_module_activityaccumulative_AccumulativeActivityC(累计活动)、game_module_logic_module_anniversary_AnniversaryCtrl、game_module_logic_module_linkageharbin_LinkageHarbinC、game_module_logic_module_arsenalleague_*、game_module_logic_module_advertising_MirageTheatreC。

活动数据类全量(tokens.txt 截录,activity_data_ 后去前缀排序)共 110+ 个:Accumulative_ActivityD…、ActiveRecharge_ActivityD…、AnniversaryReview_ActivityD…、ArsenalLeague*、Balloon_ActivityD…、CapitalWar_ActivityD…、DuckMarket_ActivityD…、EmbarkOnANewJourne…、MergeMilestone_ActivityD…、PopularStar_ActivityD…、PitchPot_ActivityD…、ReturnSign_ActivityD…、Slg3League*、SnowClean_ActivityD…、StoveSkinGift_ActivityD…、SupremacyWar*、ThanksgivingCooking_ActivityD…、ThanksgivingFeast_ActivityD…、ThreeDayStore_ActivityD…、ThreeTiles_ActivityD…、TruckEscort_ActivityD…、Turntable_ActivityD…、ValueExchange_ActivityD…、VersionUp_ActivityD…、WorldBoss_ActivityD… 等。


2. 季节 / 节日活动战役(Seasonal & Holiday Campaigns)#

节日活动由同一批通用子玩法(PassCheck 通行证、FrozenTreasure、MostLords、PitchPot、SlotMatrix、FestivalTurntable、Accumulative、ValueExchange、PinBall、ThreeTiles、Recharge、SignIn…)叠加 活动前缀 组合而成。证据中可确定到年的 campaign 如下(token 大小写不敏感,均取自 tokens.txt / lua_strings_32.txt / Raw/data 清单):

战役 关键 token / 类 UI 面板 bundle(节选) 横幅/加载资源 i18n/配置佐证
端午 DragonBoat 2026(及 2024/2025) DragonBoat2026*、DragonBoat2025*、DragonBoatFestival2025、CreateDragonBoatFestival2025Tree ui_panel_activity_drop_activitydropdragonboatfestival2024/2025subpanel、DragonBoat2026PassCheckAndDailyTask*、DragonBoat2026SlotMatrix*、DragonBoat2026Exch…、DragonBoat2026PitchPot* spine_ui_loading_dragonboat2026、art_spine_ui_banner_dragonboat2025_gift_01/02_anim 词条 dragonboat2026_exchangeshop_single_bg_4…、SLOTMATRIX_NUMBER_STATS_DragonBoat2026
世界杯 2026 World Cup Activity_WorldCup2026、CreateActivityWorldCup2026Tree、WorldCup2026Pumpkin、worldcup2026_passcheck_icon worldcup2026_*、…PassCheck…、folt 系列 spine_ui_loading_worldcup2026_01..04_anim、spine_ui_banner_worldcup2026_gift_anim worldcup2026_festival_turntable_gift/rule/reward/bg_20x、头像 art_spine_ui_icon_touxiang_worldcup2026_anim
中秋 2026 Mid-Autumn(及 2024/2025) Activity_MidAutumn、Activity_MidAutumn2025/2026、CreateActivityMidAutumn2026Tree、Midautumn2026* ui_panel_frozentreasure_midautumn2024frozentreasure*、ui_panel_midautumn2024_midautumn2024popuppanel、ui_panel_accumulativeactivity_midautumnaccumulativeactivitysubpanel spine_ui_banner_mid_autumn2026_anim、scene_pitchpot_activity_pitchpot_scene_midautumn2026 中文串「【中秋的祈愿】活动即将结束/将于%{time}结束」、Midautumn2026PassCheckAndDailyTask
少儿/儿童节 2026 Children's Day Children2026*、Childrensday2026PassCheckAndDailyTask*、Children2026SevenDays、PinBallChildren2026、CreateActivityChildren2026Tree ui_panel_mostlords_childrensdaymostlords*、ui_panel_childrenfestival_childrenfestivalpanel art_spine_loading_loading_childrenday2026_01/02_anim、spine_ui_banner_children2026_giftpack_anim、spine_ui_banner_children2026_signin_anim 中文串「儿童节奇趣礼包」「儿童节盛宴筹备」「可获得儿童节个人派对积分」
元宵 Lantern 2025 / 2026 Activity_LanternFestival2026、CreateLanternFestival2026Tree、Lantern2026PassCheckAndDailyTask* ui_panel_activity_drop_activitydroplantern2025subpanel、lanternfestival2026_slotmatrix*、lanternfestival2026_single_valueexchange* art_spine_ui_banner_lanterngift2025_anim、spine_ui_lanternfestival_drawlots_2026_anim 中文串「糯糯元宵铭牌」
周年庆 Anniversary(2024/2025/2026 + 半周年) Anniversary2025/2026、AnniversaryReview2026、AnniversarySignIn…、CreateAnniversary2025Tree、CreateAnniversaryReviewTree、onehalfanniversary ui_panel_anniversarysignin_*、ui_panel_interactive_anniversaryinteractive*、ui_panel_main_sub_lobbycenteranniversaryfeastitem art_effect_ui_material_anniversary2026、scene_activity_anniversarysigndraw_fxui…、art_effect_ui_material_onehalfanniversary 中文串「周年信件」「事件一周年」、game_config_default_anniversary_*(mess/pv/review/tower…)
感恩节 Thanksgiving(2024/2025) Thanksgiving2024/2025、CreateActivityThanksGivingTree、ThanksgivingFeast*、ThanksgivingCooking* ui_panel_main_sub_lobbycenterthanksgivingfeastitem、ui_panel_frozentreasure_* ui_panel_worldscene_thanksgiving_fxui_*、art_spine_ui_icon_touxiang_thanksgiving2025_anim 中文串「感恩节盛宴」;配置 thanksgiving_feast_*、thanksgiving_cook_*、thanksgiving_menu_*、thanksgivingday_*
圣诞 Christmas(2023/2024/2025) CreateActivityChristmas2024Tree、Christmas2024*、christmas2024frozentreasure*、ChristmasFindC、ChristmasFind_ActivityD ui_panel_threetiles_christmasthreetiles*、ui_panel_accumulativeactivity_christmasaccumulativeactivitysubpanel、scene_city_christmas_npc_xmas art_effect_ui_material_christmas2023、ui_panel_lobby_fxui_lobby_christmas_tishi_wwj 中文串「装扮圣诞树」「【水晶圣诞树】装扮」「圣诞…」
哈尔滨联动 Linkage Harbin(冰雪大世界) LinkageHarbinC、LinkageHarbin_ActivityData、linkageharbin_activityd、CreateLinkageHarbinNode ui_panel_linkageharbin_linkageharbinsubpanel 词条 linkage_harbin_ui_01..08 定义文件 sharedef/linkage_harbin_activity_def.lua(协议注释原文:「奖励状态(取值见 sharedef/linkage_harbin_activi…」lua_strings_32.txt);中文串「冰雪大世界」;err_linkage_harbin_received;banner activity_banner_20023001
足球 Football = 世界杯 2026 同上 WorldCup2026 同上 同上 头像/横幅/加载三件套均以 worldcup2026 命名
(佐证)音乐节 2025、运动会 2025、联动大富翁 2026 MusicFestival2025、CreateActivityMusicFestival2025Tree、SPORTS_MEET_2025_FESTIVAL_TURNTABLE_、CreateActivitySportsMeetTree、LinkageMonopoly2026PassCheckAndDailyTask ui_panel_lobbycenter…musicfestivalfeastitem、ui_panel_travel_monopoly_*、ui_panel_activitygift_activitygiftlinkagemonopolyslapface* spine_ui_banner_music2025_01..03_anim game_config_default_monopoly_linkage_*(联动大富翁配置族)

说明:DragonBoat2026、WorldCup2026、Children2026、Midautumn2026、Lantern2026、Anniversary2026、Valentine2026、Spring2026(春节)在 token 池中出现的换皮词条数量为 60–109 个/战役,说明活动以「通用玩法模板 + 节日皮肤」批量复用(见 §3)。


3. 活动定义与生命周期(Data-Driven Activity Model)#

3.1 定义文件与配置表

  • 活动定义文件:证据中唯一命名的服务端定义文件是 sharedef/linkage_harbin_activity_def.lua(lua_strings_32.txt 协议注释引用),命名模式为 sharedef/<活动>_activity_def.lua;其字段被协议注释直接引用(「奖励状态(取值见 sharedef/…_activity_def.lua)」)。
  • 通用活动数据模型(协议 DSL 字段,lua_strings_32.txt): id、activity_type、begin_ts/end_ts、actEndTime、actSettleTime、start_time/end_time、main_icon_id、calendar_color、calendar_bg、calendar_desc、banner、preview_banner、activity_name、activity_icon、activityRandomKey、map_id、boxRewardList、illusts。→ 说明活动开启/结束时间、图标、日历配色、横幅、随机种子均由服务端配置下发(数据驱动),客户端仅渲染。
  • 核心配置家族(config_tables.txt,截断照录):
家族 代表表名(证据原文) 用途
充值/累计 game_config_default_active_recharge_activity_t…、..._active_recharge_coll…、..._accumulative_recha…、..._month_recharge_c… 充值类活动条件与档位
活动中心/图标 ..._activity_center_s…、..._activity_main_icon_…、..._activity_main_icon_lo…、..._activity_exchange_go… 活动日历、入口图标、兑换跳转
目标/积分 ..._target_activity_c…、..._integral_activity_c…、..._target_rank_rew… 目标积分活动与排行奖励
礼包 ..._activity_gift_po…、..._gift_activity_…、..._optional_gift_p…、..._birthday_gift_pre…、..._subscription_gift_con… 活动礼包/可选礼包/生日礼包/订阅
掉落 ..._drop_activity_…、..._relic_adventure_drop_rew… 掉落活动
抽奖/转盘 ..._recharge_lottery_…、..._recharge_lottery_guarant…(保底)、..._recharge_lottery_rew…、..._hero_turntable_r…、..._festival_turntable_gr…/_rew…/_s…、..._icebound_amazing_lottery…、..._fortune_card_* 抽奖/转盘/幸运卡
排行 ..._world_boss_rank_rew…、..._three_tiles_rank_rew…、..._fishing_ranking_*、..._arsenal_league_rank_rew…、..._popular_star_rank_rew… 活动排行榜奖励
节日七日 ..._festival_sevendays_c…/_rew…、..._sevendays_task_c…/_con…/_group/_rew… 七日任务/节日挑战

3.2 Gift / Drop / Rank / Lottery 四大子类型

类型 逻辑类 数据/协议 配置
Gift(礼包) ActivityGiftC/ActivityGiftCtrl;prefab_free/prefab_custom(触发礼包面板绑定) ActivityGiftInfo;req_activity_gift_popup_claim 21131、notify_pick_one_gift_info 17601、push_multiple_choice_activity_info 16410 activity_gift_po…、gift_activity_…、gift_type 字段
Drop(掉落) ActivityDropC/ActivityDropCtrl;ActivityDrop{Common,Children,Easter,Halloween,Valentine,…}SubPanel DropEvent/DropEventId/DropEvent_Activity/ActivityDrop_ActivityD…;notify_activity_drop_direct 2103、NotifyDropEventInfo drop_activity_…、drop_type 字段
Rank(排行) 各活动 *RankPanel;服务端排行 req_target_integral_rank 10252、req_world_boss_get_rank 20612、req_three_tiles_get_rank_info 15783、req_popular_star_rank 20501、req_fishing_self_rank 13512 target_rank_rew…、three_tiles_rank_rew…、world_boss_rank_rew…
Lottery(抽奖/转盘) 转盘/抽奖面板 req_recharge_lottery_draw 20281、req_sign_draw_lottery 16132、req_hero_turntable_get_free_gift 10353、req_festival_turntable_shop_buy 20645、LOTTERY_DRAW/FREE_SUCCESS 事件 recharge_lottery_guarant…(保底机制)、festival_turntable_*、hero_turntable_*

3.3 生命周期(日历 → 开启 → 进行 → 结算 → 关闭)

证据中的状态机与消息:ACTIVITY_STATE、ACTIVITY_STATE_CHANGE、ACTIVITY_CHANGE_STAGE、ACTIVITY_ENTER、ACTIVITY_FORCE_CLOSE、ACTIVITY_CLOSE、ACTIVITY_END、ACTIVITY_END_TIME、CheckActivityState、ActivityStage。

阶段 关键协议 / 操作码
拉取日历 req_activity_calendar_get_data 9901 → notify_activity_calendar_data 9925
活动信息/阶段 notify_test_activity_info 2101、notify_version_up_activity 13161、notify_activity_calendar_data
开启/关闭(调试) start_activity 1234、close_activity 1235、req_cheat_refresh_activity_event 1278、req_cheat_open_global_activity 14008
掉落推送 notify_activity_drop_direct 2103
入口/报名 req_alliance_activity_auto_join_info 10001 / _open 10002、notify_fortwar_activity_init 10761、req_linkage_monopoly_open_activity 30758
结束 ACTIVITY_FORCE_CLOSE、ACTIVITY_GIFT_END

4. 协议(Protocol / Opcodes)#

活动相关操作码分布(protocol_ops.txt + lua_strings_32.txt 交叉核对;部分 req_ 因截断显示为 eq_/q_/_):

操作码 协议名 分类
9901 req_activity_calendar_get_data 活动总控/日历
9925 notify_activity_calendar_data 活动总控/日历
2101 notify_test_activity_info 活动总控
2103 notify_activity_drop_direct 掉落
1234 / 1235 start_activity / close_activity 生命周期(作弊/调试)
21131 req_activity_gift_popup_claim 礼包
17601 / 17602 notify_pick_one_gift_info / notify_pick_one_gift_recharge_success 礼包(多选一)
16410 push_multiple_choice_activity_info 礼包(多选一)
16151 req_gift_message_get_reward 礼包
9751 / 9770 / 9772 req_accumulative_collect_reward / notify_accumulative_info / notify_accumulative_progress_change 累计充值/消耗
12921 / 12931 / 12932 / 12933 req_activity_get_task_reward / …task_activity_info / …activity_task_update / …activity_integral_update 活动任务/积分
12922 req_daily_task_activity_get_integral_reward 日常任务活动
11301 / 11352 notify_exchange_activity_info / req_exchange_activity_exchange_all 兑换活动
20645 / 20647 req_festival_turntable_shop_buy / notify_festival_turntable_info 节日转盘
10352 / 10353 / 10354 req_hero_turntable_extra_reward / _get_free_gift / _switch_version 英雄转盘
20281 / 20282 / 20291 req_recharge_lottery_draw / _acc_box / notify_recharge_lottery_info 充值抽奖
16131 / 16132 / 16133 / 16140 …sign_draw_get_sign_progress_reward / req_sign_draw_lottery / …free / notify_sign_draw_info 签到抽奖
11551 / 11552 / 11757 req_get_festival_sevendays_quest_reward / _score_reward / update_festival_sevendays_quest 节日七日
20261 / 20262 / 20271 / 20272 req_get_sevenday_task_reward / _score_reward / notify_sevenday_task_init / notify_update_sevenday_task_quest 七日任务
20250 / 20251 notify_pin_game_update / req_pin_game_task 弹珠机
20423 req_pachinko_task 弹珠/扭蛋
20751 / 20757 req_balloon_sign_reward / notify_balloon_sign 气球签到
16252 / 16253 / 16261 req_home_sign_get_reward / _all_reward / notify_home_sign_info 家园签到
15814 / 15783 notify_three_tiles_task_info / req_three_tiles_get_rank_info 三消/翻牌
17410 / 17411 notify_puzzle_shop_info / req_puzzle_shop_buy_item 拼图商店
21031 / 21033 notify_magic_potion_init / req_magic_potion_task_reward 魔法药水
20926 / 20927 / 20903 notify_pitch_pot_ticket / _task_update / req_pitch_pot_task_reward 投壶
15670 / 15672 / 15601 / 15622 / 15623 notify_thanksgiving_cooking_info / …exchange_lst_nums_update / req_thanksgiving_sign_get_reward / req_thanksgiving_menu_rank / …self_rank 感恩节
15635 / 15655 / 15683 …thanksgiving_menu_activity_info / req_thanksgiving_cooking_exchange / req_thanksgiving_bp_alliance_member_rank 感恩节
11652 / 11654 / 11655 / 11683 / 11684 req_fes_bp_get_all_reward / _donate_item / _rank / notify_fes_bp_purchase / _buy_gift 节日战令
13753 / 13754 / 13782 / 13785 req_fes_bp_dailytask_get_extra_reward / _task_reward / notify_fes_bp_dailytask_purchase / …task_info 节日战令日常
10406 / 10408 / 10410 req_alliance_trap_join_count / _batch_get_personal_score_reward / _auto_reserve 联盟陷阱
16815 / 16816 / 16856 notify_supremacy_war_feast_gift_buy / …unread_record / …supremacy_war_gift_record 霸主盛宴
16571 / 16581 req_supremacy_war_task_reward / notify_supremacy_war_task_info 霸主之战
20614 / 20632 req_world_boss_get_boss_info / notify_world_boss_info_update 世界 BOSS
30201 / 30202 req_linkage_harbin_change_state / req_linkage_harbin_get_reward 哈尔滨联动
30745–30790 req_linkage_monopoly_* / notify_linkage_monopoly_*(约 20 条:open_activity 30758、free_gift 30769、play_dice 30786、quest 30789/30790…) 联动大富翁
4352 / 4652 / 7431 / 11005 / 13507 / 16292 / 30702 req_daily_bundle_get_free_gift / req_vip_get_daily_free_gift / req_gift_buy_free_gift / req_fortune_card_get_daily_free_gift / req_fishing_get_free_gift / req_limit_time_shop_get_free_gift / req_stove_skin_gift_daily_free_reward 每日免费礼包
10908 req_capital_war_gift 王城战礼包
14003–14016 req_cheat_back_start / …back_end / …finish_festival_sevenday_quest / …thanksgiving_menu_add_integral 等 活动作弊面

另有世界/联盟情境活动(req_situation_activity 7058、req_unwatch_alliance_situation_activity 7007)、活动战力同步(notify_player_activity_power_update 1030)、动员活动更新(notify_mobilization_activity_update 10172)、版本升级活动(notify_version_up_activity 13161)。

通知/推送类活动 op 还包含:notify_activity_drop_direct 2103、notify_activity_calendar_data 9925、notify_festival_turntable_info 20647、notify_recharge_lottery_info 20291、notify_sign_draw_info 16140、notify_accumulative_info 9770、notify_fes_bp_info 11681、notify_thanksgiving_cooking_info 15670、push_multiple_choice_activity_info 16410。


5. 风险(Risk)#

5.1 限时优惠 / FOMO 推送

  • 客户端内置大量触发式礼包面板:ui_panel_gift_giftpushcustompanel_100001..2026、gifttriggerbagpanel_2026、gifttriggerbagpanel_2490050/2490356/2490359/…、gifttriggerbagbirthdaypanel、gifttriggeralonepanel、giftrechargetokenpanel、giftpushcustomtriggerpanel、pushmultiplechoicepackpanel_100001..100007、vipexclusivegiftpackagesubpanel、optionalgiftpanel。
  • 配合限时商店与每日免费礼包协议(req_limit_time_shop_get_free_gift 16292、req_daily_bundle_get_free_gift 4352、req_vip_get_daily_free_gift 4652、req_stove_skin_gift_daily_free_reward 30702),构成「倒计时 + 触发弹窗 + 每日免费领取」的经典 FOMO(错失恐惧) 商业化链路。
  • 累计充值/消耗(accumulative)、节日战令(fes_bp)、转盘(turntable)均在活动截止时清零/结算(ACTIVITY_END_TIME、ACTIVITY_FORCE_CLOSE)。

5.2 抽奖 / 扭蛋概率

  • 存在保底配置 game_config_default_recharge_lottery_guarant…,说明保底机制为服务端配置驱动;抽奖/转盘还包括 hero_turntable_*、festival_turntable_*、sign_draw_lottery、fortune_card_*、treasure_hunt_*、icebound_amazing_lottery。
  • 协议字段含 activityRandomKey(随机密钥/种子),抽奖结果由服务端裁定(LOTTERY_DRAW_SUCCESS 等事件);赔率/保底不进客户端,但 UI 会展示「概率/说明」文本(recharge_ui_22、festival_turntable_err_01「活动数据异常,请稍后再试」)。
  • 风险点:多入口(充值抽奖 20281、签到抽奖 16132、英雄转盘 10353、节日转盘 20645)并存的概率型付费,需关注各地合规披露(概率公示、保底声明)。

5.3 客户端信任边界

  • 业务逻辑整体位于 LuaJIT 字节码(可逆),活动状态机(ActivityState/ActivityStage)、掉落展示、礼包触发面板均在客户端执行;服务端通过 req_/notify_ 协议做权威校验(领取、购买、抽奖均走 req_*)。
  • 证据中存在成体系的作弊接口(req_cheat_*:req_cheat_open_global_activity 14008、req_cheat_refresh_activity_event 1278、req_cheat_start_sevenday_task 14062、req_cheat_fes_bp_add_integral 1280、req_cheat_thanksgiving_menu_add_integral 14016、req_cheat_linkage_monopoly_try_join_teams 14300 等)。这些接口是攻击面:若服务端鉴权不足,可能被用于刷活动积分/奖励;建议确认其在正式服被禁用或严格白名单。
  • 活动定义以 sharedef/<活动>_activity_def.lua(如 linkage_harbin_activity_def.lua)形式下发,配置/奖励判定若被客户端缓存,需验证奖励领取是否二次校验而非仅信任客户端上报。

证据复核要点:活动控制器 tokens.txt:164798–165119;活动数据类 110+ 条;协议操作码取自 protocol_ops.txt 与 lua_strings_32.txt 协议 DSL;节日 campaign 词条来自 tokens.txt / Raw/data 资源清单;sharedef/linkage_harbin_activity_def.lua 为 lua_strings_32.txt 中唯一显式命名的活动定义文件。


附录 · 复现环境、命令与artifacts#

A.1 分析环境#

项 值
主机 macOS 26.6.2 (Build 25G83), arm64 (Apple Silicon)
工具链 Xcode Command Line Tools(otool/nm/lipo/codesign/plutil/dyld_info/unzip/strings)
脚本 Python 3.9.6 + numpy 2.0.2
样本 SHA-256 1e64c47197def718e28f5ed0acd4aeba03bcfe497bf6b3284ff086d060a8b3aa

A.2 关键产物(playground20261012/artifacts/)#

文件 说明
global-metadata.dec.dat 解密后的 IL2CPP 元数据(9,902,340 B, version 31)
out_identifiers.txt 从元数据还原的 88,084 个标识符(类/方法/字段名)
out_literals.txt 19,294 条字符串字面量(含 URL/密钥线索)
out_types.txt 按程序集分组的 8,511 个类型全名
key612.bin / key612_mode.bin 众数法恢复的候选密钥(过程产物)
decrypt_global_metadata.py 可复现的元数据解密脚本

A.3 一键复现#

# 0) 解包
cd /Users/jarvis/Downloads/playground20261012
unzip -q com.gof.china_1.15.6_und3fined.ipa -d extracted
APP=extracted/Payload/whiteoutsurvivalcn.app

# 1) 确认脱壳
otool -l $APP/whiteoutsurvivalcn | awk '/LC_ENCRYPTION_INFO_64/,/cryptid/'
otool -l $APP/Frameworks/UnityFramework.framework/UnityFramework | awk '/LC_ENCRYPTION_INFO_64/,/cryptid/'

# 2) 解密 IL2CPP 元数据(密钥 NTESCSLLVMPASSKEY,周期 17)
python3 artifacts/decrypt_global_metadata.py \
    $APP/Data/Managed/Metadata/global-metadata.dat \
    artifacts/global-metadata.dec.dat

# 3) 校验
xxd artifacts/global-metadata.dec.dat | head -1
strings artifacts/global-metadata.dec.dat | grep -m3 -E 'AntiCheatResult|DecryptLuaBytecode|UnityEngine.MonoBehaviour'

A.4 元数据解析片段(自研解析器)#

import struct
d = open("artifacts/global-metadata.dec.dat", "rb").read()
u32 = lambda o: struct.unpack_from("<I", d, o)[0]
assert u32(0) == 0xFAB11BAF and u32(4) == 31
# 头字段: magic, version, (offset,size) * N  —— 见报告 6.3.1 表
off_str, cnt_str = 0xAB648, 0x211DDC
heap = d[off_str:off_str+cnt_str]
def name(i):
    return heap[i:heap.find(b"\x00", i)].decode("utf-8", "replace")
# 类型定义 size=88, 字段 nameIndex 在偏移 0, namespaceIndex 在偏移 4
td, SZ = 0x81394C, 88
for i in range(748968 // SZ):
    b = td + i*SZ
    print(name(u32(b)), name(u32(b+4)))

A.5 主要命令清单#

# 结构
file whiteoutsurvivalcn; lipo -info whiteoutsurvivalcn
otool -hv whiteoutsurvivalcn
otool -L Frameworks/UnityFramework.framework/UnityFramework

# 权限 / 签名
codesign -dv --verbose=4 whiteoutsurvivalcn
codesign -d --entitlements :- whiteoutsurvivalcn
plutil -p Info.plist
plutil -p PlugIns/CGPushServerExtension.appex/Info.plist

# 串
strings -n 6 Frameworks/UnityFramework.framework/UnityFramework | grep -iE 'jailb|cydia|frida|AntiCheat|tamper'

# 框架版本
for d in Frameworks/*/; do \
  echo "$d $(plutil -extract CFBundleShortVersionString raw "$d/Info.plist")"; done

A.6 游戏内容(Lua)提取工具链#

包内玩法逻辑以 LuaJIT 字节码 形式承载于 luapackage_32/64(各 406 个压缩块,首个块加密)。提取步骤:

# 1) 重建解压流(跳过加密的首块)
python3 tools/extract_lua.py            # -> artifacts/lua/*.partial/bin
# 2) 从字节码中提取字符串常量(ULEB128 长度前缀启发式)
python3 tools/extract_lua_strings.py artifacts/lua/luapackage_32_*.partial.bin artifacts/lua/lua_strings_32.txt

产出数据集(artifacts/lua/):

文件 内容
luapackage_32/64_*.partial.bin 重建数据流(各 ~53MB)
lua_strings_32.txt 从字节码提取的 297,209 条字符串常量
tokens.txt 252,027 个干净标识符
config_tables.txt 1,600 个 game_config_* 配置表名
protocol_ops.txt 2,635 条网络协议 opcode ⇄ 名称
ui_views.txt 6,977 个 View/Panel/Ctrl
activity_tokens.txt 129 个活动/节日标识符

说明:luapackage 中内嵌了游戏自己的网络协议定义文本(形如 _league_detail_4_player_situation 17208 { request { owner 0 : ... } }),据此可完整还原 opcode 表与字段结构。

A.7 报告合并与站点构建#

python3 tools/merge_report.py     # 合并 report/*.md -> 单一全文
python3 tools/build_site.py       # 生成 site/(index.html + 样式 + 交互)
npx wrangler pages deploy ./site --project-name=whiteout-survival-reverse --branch=main

A.8 免责声明#

以上全部操作均为离线、只读的静态分析,未连接任何线上服务、未绕过鉴权与付费。仅用于授权范围内的安全研究与防御加固。