• bfloat16

    play.google.com

    Arcaea – 创新立体节奏游戏 - Google Play 上的应用

    图片

    创新立体节奏游戏:全新沉浸式音效与剧情体...

    Free

    注意版本为 6.16.1 !!!不同版本的常量不一样 !!!

    目标为逆向网络请求里面的X-Random-Challenge

    雷霆算法,全部inline,GPT-5.6 sol Xhigh也不能轻易搞定这玩意

    图片

    这里贴个标准答案(经过简化过的算法)```
    import base64
    import struct

    C = bytes.fromhex("0891e9d19265d512dc554094a4079ba6837d368c18f4b631c0d2347ee3059e66")

    MASK = 0xFFFFFFFF

    IV = [
    0x243F6A88,
    0x85A308D3,
    0x13198A2E,
    0x03707344,
    0xA4093822,
    0x299F31D0,
    0x082EFA98,
    0xEC4E6C89,
    ]

    K = [
    0x452821E6,
    0x38D01377,
    0xBE5466CF,
    0x34E90C6C,
    0xC0AC29B7,
    0xC97C50DD,
    0x3F84D5B5,
    0xB5470917,
    0x9216D5D9,
    0x8979FB1B,
    0xD1310BA6,
    0x98DFB5AC,
    0x2FFD72DB,
    0xD01ADFB7,
    0xB8E1AFED,
    0x6A267E96,
    0xBA7C9045,
    0xF12C7F99,
    0x24A19947,
    0xB3916CF7,
    0x0801F2E2,
    0x858EFC16,
    0x636920D8,
    0x71574E69,
    0xA458FEA3,
    0xF4933D7E,
    0x0D95748F,
    0x728EB658,
    0x718BCD58,
    0x82154AEE,
    0x7B54A41D,
    0xC25A59B5,
    0x9C30D539,
    0x2AF26013,
    0xC5D1B023,
    0x286085F0,
    0xCA417918,
    0xB8DB38EF,
    0x8E79DCB0,
    0x603A180E,
    0x6C9E0E8B,
    0xB01E8A3E,
    0xD71577C1,
    0xBD314B27,
    0x78AF2FDA,
    0x55605C60,
    0xE65525F3,
    0xAA55AB94,
    0x57489862,
    0x63E81440,
    0x55CA396A,
    0x2AAB10B6,
    0xB4CC5C34,
    0x1141E8CE,
    0xA15486AF,
    0x7C72E993,
    0xB3EE1411,
    0x636FBC2A,
    0x2BA9C55D,
    0x741831F6,
    0xCE5C3E16,
    0x9B87931E,
    0xAFD6BA33,
    0x6C24CF5C,
    0x7A325381,
    0x28958677,
    0x3B8F4898,
    0x6B4BB9AF,
    0xC4BFE81B,
    0x66282193,
    0x61D809CC,
    0xFB21A991,
    0x487CAC60,
    0x5DEC8032,
    0xEF845D5D,
    0xE98575B1,
    0xDC262302,
    0xEB651B88,
    0x23893E81,
    0xD396ACC5,
    0x0F6D6FF3,
    0x83F44239,
    0x2E0B4482,
    0xA4842004,
    0x69C8F04A,
    0x9E1F9B5E,
    0x21C66842,
    0xF6E96C9A,
    0x670C9C61,
    0xABD388F0,
    0x6A51A0D2,
    0xD8542F68,
    0x960FA728,
    0xAB5133A3,
    0x6EEF0B6C,
    0x137A3BE4,
    ]

    WP2 = [
    5,
    14,
    26,
    18,
    11,
    28,
    7,
    16,
    0,
    23,
    20,
    22,
    1,
    10,
    4,
    8,
    30,
    3,
    21,
    9,
    17,
    24,
    29,
    6,
    19,
    12,
    15,
    13,
    2,
    25,
    31,
    27,
    ]
    WP3 = [
    19,
    9,
    4,
    20,
    28,
    17,
    8,
    22,
    29,
    14,
    25,
    12,
    24,
    30,
    16,
    26,
    31,
    15,
    7,
    3,
    1,
    0,
    18,
    27,
    13,
    6,
    21,
    10,
    23,
    11,
    5,
    2,
    ]

    TAIL = bytes([0x29, 0x30])

    def ror(v, n):
    return ((v >> n) | (v << (32 - n))) & MASK

    def f1(w):
    return (w[1] ^ ((w[1] ^ w[6]) & w[5]) ^ (w[2] & w[3]) ^ (w[4] & w[7])) & MASK

    def f2(w):
    return (
    (w[6] & (w[5] ^ w[3]))
    ^ w[2]
    ^ (w[7] & w[5])
    ^ ((w[2] ^ w[1] ^ (w[6] & w[5]) ^ (w[3] & ~w[7])) & w[4])
    ) & MASK

    def f3(w):
    return (
    (w[1] & w[4]) ^ w[2] ^ ((w[5] ^ w[2] ^ (w[6] & w[4])) & w[3]) ^ (w[7] & w[6])
    ) & MASK

    def _pad(msg: bytes) -> bytes:

    bit_len = len(msg) * 8

    out = bytearray(msg)
    out.append(0x01)

    while len(out) % 128 != 118:
    out.append(0)

    out += TAIL
    out += struct.pack("<Q", bit_len)

    return bytes(out)

    def haval192(msg: bytes) -> bytes:

    h = IV[:]
    data = _pad(msg)

    for blk_off in range(0, len(data), 128):
    m = list(struct.unpack("<32I", data[blk_off : blk_off + 128]))

    win = h[::-1]

    ts = []

    for i in range(96):
    if i < 32:
    mk, f = m[i], f1(win)

    elif i < 64:
    mk, f = (m[WP2[i - 32]] + K[i - 32]) & MASK, f2(win)

    else:
    mk, f = (m[WP3[i - 64]] + K[32 + i - 64]) & MASK, f3(win)

    t = (mk + ror(win[0], 11) + ror(f, 7)) & MASK

    ts.append(t)

    win = win[1:] + [t]

    for j in range(8):
    h[7 - j] = (h[7 - j] + ts[88 + j]) & MASK

    h0, h1, h2, h3, h4, h5, h6, h7 = h

    out = [
    (h0 + ((h6 >> 26) | ((h7 & 0x1F) << 6))) & MASK,
    (h1 + ((h6 & 0x1F) | (h7 & 0x3E0))) & MASK,
    (h2 + (((h6 & 0x3E0) | (h7 & 0xFC00)) >> 5)) & MASK,
    (h3 + (((h6 & 0xFC00) | (h7 & 0x1F0000)) >> 10)) & MASK,
    (h4 + (((h6 & 0x1F0000) | (h7 & 0x3E00000)) >> 16)) & MASK,
    (h5 + (((h6 & 0x3E00000) | (h7 & 0xFC000000)) >> 21)) & MASK,
    ]

    return struct.pack("<6I", *out)

    def make_challenge(ts_ms: int, endpoint: str, body: bytes = b"") -> str:
    ts = struct.pack("<Q", ts_ms)
    path = endpoint.encode()
    h1 = haval192(ts + body + C)
    h2 = haval192(ts + body + path + C)
    return base64.b64encode(ts + h1 + h2).decode()

    if __name__ == "__main__":
    print(make_challenge(1786347560315, r"/steeptennis/40/compose/aggregate", b'[{"endpoint":"/user/me","id":0}]'))
    ``目前测试是只有GPT-5.6 sol Xhigh 和 Kimi K3 Max 做出来了,不过做的也不是很顺,都是先定位被加密的X-Random-Challenge`,然后开unicorn跑模拟,然后抄算法,最后一步一步简化(有些模型unicorn都开不明白,难崩)

    被斩杀的有opus-5/4.8,dsv4fga/dsv4pga,ox-alpha

    以下模型未测试:fable-5,GLM-5.3,glm-5.3-flash GA

    主楼
  • 恒烈_Henglie

    搞半天原来是控制流,我还以为是频谱图呢

    #1
  • Miluko

    点进来前还在想是不是我想的那个 Arcaea…

    没想到真的是 ^-^

    怎么这里也有音游人 ^-^

    #2
  • FireGuo

    这个怎么逆向出来的啊。。。gpt说这个so里面找都找不到这个字段

    #3
  • bfloat16

    因为被加密了,同样被加密的还有一些请求参数里面的字段

    #4
  • FireGuo

    原来如此,我想请教一下是怎么让GPT拿出来的,我这边想做查分 ^-^

    #5

发表回复

登录后回复