news 2026/8/11 2:54:58

某deepseek提问answer逆向分析,wasm + worker

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
某deepseek提问answer逆向分析,wasm + worker

仅供学习使用,如有侵权,联系删除!!!

仅供学习使用,如有侵权,联系删除!!!

url = 'aHR0cHM6Ly9jaGF0LmRlZXBzZWVrLmNvbS8='

来到这个网站随便问点东西,找到需要的接口信息观察发现请求头里面有一些参数需要分析请求载荷里面也有两个参数,chat_session_id和client_stream_id需要分析一下。

首先请求头里面的'x-hif-leim'是前面接口返回的,'x-hif-dliq'是localStorage里面的,经过测试发现可以不携带,请求载荷里面的chat_session_id也是前面接口返回的。

那么需要分析的只有'x-ds-pow-response'和'client_stream_id'

首先看看'x-ds-pow-response',直接进行base64解码可以看到,只有这个answer需要分析,其它的都是前面接口返回的。

搜索定位,打上断点这里返回的是一个异步,进入this.doSolveChallenge方法这里有点看不懂,问一下ai

let solveChallenge = async (challengeData, tracker) => { tracker.info({ name: "powSolveChallengeStart", message: "Start solving challenge", payload: {} }) // 第一套方案:normal(Worker A) try { const startTime = performance.now() const worker = (() => { if (!window.Worker) { throw new Error("Worker is not supported") } return new Worker( new URL(n.p + n.u("33614"), n.b), { type: "module" } ) })() const result = await o(challengeData, worker) tracker.info({ name: "powSolveChallengeSuccess", message: "Solved challenge", payload: { duration: performance.now() - startTime, from: "normal" } }) return result } catch (err) { tracker.error({ name: "powSolveChallengeFailed", message: "Failed to solve challenge", payload: tracker.withError(err, { from: "normal", info: JSON.stringify(challengeData) }) }) } // 第二套方案:fallback(Worker B / js) try { const startTime = performance.now() const worker = (() => { if (!window.Worker) { throw new Error("Worker is not supported") } return new Worker( new URL(n.p + n.u("38401"), n.b), { type: "module" } ) })() const result = await o(challengeData, worker) tracker.info({ name: "powSolveChallengeSuccess", message: "Solved challenge", payload: { duration: performance.now() - startTime, from: "js" } }) return result } catch (err) { tracker.error({ name: "powSolveChallengeFailed", message: "Failed to solve challenge", payload: tracker.withError(err, { from: "js", info: JSON.stringify(challengeData) }) }) throw err } }

那么我们只需要在第一个await o(e, s)打上断点,进入o方法又有点看不懂了,再问下ai

const solveWithWorker = async (challenge, worker) => { // 把 challenge 发给 worker worker.postMessage({ type: "pow-challenge", challenge }) const startTime = performance.now() // 等 worker 回消息 const workerResult = await new Promise((resolve, reject) => { worker.onmessage = event => { // worker 主动返回 error if (isWorkerError(event)) { reject( supportsErrorCause ? new Error("Worker error", { cause: event.data.error }) : event.data.error ) worker.terminate() return } // worker 返回成功结果 if (isWorkerSuccess(event)) { resolve(event.data) worker.terminate() return } } worker.onerror = err => { reject( new Error( `Worker error: ${err.message} ${err.filename}:${err.lineno}:${err.colno}` ) ) worker.terminate() } }) const endTime = performance.now() return { challengeResponse: workerResult.answer, duration: endTime - startTime } }

那么这里就清楚了,t是worker,通过t.postMessage发送数据,这里就单步进入t.postMessage,来到这里了这里就是这个answer生成的位置了

let o = n.__wbindgen_add_to_stack_pointer(-16) , h = u(e, n.__wbindgen_export_0, n.__wbindgen_export_1) , f = i , l = u(t, n.__wbindgen_export_0, n.__wbindgen_export_1) , p = i; n.wasm_solve(o, h, f, l, p, r); var s = c().getInt32(o + 0, !0) , a = c().getFloat64(o + 8, !0); return 0 === s ? void 0 : a

n.wasm_solve里面就是一个wasm文件,全部拿下来,用Js里面的WebAssembly做导出,调用就可以了。

加密的参数也是前面接口返回的,最后返回的a就是我们需要的answer。

接下来还有一个client_stream_id,这个就简单了,20260211代表当前日期,后面拼接了一个随机字符串

import uuid import datetime def generate_date_uuid(): """生成日期前缀的UUID""" date_prefix = datetime.datetime.now().strftime("%Y%m%d") random_part = uuid.uuid4().hex[:16] # 直接获取十六进制表示 return f"{date_prefix}-{random_part}" print(generate_date_uuid())

最后看一下实现吧

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/8 20:49:42

如果AI在写代码的时候,不小心删库了谁应该承担法律责任?

聊天截图 图1 图2 . 图3 图4 AI删库的法律责任,本质是“工具使用者的责任”。无论是个人还是组织,若想利用AI降本,必须同步建立“风险防控体系”(如权限管理、审计日志、责任划分协议),否则“低成本”可…

作者头像 李华
网站建设 2026/7/29 10:11:13

Java毕设项目:基于springboot的乡村书屋数字化资源平台的设计与实现(源码+文档,讲解、调试运行,定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/8/9 8:02:59

音频比特率设置多少最好?320kbps 真的比 128kbps 好很多吗

无论是听音乐、看视频、播客,还是进行语音通话、内容创作,我们几乎每天都在和音频打交道。而提到音频质量,比特率往往是绕不开的核心参数。那么,MP3 或其他常见音频格式的比特率到底设置为多少最合适?128kbps 够用吗&a…

作者头像 李华
网站建设 2026/8/6 20:42:56

【毕业设计】基于springboot的乡村书屋数字化资源平台的设计与实现(源码+文档+远程调试,全bao定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/8/10 3:53:15

Java毕设项目:基于springboot的面向新工科课程线上教学辅助平台(源码+文档,讲解、调试运行,定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华