JesperLive/gse-companion-disclosure

GitHub: JesperLive/gse-companion-disclosure

一份可复现的技术披露仓库,记录了《魔兽世界》GSE 插件及其桌面配套应用中未公开的竞品检测、服务端控制的数据删除和序列锁定行为。

Stars: 0 | Forks: 0

# GSE (GnomeSequencer-Enhanced) 和 GSE Companion 应用中未公开的竞品插件检测、服务端控制的数据删除及序列锁定 **发布日期:** 2026-06-12 **作者:** Jesper (JesperLive / MrSataana),GRIP - Enhanced Macro Sequencer (GRIP-EMS) 开发者 **涉及软件:** GSE Companion v0.4.12(桌面应用),分发于 https://gse.tools/releases **相关项目:** GSE: Sequences, Variables, Macros (GnomeSequencer-Enhanced),一款《魔兽世界》插件 ## 本仓库记录的内容 这是一份关于 GSE(也称为 GnomeSequencer-Enhanced 或 "GSE: Sequences, Variables, Macros",《魔兽世界》宏插件)及其桌面配套程序(从 gse.tools 分发的 GSE Companion 应用)行为的技术复现记录。结合公开下载的代码引用和分步复现过程,本文记录了以下内容:GSE Companion 应用检测竞品插件的存档数据、向 GSE 服务器汇报、标记用户账号,并携带由服务端控制删除该数据的例程;随后将这种删除机制移入了一个通用的、由 ed25519 签名和服务端下发的文件修改引擎中;以及在游戏内 GSE 插件中的改动,这些改动将其序列数据对其他插件封闭,包括一种新的 ChaCha20 加密序列格式。本文的每一项声明都是您可以在已发布文件中直接读到的代码行。我是竞争对手,所以请不要只听信我的一面之词:每一节末尾都提供了供您自行复现的步骤。 供相关研究者参考的关键词:GSE, GnomeSequencer-Enhanced, GSE Companion, gse.tools, World of Warcraft macro addon, SavedVariables, sequence import and migration, addon security。 ## 首先请阅读:我是谁以及如何看待本文档 我是 GRIP-EMS 的作者,这是一款免费的《魔兽世界》宏插件。下文描述的软件由竞争对手项目 GSE 开发,其包含的行为专门针对我的插件。 我是竞争对手。您不应盲目相信我的任何话。编写本文档是为了让您不必这样做:每一项声明都是已发布文件中引用的代码行,并且从公开下载版本中复现所有内容的步骤均附在文末。请自行验证并忽略我个人的主观阐述。 ## 一段话摘要 GSE Companion 是 GSE 分发的一款桌面应用程序,作为向 GSE 插件“同步”宏序列的工具。该已发布的应用程序还包含一个“访问策略”子系统,在登录时及随后每十分钟执行以下操作:(1) 扫描每个已安装《魔兽世界》客户端的 SavedVariables,寻找我的插件的存档文件 `GRIP-EMS.lua`;(2) 向 GSE 的后端汇报我的插件是否存在,并在已登录用户的 GSE 账号上设置 `restrictedAccount` 标志;(3) 携带一个名为 `purgeGripCharSequences` 的例程,该例程会打开我的插件的按角色存档文件并从中删除序列,此操作由服务端控制的开关控制。Companion 的文档中并未描述任何这些内容,其文档仅将该应用程序展示为一个序列同步工具。 ## 该应用程序是什么 GSE Companion 是一个 Electron 桌面应用。Electron 应用将其 JavaScript 存储在 `resources/app.asar` 归档文件中,一旦解压即为纯文本——不涉及任何反编译。下文所有内容均引用自已安装应用程序中的该文件。以 `//` 开头的英文行是我的注释;代码行均为原文照录。 ## 发现 1 — 检测、汇报竞品数据及条件性删除 **应用程序中定义的常量:** ``` const GSE_API_URL = "https://api.qik.dev"; const GSE_SVC_URL = "https://api.gse.tools"; const GRIP_SV_FILENAME = "GRIP-EMS.lua"; const ACCESS_POLICY_REFRESH_MS = 10 * 60 * 1000; ``` **调度逻辑(`runAccessPolicyCheck`,在登录和 10 分钟计时器触发时调用):** ``` const present = detectGripEmsAcrossClients(clients, getWtfAccounts); accessPolicyState.restricted = !!present; if (personaId && token) { accessPolicyState.lastSyncResult = await syncRestrictedAccountFlag({ apiUrl: GSE_API_URL, token, personaId, present }); } const e = await fetchAccessPolicy(GSE_SVC_URL); // GET /settings/access-policy accessPolicyState.enforce = !!e.enforce; if (accessPolicyState.restricted && accessPolicyState.enforce) { ... if (!anyRunning) runAccountCleanup(clients); } ``` **删除例程(`purgeGripCharSequences`):** ``` const charBlob = parsed.GRIP_EMS_CHAR; const sequences = charBlob?.sequences; ... for (const [seqName, seqData] of Object.entries(sequences)) { if (!seqData || typeof seqData !== "object") continue; const provenance = seqData.provenanceSource; const isGseLegacy = provenance === "gse-legacy"; const nameMatchesGse = gseSequenceNames?.has?.(seqName); if (isGseLegacy || nameMatchesGse) { toDelete.push(seqName); } } // entries in toDelete are then removed from `sequences` and the file is // atomically rewritten (writeSync to a .tmp, then renameSync over the original) ``` **其行为的具体说明:** - `detectGripEmsAcrossClients` 遍历每个已配置《魔兽世界》客户端的 `WTF/Account/*/SavedVariables` 文件夹以及每个角色文件夹,寻找名为 `GRIP-EMS.lua` 的文件——即我的插件的存档文件。 - `syncRestrictedAccountFlag` 调用 GSE 的后端(`api.qik.dev`),并根据我的插件是否存在,在已登录用户的 GSE 账号记录上设置 `data.restrictedAccount = true` 或 `false`。只要用户登录了 Companion,此操作就会运行,与删除开关无关。 - `fetchAccessPolicy` 从 `https://api.gse.tools/settings/access-policy` 读取服务端控制的布尔值 `enforce`。 - 如果 `restricted && enforce` 为真且《魔兽世界》未运行,`runAccountCleanup` 将调用 `purgeGripCharSequences`,它会打开用户的 `GRIP-EMS.lua`,删除 `provenanceSource` 为 `"gse-legacy"` 或名称匹配 GSE 序列的条目,并在没有这些条目的情况下重写文件。要求《魔兽世界》处于关闭状态很重要,因为正在运行的游戏会在下次保存时覆盖被编辑的文件。 **这是专门针对我的插件编写的,而不是某种通用启发式规则。** GRIP-EMS 的 TOC 声明了 `## SavedVariablesPerCharacter: GRIP_EMS_CHAR`,《魔兽世界》会将其写入 `GRIP-EMS.lua`。Companion 精确读取 `parsed.GRIP_EMS_CHAR.sequences`,并以 `provenanceSource === "gse-legacy"` 作为删除依据,这正是 GRIP-EMS 用于标记用户从 GSE 导入的序列的内部标签。该例程按名称直接针对我的插件在磁盘上的真实 schema。 ## 游戏内插件引导用户使用 Companion 托管在 CurseForge 上的免费 GSE 插件(当前文件版本 3.3.22)包含指向 Companion 的链接,并引导用户完成安装,尽管商店列表中并未提及。在已发布的免费版本中: - `GSE_GUI/Editor_Tree.lua` — 包含一个指向 `https://gse.tools` 的游戏内可点击链接,该网站分发 Companion。 - `GSE/Localization/ModL_enUS.lua` — 游戏内文本显示:“在 gse.tools 下载 Companion。安装后,插件列表中会出现一个小型桥接插件(GSE Companion Bridge)——请保持其启用状态。” - `GSE_Options/Options.lua` — 一个“Companion App”设置面板(自动接受 Companion 更新,同步《魔兽世界》宏到 GSE.Tools)。 这些字符串在免费版本和 PATRON 版本中逐字节相同。正是游戏内的这个插件将用户引导至上述桌面应用程序。 ## 我未声明的内容 我刻意限定了本发现的范围,以确保准确性: - 检测和账号标记在用户登录 Companion 后无条件运行。这存在于已发布的代码中,并且在今天依然运行。 - 删除操作受服务端的 `enforce` 标志控制。其当前值由 GSE 设置,无法从客户端观察。我**并未**声称该删除功能目前对任何用户开启了。 - 我的陈述是狭窄且可验证的:即当前分发的应用程序中包含了用于检测竞品存档文件、向服务器汇报其存在、标记用户账号的代码,并携带了一个可远程触发以删除该竞品数据的例程。最终开关目前是否被开启,是唯一无法从客户端观察到的部分。 ## 发现 2(次要)— 付费的 "PATRON" 版本插件 GSE 在 https://gse.tools/releases 上与公开版本一同发布了单独的 "PATRON" 版本。比较同一版本(`3.3.22`)的公开版本和 PATRON 版本: - 两个版本中共同存在的文件除了某一行外完全(逐字节)相同:PATRON 版本的 `.toc` 版本字符串以 `-PatronBuild` 结尾。 - `GSE/API/Init.lua` 包含:`if GSE.VersionString:find("Patron") then GSE.Patron = true end`。 - 该标志控制着编译在两个版本中的功能:原始宏编辑、多窗口编辑、变量和序列的 Tab 自动补全、点击计时配置以及高级导出功能。PATRON zip 包还额外附带了一个 `GSE_QoL` 模块(原生图标选择器、Skyriding 快捷键栏、保存时校验和印记)。 为准确起见:CurseForge 仅托管免费的 GSE 版本;PATRON 版本通过 CurseForge 之外的 gse.tools 分发。暴雪的 UI 插件开发政策第 1 点指出,所有插件必须免费分发,开发者不得创建带有额外付费功能的高级版本。带有功能限制门控的付费插件版本本身,正是该政策所针对的范畴。 在当前版本(3.3.22,2026-06-16)上重新验证:公开版和 PATRON 版文件树除了 `.toc` 文件中的版本字符串以及 Patron 独享的 `GSE_QoL` 模块外完全相同。根据开发者自己的 Patreon 说明,PATRON 版本已“进行角色锁定,因此仅对 Patrons 可用”。 ## 如何自行验证以上所有内容 **发现 1 (Companion):** 1. 从 https://gse.tools/releases 下载 GSE Companion 并安装。 2. 打开 `%LOCALAPPDATA%\Programs\gse-companion\resources\app.asar`。这是一个 asar 归档文件;使用 `npx asar extract app.asar out` 解压它,或使用任何文本编辑器或 `strings` 工具直接读取。 3. 在内容中搜索:`detectGripEmsAcrossClients`、`syncRestrictedAccountFlag`、`purgeGripCharSequences`、`GRIP-EMS.lua`、`GRIP_EMS_CHAR`、`access-policy`。 4. 确认上述常量和 `runAccessPolicyCheck` 流程。 关于 v0.4.14(当前版本)的注意:步骤 3 中的函数名已被混淆(minified),且四个 GRIP-EMS 标识符经过了 Base64 编码,因此纯文本搜索不会有结果。请使用 [UPDATE-2026-06-20-v0.4.14-obfuscation.md](UPDATE-2026-06-20-v0.4.14-obfuscation.md) 中的更新方法:搜索 Base64 字面量(例如 `R1JJUC1FTVMubHVh`)并进行解码,或查看 [evidence/app_asar_grip_region_0.4.14.js](evidence/app_asar_grip_region_0.4.14.js)。 **发现 2 (付费版本):** 1. 从 https://gse.tools/releases 下载同一版本的公开版和 PATRON 版 zip 压缩包。 2. 比较两个文件夹树的差异。共有文件仅因 `-PatronBuild` 版本字符串而异;PATRON 版本添加了 `GSE_QoL` 文件夹。打开 `GSE/API/Init.lua` 和 GUI 文件即可查看 `GSE.Patron` 功能门控。 ## 文件完整性 (SHA-256) 所有文件均在所示日期获取。如有需要,我可以提供这些文件中的任何一个,或提取出的 `app.asar` JavaScript。 - **GSE Companion Setup 0.4.12.exe**(安装程序,来自 gse.tools/releases) `706742b44f5ea9056f67df2e8cae771cd909dd0b882a0d4c3bf87a7639d0043f` 81,299,552 字节 — 获取于 2026-06-11 - **resources/app.asar**(已安装的 Companion 应用程序逻辑) `209adedde7905179832038661b5d279a95831a155d963da3190871d502f36b0f` 6,068,792 字节 — 安装于 2026-06-09 - **GSE-3.3.20-9-gd5e65ce.zip**(公开插件版本) `789753305d33dc21732b67948ef839f4b058fcc15e095b8be8fcb855e28d9c85` 2,514,665 字节 — 获取于 2026-06-11 - **GSE-3.3.20-9-gd5e65ce-PatronBuild.zip**(PATRON 插件版本) `7ea11bd7dbe6bb64eb1867462197c7ac52e795a0e7a528eeba77d62be475f5a0` 2,522,115 字节 — 获取于 2026-06-11 - **GSE Companion Setup 0.4.13.exe**(安装程序,来自 gse.tools/releases) `d580dc7c7c39fb747b25830e8233d71b7f4404a07d3c8b14262dc3254d114729` 81,299,75 字节 — 获取于 2026-06-17 - **resources/app.asar**(0.4.13,从安装程序中静态提取) `4f9a2664ea0d2cb5a4f4594299dfd7e74242379fd4fbf2edbf75655893278c5f` 6,068,841 字节 — 提取于 2026-06-17 ## 本文档范围 本文档是对已分发软件行为的描述,并附有引用的代码和复现步骤。它不涉及对任何人品行的指控,也不涵盖社区管理、账号封禁或项目间的任何纠纷——仅客观陈述已发布应用程序的具体行为。请根据文件自行得出结论。 ## 本仓库中的文件 - `README.md` — 本文档。 - `hashes.txt` — 安装程序、`app.asar` 及两个插件版本的 SHA-256 哈希值。 - `evidence/app_asar_grip_region.js` — 从 Companion 的 `app.asar` 中提取的代码区域,包含上述引用的访问策略、检测、账号标记和删除代码。请阅读实际文件,而不仅是信赖本文的引用。 - `evidence/patron_vs_public_build_diff.txt` — 公开版与 PATRON 插件版本的文件树和内容对比(支持次要发现)。 - `evidence/ems_vs_gse_similarity_scan.txt` — GRIP-EMS 和 GSE 之间的源码相似度扫描,出于完整性考虑而包含在内,以便插件代码问题也能被独立核对。 - `UPDATE-2026-06-20-v0.4.14-obfuscation.md` — 2026-06-20 更新:v0.4.14 保留了相同的定向代码,但对 GRIP-EMS 标识符进行了 Base64 编码。包含纯文本 (0.4.12) 与 Base64 (0.4.14) 的对比、解码过程及更新的复现方法。 - `FULL-TECHNICAL-AUDIT-v0.4.14.md` — 对 v0.4.14 的完整静态安全审计。上述针对竞争对手的行为是核心重点;审计还涵盖了应用程序的其余部分(大部分平淡无奇),并为求完整,记录了自动更新程序中一个不相关的常规安全问题。 - `evidence/app_asar_grip_region_0.4.14.js` — v0.4.14 的原样代码区域(检测器、账号标记、删除、策略调度器);这是 0.4.12 提取物的对应版本。 - `evidence/decoded_strings_0.4.14.txt` — 四个 Base64 字面量及其解码后的值。 - `evidence/live_access_policy_2026-06-20.json` — 2026-06-20 对服务器线上 `enforce` 标志(`false`)的抓取记录,以及所使用的请求。 - `evidence/file_manifest_0.4.14.txt` — v0.4.14 安装程序有效载荷和 `app.asar` 中每个文件的 SHA-256 哈希。 - `UPDATE-2026-06-21-v0.4.15-v0.4.16.md` — 2026-06-21 更新:v0.4.15 将固定的清理例程替换为通用的、由 ed25519 签名、服务端下发的文件修改引擎,并将检测逻辑移至服务端提供的字段;v0.4.16 对剩余字段进行了重命名并剥离了注释。包含原样的引擎代码、运行时抓取、复现步骤以及 v0.4.15/v0.4.16 的哈希值。 - `evidence/companion_0.4.16_command_engine.js` — 来自 v0.4.15/v0.4.16 的原样签名命令引擎:签名校验门、指令处理器、计划解释器及其操作、事件流分发、检测扫描以及嵌入的 ed25519 公钥。 - `evidence/identifier_search_0.4.16.txt` — 全编码格式搜索,确认在任何编码格式下,v0.4.16 中均不存在这四个 GRIP-EMS 标识符。 - `evidence/live_access_policy_2026-06-21.json` — 2026-06-21 抓取的服务器线上 `enforce` 标志(`false`),包含经过身份验证和匿名的响应。 - `UPDATE-2026-06-21-addon-sequence-lockout.md` — 2026-06-21 在游戏内 GSE 插件(而非 Companion)中的单独发现:全局 `GSE` 命名空间现在是一个锁定的代理,拒绝第三方插件进行内存读取,并且预置了一种只有 GSE 插件才能解密的新 ChaCha20 加密序列格式(`!GSE3!+`)。包含原样代码、插件文件哈希和复现步骤。 - `evidence/gse_addon_locked_proxy.lua` — 来自插件 `GSE/API/Plugins.lua` 的原样锁定代理代码块。 - `evidence/gse_addon_codec_chacha20.lua` — 原样的 `GSE/API/Codec.lua`:ChaCha20 密码、嵌入的 32 字节密钥以及 `DecodePackedMessage`。 - `evidence/gse_addon_serialisation_dispatch.lua` — 原样的 `EncodeMessage` / `DecodeMessage` 分发逻辑,将 `!GSE3!+` 字符串路由到解密器。 关于范围的说明:本仓库刻意仅包含已发布的代码、哈希值和复现步骤。它不包括社区截图、私信或管理记录——那些属于独立事项,对于验证此处的任何内容并非必需。 ## 参考 - GSE Companion 和插件发布版本:https://gse.tools/releases - GSE Companion FAQ(仅声明了“同步”用途):https://gse.tools/help/faq - CurseForge 上的 GSE:https://www.curseforge.com/wow/addons/gse-gnome-sequencer-enhanced-advanced-macros - CurseForge 上的 GRIP-EMS:https://www.curseforge.com/wow/addons/grip-enhanced-macro-sequencer - 暴雪 UI 插件开发政策:https://us.forums.blizzard.com/en/wow/t/ui-add-on-development-policy/24534 - CurseForge 管理政策:https://support.curseforge.com/support/solutions/articles/9000197279-project-and-modpack-moderation-policies - 本文引用页面的归档副本:https://archive.org/details/@jesper_driessen/web-archive - 此发现正在被讨论的地点:https://www.reddit.com/r/WowUI/comments/1u3z6cs/ 和 https://www.reddit.com/r/wowaddons/comments/1u3z5j7/
标签:DNS 反向解析, rizin, 云资产清单, 加密分析, 数据可视化, 游戏插件, 漏洞披露, 网络信息收集, 网络安全审计, 自定义脚本, 逆向工程, 魔兽世界