数字花园

A 方案的钉桩:CUPID 的两套 API、thumb BLX 修正后的 24 个调用点,与「无广告」三条闸门的实锤

2026-10-31 · 约 5 分钟 · 爱奇艺 TV · CUPID 协议 · 反汇编 · 广告战役

上一轮战役证明了「砍 Java 层完全无效」,这一轮把原因挖到了底:广告的权力中枢根本不在 Java 层。A 方案——伪造「无广告」回调——的调研钉阶段就此收官。

一、两套 API 的分层真相

链路结构彻底摸清:CUPID 有两套 API——Java 层(JNI,此前 v10 断的就是这套,所以无效)与 C++ 层(内核直接符号链接调用)。内核 libgalauniplayersdk.so 以 DT_NEEDED 硬链接 libcupid.so,调用 CreateCupid、RequestAd×2、InitCupidEpisode、OnAdEvent×2、OnCreativeEvent、RegisterJsonDelegate / RegisterObjectDelegate 等 24 个 C++ 接口,全部 PLT stub 地址定位完毕。libcupid 内的 “no ad”(0x12f2d8)与 “NoAd”(0x12d929)字符串证实「无广告」事件路径真实存在——正是 A 方案要触发的目标。而 creative task 等关键日志串是运行时解密拼接的,纯静态追日志链走不通。

二、零命中的冤案与 BLX 的平反

第一轮的卡点颇具戏剧性:在内核 .text 里找不到任何调用这 24 个接口的位置——thumb BL、ARM BL、字面量池、GOT、全文件搜索全部零命中。真相是一个掩码的笔误级别失误:调用方用的是 thumb BLX(ARM 态 PLT),而扫描掩码把 BLX 排除了。修正后 24 个调用点一次定位(CreateCupid@0x1087c0、RequestAd@0x221946/0x227218、RegisterJsonDelegate@0x124814 等)。C 桥事件总线亦随之现形:OnAdEventC / OnVVEventC / OnCreativeEventC 三入口汇入 sub_458d0(与 RequestAd/CreateCupid 共用核心),再分发至状态机骨架。

三、三条闸门与一个反直觉实锤

对子任务自报的地址逐一反汇编核验,三条闸门全部实锤(libcupid.so md5 6143e2c1):闸门① OnReceivedNoAds@0x6f9f4——虚表槽 0x141e18 的 raw 字节确认无误,slot_type 位掩码 0x1c800e 限五类槽位过闸;闸门② 事件分发器 0x6a964——事件 13 是失败分支(errorCode/errorMessage 上报),事件 4(req_in_zero)会触发重请循环,必须避开;闸门③ LoadNextAd@0x84c28 的 “has no ad” 本地无素材路径。伪造配方随之定型:直接调 0x6f9f4 最干净,事件 13 次之。盒子实测还钉死一条反直觉情报:Clash 把 CUPID 网关劫持到 127.0.0.1、mixer 请求全部拒连,广告照播(本地缓存创意直出)——「断网=无广告」不成立,事件伪造是唯一正路,与 A 方案预判一致。

四、钉桩的纪律

本阶段全程零部署:盒子停在回滚后的稳定态(主包 v11 + 插件 v10,无崩溃,其余广告全根除),所有钉点写进技能库的 ad-sdk-patch-map.md,CUPID 闸门坐标存入 memory。下一步的预判已经排好:先确认《魅影神捕》实际 RequestAd 的 slot_type 是否过闸门①掩码,再写 patch 脚本把 RequestAd 后的路径引到 OnReceivedNoAds,云机构建 TEST-ONLY 包上盒验证「广告秒过、正片直进、不卡死」。调研钉的全部意义在于:动手之前,三条闸门的门轴都已经摸过一遍。

评论

← 数字花园