背景

懂车帝(com.ss.android.auto)是字节跳动旗下汽车资讯 App,使用与抖音、今日头条相同的 TTNet 网络库和 Gorgon 鉴权体系。本文分析其签名生成机制。

抓包初探

使用 mitmproxy 抓包,发现所有 API 请求都带有额外请求头:

X-Gorgon: 0404b00100xxxxxxxxxxxxxxxxxxxx
X-Khronos: 1700000000
X-SS-REQ-TICKET: 1700000000000

其中 X-Gorgon 是关键签名字段,X-Khronos 是 Unix 时间戳。

定位签名生成

1. 找 Native 库

jadx-gui com.ss.android.auto.apk
# 搜索 "X-Gorgon" 或 "gorgon"

定位到 com.bytedance.frameworks.core.encrypt.TTEncryptUtils

public static native String getGorgon(String uri, String params, String cookie, long timestamp);

Native 实现在 libcms.so 中。

2. IDA 分析 libcms.so

搜索字符串 X-Gorgon,定位到核心函数。Gorgon 签名算法大致流程:

Input = URL_path + body_md5 + cookie_md5 + timestamp
Hash  = custom_hash(Input)   // 基于 CRC32 变种
Result = "0404b001" + hex(Hash)

3. Frida Hook 提取参数

// hook_gorgon.js
Java.perform(function () {
    var TTEnc = Java.use("com.bytedance.frameworks.core.encrypt.TTEncryptUtils");
    TTEnc.getGorgon.implementation = function (uri, params, cookie, ts) {
        var result = this.getGorgon(uri, params, cookie, ts);
        console.log("[Gorgon] uri=" + uri);
        console.log("[Gorgon] params_md5=" + params);
        console.log("[Gorgon] result=" + result);
        return result;
    };
});
frida -U -f com.ss.android.auto -l hook_gorgon.js

device_id / install_id 体系

字节系 App 的设备注册流程:

POST https://log.snssdk.com/service/2/device_register/
{
  "openudid": "<random_16bytes_hex>",
  "device_type": "Redmi K60",
  "os_version": "13",
  "aid": 1839,          // 懂车帝的 app_id
  ...
}
Response: {
  "device_id": "72xxxxxxxxxxxx",
  "install_id": "73xxxxxxxxxxxx",
  "device_id_str": "72xxxxxxxxxxxx"
}

参数 aid=1839 是懂车帝的 AppID,不同字节系 App 的 aid 不同:

App aid
抖音 1128
今日头条 13
懂车帝 1839
西瓜视频 1340

iOS 设备 CK 获取

对于部分需要 iOS 端 CK 的场景,可以:

  1. 越狱设备 + Shadowrocket 抓包
  2. 使用 ios_cookie_extractor.py 模拟 iOS 注册:
import uuid, hashlib, requests

def get_ios_cookie(aid: int) -> str:
    idfa = str(uuid.uuid4()).upper()
    payload = {
        "aid": aid,
        "platform": "iphone",
        "os_version": "17.0",
        "idfa": idfa,
        "idfv": str(uuid.uuid4()).upper(),
    }
    r = requests.post(
        "https://log.snssdk.com/service/2/device_register/",
        json=payload,
        headers={"User-Agent": "com.ss.iphone.auto/4.0.0"}
    )
    return r.json()

还原 X-Gorgon 生成(Python)

import hashlib, struct, time

def md5_hex(data: bytes) -> str:
    return hashlib.md5(data).hexdigest()

def gorgon_hash(data: bytes) -> int:
    # 简化版,实际涉及更多字节运算
    val = 0xFFFFFFFF
    for byte in data:
        val ^= byte
        for _ in range(8):
            if val & 1:
                val = (val >> 1) ^ 0xEDB88320
            else:
                val >>= 1
    return val ^ 0xFFFFFFFF

def get_gorgon(url_path: str, body: bytes, cookie: str, ts: int) -> str:
    body_md5 = md5_hex(body) if body else ""
    cookie_md5 = md5_hex(cookie.encode()) if cookie else ""
    raw = url_path + body_md5 + cookie_md5 + str(ts)
    h = gorgon_hash(raw.encode())
    return "0404b001" + format(h, '08x')

# 使用
ts = int(time.time())
gorgon = get_gorgon("/aweme/v1/feed/", b"", "", ts)

总结

字节系 Gorgon 签名本质是自定义哈希算法,核心逻辑在 libcms.so,通过 IDA 反编译 + Frida 动态验证可以完整还原。实际生产中建议对接 RPC 方案避免重复逆向维护成本。

免责声明:本文仅供安全学习研究使用,请勿用于违法目的。