ai补环境下
上次发的那个教程,有很多小伙伴说希望看到一个更加详细的一点的教程,上次出的那个文章,确实是ai辅助写了一下,没有写具体分析内容。主要是当时我的想法是提供一个我的看法,可以使用ai来补环境,而且不是一般的js环境,而是wasm+vmp环境。(主要当时也不知道分享啥,过程全是ai弄得,我只是一味的点击yes,哈哈哈哈哈)。这次我把过程写的详细一点
尝试一 wasm转成c,准备补环境,打成dll包
我看了前面的几篇参考文章,都是wasm转c,然后补环境进行解密的。这里我也准备使用这种方式,使用wasm2c,将浏览器的wasm转成c,然后找ua函数的实现。
u32 w2c_cctv_ua_0(w2c_cctv* instance, u32 var_p0, u32 var_p1, u32 var_p2, u32 var_p3) {
FUNC_PROLOGUE;
u32 var_i0, var_i1;
var_i0 = instance->w2c_g9;
var_i1 = 2u;
var_i0 = var_i0 != var_i1;
if (var_i0) {
var_i0 = instance->w2c_g6;
var_i1 = var_p0;
i32_store_default32(instance->w2c_env_memory, (u64)(var_i0) + 8, var_i1);
var_i0 = instance->w2c_g6;
var_i1 = var_p1;
i32_store_default32(instance->w2c_env_memory, (u64)(var_i0) + 16, var_i1);
var_i0 = instance->w2c_g6;
var_i1 = var_p2;
i32_store_default32(instance->w2c_env_memory, (u64)(var_i0) + 24, var_i1);
var_i0 = instance->w2c_g6;
var_i1 = var_p3;
i32_store_default32(instance->w2c_env_memory, (u64)(var_i0) + 32, var_i1);
var_i0 = instance->w2c_g9;
var_i1 = 1u;
var_i0 = var_i0 == var_i1;
if (var_i0) {
var_i0 = 3u;
instance->w2c_g9 = var_i0;
}
}
var_i0 = (*instance->w2c_env_d);
var_i1 = 506868u;
var_i0 += var_i1;
w2c_cctv_f50(instance, var_i0);
var_i0 = instance->w2c_g6;
var_i0 = i32_load_default32(instance->w2c_env_memory, (u64)(var_i0));
FUNC_EPILOGUE;
return var_i0;
}
然后可以明显的看到走到f50函数里面去了,之前的操作都是js传的参数取出来,然后就走到f50函数里面了。这里我就不继续分析了,渔哥大佬已经找到是vmp了,其实大概浏览一下,也能发现,里面大部分函数都走到f50函数里面去了,f50函数可以就是一个分发器的作用。这里我也不深究了。
出来吧!codex !让gpt5.4直接给我补环境,这个里面很多导入函数,我自己一个一个找,再去补太麻烦了,直接把调用wasm 的js丢给gpt5.4,让他去补,我只需要点击yes,yes就行。对了,这个里面有个超长的字节码,就是vmp的指令集,那一块要单独处理一下,gpt5.4可能会报错。补完环境以后,尝试运行,能正常运行,ua函数也能正常运行,但是是没有补浏览器环境,导致解密结果不对。我尝试让ai补了一下,但是因为是vmp,也不知道是那个函数传环境进去的。ai也没看出来。解密出来的视频还是花屏。遂放弃。
尝试二 使用wasm2js,将wasm转js,再次尝试补环境
放弃wasm转c补环境后,就想着把wasm转成js,在js补环境,js调试起来比c语言方便很多,转成js大概是下面这样。使用wasm2js将wasm转成js后,让ai帮我把环境补好。
function $49($0_1, $1_1, $2_1, $3_1) {
$0_1 = $0_1 | 0;
$1_1 = $1_1 | 0;
$2_1 = $2_1 | 0;
$3_1 = $3_1 | 0;
if ((global$4 | 0) != (2 | 0)) {
HEAP32[(global$1 + 8 | 0) >> 2] = $0_1;
HEAP32[(global$1 + 16 | 0) >> 2] = $1_1;
HEAP32[(global$1 + 24 | 0) >> 2] = $2_1;
HEAP32[(global$1 + 32 | 0) >> 2] = $3_1;
if ((global$4 | 0) == (1 | 0)) {
global$4 = 3
}
}
$0(gimport$4 + 513548 | 0 | 0);
return HEAP32[global$1 >> 2] | 0 | 0;
}
function $50($0_1, $1_1, $2_1, $3_1) {
$0_1 = $0_1 | 0;
$1_1 = $1_1 | 0;
$2_1 = $2_1 | 0;
$3_1 = $3_1 | 0;
if ((global$4 | 0) != (2 | 0)) {
HEAP32[(global$1 + 8 | 0) >> 2] = $0_1;
HEAP32[(global$1 + 16 | 0) >> 2] = $1_1;
HEAP32[(global$1 + 24 | 0) >> 2] = $2_1;
HEAP32[(global$1 + 32 | 0) >> 2] = $3_1;
if ((global$4 | 0) == (1 | 0)) {
global$4 = 3
}
}
$0(gimport$4 + 553328 | 0 | 0);
}
function $51($0_1, $1_1, $2_1) {
$0_1 = $0_1 | 0;
$1_1 = $1_1 | 0;
$2_1 = $2_1 | 0;
if ((global$4 | 0) != (2 | 0)) {
HEAP32[(global$1 + 8 | 0) >> 2] = $0_1;
HEAP32[(global$1 + 16 | 0) >> 2] = $1_1;
HEAP32[(global$1 + 24 | 0) >> 2] = $2_1;
if ((global$4 | 0) == (1 | 0)) {
global$4 = 3
}
}
$0(gimport$4 + 688348 | 0 | 0);
return HEAP32[global$1 >> 2] | 0 | 0;
}
这个里面也是ai补了半天,解密还是花屏,遂又放弃
尝试三 直接使用源js,不进行转换
wasm是直接写在js里面的,直接补这个js就行,也不进行转换了,这样就不用手动去处理那个很长的字节码了,省去了很多麻烦。之后就是和ai进行沟通,让他用这个chrome devtool mcp去把网页的播放逻辑给扣下来,做成node解密。这个里面也还是要提供很大上下文的,比如告诉她解密函数是ua,里面有对nal的处理,不然扣下来的就是不同的m3u8文件解析,没有解密流程。
然后就是一直聊天了,先让ai打开这个网页梳理一下视频播放逻辑,调用了哪些文件。梳理完成后,我看一下他梳理的流程,看看里面有没有找到解密逻辑,有没有提到wasm和nal处理,没有的话,告诉ai有解密和处理nal,让他继续找。找到我看了一下,大概没啥问题,就开始让他复刻了。明确说明要node本地运行,不要html。
用ai本地补完环境后,让他跑了一下试试解密看看,用ffmpeg去验证合成mp4文件解密是否正确。第一次解密还是花屏,我就让他补一下环境,把window啥的补上用jsdom,环境要和浏览器同步,补上之后,ai检测到结果有变化,我自己手动断点调试了一下,大概检测了location还有请求了一个json文件用的xhr,用xhr估计也是检测的作用。让ai把这两个补上。完全按照浏览器的来。再让ai补一下,结果,ai突然输出,解码错误少了很多。我赶快去把看看合成的mp4文件,发现能够播放,但是还是有部分帧会乱码。ai说还是有部分nal解密失败,返回的是0.估计还是有环境没有对齐。两分钟的视频里面有两个nal没有解密出来,但是整体视频还是能看的,但是长视频就不行了,比如45分钟的视频就会有很多花屏。这里我就不深究了。主要目的也不是要弄下来。只是想试试不写一行代码,全靠和ai聊天,能不能实现补环境。我的目的达到了,就不继续深究了(主要是没token了,哈哈哈哈)。本次花费大概是一顿隆江猪脚饭(不到20块,咸鱼买的中转站,我怀疑不是纯血gpt5.4,有点不如我买的plus)
最后,其实我也用ai分析了一下解密算法
我用ai分析了一下wasm转c和wasm转js的文件,分析了一下算法(不能保证准确哈),只是分享一下,里面有个LCG随机数生成算法,应该是生成mediaid,以时间戳作为种子。还有一个tea算法算法,密钥应该是nal的[15:31]的位置作为16位密钥来进行就解密(ai分析了,不一定准确)。里面还有一个vmptag进行流程推进,每调用一次,vmptag里面0到6的会触发函数,之后会变成7。再之后就没啥了
更新skill
这里放一下更新后的skill,这个skill我写的详细了一点,这个skill本来把ffmpeg和ffprobe也放到里面了,但是文件太大,超过100M了,无法上传蓝奏云了,所以删掉了,后面记得自己放一下,在skill文件夹里面的assets\bin目录下面。
使用之前记得一定要先下载并配置好chrome devtool mcp,我自己试过了,一般喂给codex+5.4 high都能复现我的那个下载部分nal解密失败的代码。
蓝奏云:https://wwaxz.lanzoul.com/iCUz33nncm8h
后记
这里推荐一个项目CharlesPikachu/videodl: Videodl: A lightweight video downloader written in pure python. (轻量级视频下载器,优先高清无水印,支持抖音,快手,小红书,B站,TikTok,YouTube,FIFA+,优酷,腾讯,爱奇艺,1905电影网,乐视,芒果,咪咕,PPTV,搜狐,Facebook,Twitter,新浪微博,今日头条,网易公开课,全民K歌,CCTV央视频,酷狗音乐MV,新片场,知乎,百度贴吧,TED等海量流媒体平台),里面有cctv下载,里面也是通过补环境来实现视频解密了。可以拿里面代码参考一下(已经star),可以让ai参考一下那个代码,把流程补齐