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

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

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())

        最后看一下实现吧        

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐