SnowLuma v2.4.2 source snapshot
Dev Build / cleanup (push) Waiting to run
Dev Build / typecheck (push) Waiting to run
Publish MCP to npm / Build, test, and publish MCP (push) Waiting to run
Publish SDK to npm / Build, test, and publish SDK (push) Waiting to run
Sync action catalog to docs / sync (push) Waiting to run
Publish UI to npm / Build and publish UI (push) Waiting to run
Build and Release / preflight (push) Waiting to run

This commit is contained in:
TanTan committed 2026-11-13 09:02:00 +08:00
commit fa9c73363d
1367 files changed
+355735

No files matched your search

@@ -0,0 +1,91 @@
import { describe, expect, it } from 'vitest';
import { protobuf_encode, protobuf_decode } from '@snowluma/proton';
import type { FlashApplyUploadReq } from '@snowluma/proto-defs/oidb-actions/flash-transfer';
// ENC#8: 0x12a9 sub=103 apply-upload 真实客户端请求 body(frida 抓包,QQ 9.9.26-44343,
// 2026-06-19)。用 ENC#8 的精确值手工构造 req,encode 后必须 byte-for-byte 匹配 ENC#8 hex。
// 这是真正的 byte-oracle:字段号/wire type/0值显式编码任一错误都会 hex 不等。
const ENC8_HEX =
'0a190a0508ac011067120ca80602b00604b80616c00c051a020801629d030a81020a870108b4cdcc01122063396631303334663062303431653933353339653937663839356363333139621a28306636326234663763646463373965326662666431343065646531326431633434646462373937612222e5b18fe5b995e5bd95e588b620323032352d30312d3135203030323133302e6d70342a0808001000180020003000380040004801126745685150597254337a64783534767639464137654574484554647435656869307a637742494c56304b4b4b516938796a6b3555444d675277636d396b5549447153566f51496f38546b56454c72776f454c5746544c6a433268586f445947505f676745435a336f180120fae4d4d1062880ea493000120208021a0808001000180022005288010a2438363866633433312d336361372d346130632d383538322d666135656365613062666134122438363866633433312d336361372d346130632d383538322d6661356563656130626661341a2436656639316166322d363830302d373633632d313936642d38353231303537353536343020012800300138024200480150005800600068007000';
// ENC#8 抓包值(sub=103 mp4)。
const ENC8_REQ: FlashApplyUploadReq = {
head: {
sub: { seq: 172, sub: 103 },
config: { field101: 2, field102: 4, field103: 22, field200: 5 },
field3: { field1: 1 },
},
payload: {
wrapper: {
fileInfo: {
fileSize: 3352244,
md5: 'c9f1034f0b041e93539e97f895cc319b',
sha1: '0f62b4f7cddc79e2fbfd140ede12d1c44ddb797a',
fileName: '屏幕录制 2025-01-15 002130.mp4',
field5: { field1: 0, field2: 0, field3: 0, field4: 0 },
field6: 0,
field7: 0,
field8: 0,
field9: 1,
},
fileId: 'EhQPYrT3zdx54vv9FA7eEtHETdt5ehi0zcwBILV0KKKQi8yjk5UDMgRwcm9kUIDqSVoQIo8TkVELrwoELWFTLjC2hXoDYGP_ggECZ3o',
field3: 1,
field4: 1781871226,
field5: 1209600,
field6: 0,
},
flag2: { field1: 2 },
field3: { field1: 0, field2: 0, field3: 0, field4: {} },
filesetWrap: {
filesetUuid: '868fc431-3ca7-4a0c-8582-fa5ecea0bfa4',
uploadKey: '868fc431-3ca7-4a0c-8582-fa5ecea0bfa4',
fileUuid: '6ef91af2-6800-763c-196d-852105755640',
field4: 1,
field5: 0,
field6: 1,
field7: 2,
field8: {},
field9: 1,
field10: 0,
field11: 0,
field12: 0,
field13: 0,
field14: 0,
},
},
};
describe('ApplyUpload byte-oracle (0x12a9_103 encode == ENC#8)', () => {
it('encodes the ENC#8 field values to the exact frida-captured wire bytes', () => {
const out = Buffer.from(protobuf_encode<FlashApplyUploadReq>(ENC8_REQ)).toString('hex');
if (out !== ENC8_HEX) {
// 定位首个差异字节
const n = Math.min(out.length, ENC8_HEX.length);
let i = 0;
while (i < n && out[i] === ENC8_HEX[i]) {
i++;
}
throw new Error(
`hex mismatch at char ${i} (byte ${i >> 1}):\n` +
` bot: ...${out.slice(Math.max(0, i - 20), i + 20)}\n` +
` ENC#8: ...${ENC8_HEX.slice(Math.max(0, i - 20), i + 20)}\n` +
` bot len=${out.length / 2}B, ENC#8 len=${ENC8_HEX.length / 2}B`,
);
}
expect(out).toBe(ENC8_HEX);
});
it('round-trips: encode → decode preserves the field tree', () => {
const bytes = protobuf_encode<FlashApplyUploadReq>(ENC8_REQ);
const back = protobuf_decode<FlashApplyUploadReq>(bytes);
expect(back.head?.sub?.sub).toBe(103);
expect(back.head?.config?.field103).toBe(22);
expect(back.payload?.wrapper?.fileInfo?.field9).toBe(1);
expect(back.payload?.wrapper?.fileInfo?.field5?.field4).toBe(0);
expect(back.payload?.filesetWrap?.fileUuid).toBe('6ef91af2-6800-763c-196d-852105755640');
});
});
@@ -0,0 +1,67 @@
import { describe, expect, it } from 'vitest';
import { protobuf_decode } from '@snowluma/proton';
import type { FlashApplyUploadReq } from '@snowluma/proto-defs/oidb-actions/flash-transfer';
import { ApplyUpload } from '../../../src/oidb-services/flash-transfer/apply-upload';
// ENC#8: 0x12a9 sub=103 apply-upload 真实客户端请求 body(frida 抓包,QQ 9.9.26-44343,
// 2026-06-19)。字段树逐字节解码见 flash_transfer_protocol_full.md §9.5。
// 独立 byte-oracle:从 frida 抓的 hex decode 回来,字段号/wire type 错则值读不出。
const ENC8_HEX =
'0a190a0508ac011067120ca80602b00604b80616c00c051a020801629d030a81020a870108b4cdcc01122063396631303334663062303431653933353339653937663839356363333139621a28306636326234663763646463373965326662666431343065646531326431633434646462373937612222e5b18fe5b995e5bd95e588b620323032352d30312d3135203030323133302e6d70342a0808001000180020003000380040004801126745685150597254337a64783534767639464137654574484554647435656869307a637742494c56304b4b4b516938796a6b3555444d675277636d396b5549447153566f51496f38546b56454c72776f454c5746544c6a433268586f445947505f676745435a336f180120fae4d4d1062880ea493000120208021a0808001000180022005288010a2438363866633433312d336361372d346130632d383538322d666135656365613062666134122438363866633433312d336361372d346130632d383538322d6661356563656130626661341a2436656639316166322d363830302d373633632d313936642d38353231303537353536343020012800300138024200480150005800600068007000';
describe('ApplyUpload namespace (0x12a9_103)', () => {
it('declares command 0x12a9 sub 103 uinForm=true', () => {
expect(ApplyUpload.command).toBe(0x12a9);
expect(ApplyUpload.subCommand).toBe(103);
expect(ApplyUpload.uinForm).toBe(true);
});
it('decodes ENC#8 frida capture with the exact field tree', () => {
const req = protobuf_decode<FlashApplyUploadReq>(Buffer.from(ENC8_HEX, 'hex'));
// head: { f1:{seq,sub}, f2:config{f101,f102,f103,f200}, f3:{f1:1} }
expect(req.head?.sub?.seq).toBe(172);
expect(req.head?.sub?.sub).toBe(103);
expect(req.head?.config).toMatchObject({
field101: 2,
field102: 4,
field103: 22,
field200: 5,
});
expect(req.head?.field3?.field1).toBe(1);
// payload.wrapper.fileInfo(f12.f1.f1)
const fi = req.payload?.wrapper?.fileInfo;
expect(fi?.fileSize).toBe(3352244);
expect(fi?.md5).toBe('c9f1034f0b041e93539e97f895cc319b');
expect(fi?.sha1).toBe('0f62b4f7cddc79e2fbfd140ede12d1c44ddb797a');
expect(fi?.fileName).toBe('屏幕录制 2025-01-15 002130.mp4');
// field5 = {f1:0,f2:0,f3:0,f4:0},f4 是 varint(不是 message)
expect(fi?.field5).toMatchObject({ field1: 0, field2: 0, field3: 0, field4: 0 });
expect(fi?.field9).toBe(1);
// payload.wrapper(f12.f1):fileId + 时间戳 + TTL
expect(req.payload?.wrapper?.fileId).toBe(
'EhQPYrT3zdx54vv9FA7eEtHETdt5ehi0zcwBILV0KKKQi8yjk5UDMgRwcm9kUIDqSVoQIo8TkVELrwoELWFTLjC2hXoDYGP_ggECZ3o',
);
expect(req.payload?.wrapper?.field3).toBe(1);
expect(req.payload?.wrapper?.field4).toBe(1781871226);
expect(req.payload?.wrapper?.field5).toBe(1209600);
// payload.flag2(f12.f2 = {f1:2})
expect(req.payload?.flag2?.field1).toBe(2);
// payload.field3(f12.f3 = {f1:0,f2:0,f3:0,f4:空message})
expect(req.payload?.field3).toMatchObject({ field1: 0, field2: 0, field3: 0 });
// payload.filesetWrap(f12.f10 = filesetUuid + fileUuid + flags)
const fw = req.payload?.filesetWrap;
expect(fw?.filesetUuid).toBe('868fc431-3ca7-4a0c-8582-fa5ecea0bfa4');
expect(fw?.uploadKey).toBe('868fc431-3ca7-4a0c-8582-fa5ecea0bfa4');
expect(fw?.fileUuid).toBe('6ef91af2-6800-763c-196d-852105755640');
expect(fw?.field4).toBe(1);
expect(fw?.field6).toBe(1);
expect(fw?.field7).toBe(2);
expect(fw?.field9).toBe(1);
});
});
@@ -0,0 +1,31 @@
import { describe, expect, it } from 'vitest';
import { protobuf_decode } from '@snowluma/proton';
import type { OidbBase } from '@snowluma/proto-defs/oidb';
import type { FlashGetDownloadUrlResp } from '@snowluma/proto-defs/oidb-actions/flash-transfer';
import { GetDownloadUrl } from '@snowluma/protocol/oidb-services/flash-transfer/get-download-url';
// 0x93d4 真实响应(send_packet 抓于 QQ 9.9.26-44343, 2026-06-20, fileset e7453377 已发送)。
// byte-oracle:decode + deserialize 必须从 f1.f3.f14.f1 提取到主文件 fileId。
// 0x93d4 响应结构与 0x93d3 不同(downloadUrl 在深层嵌套,非 f9.fileIdWrap),这个测试
// 锁定该结构,防止 deserialize 退回错误的 FlashFileEntry 解读。
const RESP_HEX =
'08d4a7021001180022b8090ab50910011afa080a2465373435333337372d633865612d343034652d393238352d353361613566616431393832122466613038663938332d323337662d303833632d656536332d6139646164336161616565352801300138024222e5b18fe5b995e5bd95e588b620323032352d30352d3033203135313234312e6d70344a2162696e676d756c757a686920323032352d30352d3033203135313234312e6d703458bcf7e3036ae9050a6645685330442d4c3261494b306b74314d51424f764f5377746465753574426a7939774567746e516f724c6d736d5961566c514d794248427962325251674f704a5768424d3744724a3276364843594c766576376b6f30587565674d4d61502d4341514a6e656712a804080212a30468747470733a2f2f6d756c74696d656469612e7166696c652e71712e636f6d2f646f776e6c6f61643f61707069643d313439303226636c69656e745f747970653d77696e26636c69656e745f7665723d392e322e33342666696c6569643d45685330442d4c3261494b306b74314d51424f764f5377746465753574426a7939774567746e516f724c6d736d5961566c514d794248427962325251674f704a5768424d3744724a3276364843594c766576376b6f30587565674d4d61502d4341514a6e656726666c64633d696358456459355a6b5346395f59347239514f526e58562d6a6b31536d397753546b4a316a6876334f357a5f747331484966612d4c6a7662416b52494531526c4373704a4776336c453469635434467437414a794c33577242304b78696a555f423270386a75367a3371314d26726b65793d43414d5371414878697a55514532647437517975726675552d78446d3568666a4d727073325a69723764535f42354d55694349644e594c495167792d5264776d495a797a584a6f31714a687834464d756b346a337042306a5f37787850315a7a6748706469315f3158376178422d736541556c5f3646546f4679597638564d5337645a577036414275597a3875517a79306c487574676a6762714271477138336d70417a6465426475555833513043732d426b54676952767768664b3835696661774a3874477371576e70784871394f444c762d5f37566a78526e424456587046314f306343551a286234306665326636363838326234393264643463343031336166333932633264373565626239623420f2f7012a20393365643461306234383164623936343335323034363339626366393133313830800438c002726b0a674568512d63526273544d5338304c79484637745658626c38536c5a4e63426938392d4d44494c56304b497154305a6d476c5a55444d675277636d396b5549447153566f5156637648434d53585865556b54726c384e555f4a41586f444c6b625f676745435a336f18027a2466613038663938332d323337662d303833632d656536332d613964616433616161656535900103a2012833653731313665633463633462636430626338373137626235353564623937633461353634643730a801bcf7e303b2010308d547ca0120346365613333363331386338303864646431646630613333633938316339316122327b226f6666736574223a31382c22637572736f725f74696d65223a22303030312d30312d30315430303a30303a30305a227d28012a005a1d0a0f636c69656e745f636f6e6e5f736571120a313738313932393033395a200a1a747270632d6f632d7072696f726974792d706173732d6261636b12022d315a1c0a0e73736f5f647965696e675f6b6579120a323535303431393036385a160a0c73736f5f636c69656e74696412063133333034375a9c040a08747270632d73736f128f04000000147061d586907300000ba05fe3000207b7000001fb0073c9510000000e3235353034313930363820071b1b000008040000000000000000000003000000004c668066ca67e24ac9a81bd08aa343840338fa2f632ec020158218d5d2a35f1a2ab856dcbdcc486af66c8ba961db5532e2a065d882604a01539050c7ad17748f95521b4dac5e1834160000001b4f696462537663547270635463702e3078393364345f31000000188e0800005f3a366a000000008d0b00000000000000000000000000002462376234353837623661333666373535346564353235613563396230303166660000000000000000000000040000011d1a007a91020a047061d58610081a06392e322e333420c19e0c4220633165633037346532323533303539633230303530333039653965643932666552005a10b7b4587b6a36f7554ed525a5c9b001ff62206237623435383762366133366637353534656435323561356339623030316666688008720757696e646f7773820118755f6c5253732d3243757359575a6a455851707045694d518a01009001019a015208081248668066ca67e24ac9a81bd08aa343840338fa2f632ec020158218d5d2a35f1a2ab856dcbdcc486af66c8ba961db5532e2a065d882604a01539050c7ad17748f95521b4dac5e18341618c4acf8fa05a00100b80165c00100d201174f696462537663547270635463702e3078393364345f3190010d';
describe('GetDownloadUrl byte-oracle (0x93d4 deserialize)', () => {
it('extracts main file fileId from f1.f3.f14.f1', () => {
const bytes = Uint8Array.from(Buffer.from(RESP_HEX, 'hex'));
const env = protobuf_decode<OidbBase<FlashGetDownloadUrlResp>>(bytes);
const result = GetDownloadUrl.deserialize(null as never, env.body!);
// 0x93d4 f1.f3 是 repeated fileInfo,单文件场景返回一个元素的数组。
expect(result).toHaveLength(1);
const meta = result[0];
// 主文件 fileId(0x93d4 f14.f1),用于 0x12a9 sub=200 拿主文件下载直链。
expect(meta.fileId).toBe(
'EhQ-cRbsTMS80LyHF7tVXbl8SlZNcBi89-MDILV0KIqT0ZmGlZUDMgRwcm9kUIDqSVoQVcvHCMSXXeUkTrl8NU_JAXoDLkb_ggECZ3o',
);
expect(meta.filesetUuid).toBe('e7453377-c8ea-404e-9285-53aa5fad1982');
expect(meta.fileName).toContain('mp4');
expect(meta.fileSize).toBe(7928764);
expect(meta.fileIndex).toBe(1);
});
});
@@ -0,0 +1,94 @@
import { describe, expect, it } from 'vitest';
import { protobuf_encode, protobuf_decode } from '@snowluma/proton';
import type { FlashPrepareUploadReq } from '@snowluma/proto-defs/oidb-actions/flash-transfer';
// 真实 sub=100 (mp4) frida 抓包(QQ 9.9.26-44343, 2026-06-19)。payload @ f2(不是 f12!)。
// byte-oracle:用抓包值构造 req,encode 必须 byte-for-byte 匹配。
const SUB100_MP4_HEX =
'0a180a0408081064120ca80602b00604b80616c00c051a0208011298020a6b0a6708a0d2e40212001a28643138333762626336666131653031396136326330343734616332386563363131343565656138612222e5b18fe5b995e5bd95e588b620323032352d31322d3232203135313432392e6d70342a08080010001800200030003800400048011000100118002000280032120a040800120012021a001a045a0062005000380040004a88010a2432383564346530622d363465342d343961642d396430632d666234383938393930626162122432383564346530622d363465342d343961642d396430632d6662343839383939306261621a2432343166356438382d333637352d623030612d303261302d30633035306138343032656520012800300038024200480150005800600068007000';
const SUB100_MP4_REQ: FlashPrepareUploadReq = {
head: {
sub: { seq: 8, sub: 100 },
config: { field101: 2, field102: 4, field103: 22, field200: 5 },
field3: { field1: 1 },
},
payload: {
wrapper: {
fileInfo: {
fileSize: 5843232,
md5: '',
sha1: 'd1837bbc6fa1e019a62c0474ac28ec61145eea8a',
fileName: '屏幕录制 2025-12-22 151429.mp4',
field5: { field1: 0, field2: 0, field3: 0, field4: 0 },
field6: 0,
field7: 0,
field8: 0,
field9: 1,
},
field2: 0,
},
field2: 1,
field3: 0,
field4: 0,
field5: 0,
field6: {
field1: { field1: 0, field2: {} },
field2: { field3: {} },
field3: { field11: {}, field12: {} },
field10: 0,
},
field7: 0,
field8: 0,
filesetWrap: {
filesetUuid: '285d4e0b-64e4-49ad-9d0c-fb4898990bab',
uploadKey: '285d4e0b-64e4-49ad-9d0c-fb4898990bab',
fileUuid: '241f5d88-3675-b00a-02a0-0c050a8402ee',
field4: 1,
field5: 0,
field6: 0,
field7: 2,
field8: {},
field9: 1,
field10: 0,
field11: 0,
field12: 0,
field13: 0,
field14: 0,
},
},
};
describe('PrepareUpload byte-oracle (0x12a9_100 encode == frida 抓包)', () => {
it('encodes the sub=100 mp4 capture to the exact wire bytes', () => {
const out = Buffer.from(protobuf_encode<FlashPrepareUploadReq>(SUB100_MP4_REQ)).toString(
'hex',
);
if (out !== SUB100_MP4_HEX) {
const n = Math.min(out.length, SUB100_MP4_HEX.length);
let i = 0;
while (i < n && out[i] === SUB100_MP4_HEX[i]) {
i++;
}
throw new Error(
`hex mismatch at char ${i} (byte ${i >> 1}):\n` +
` bot: ...${out.slice(Math.max(0, i - 24), i + 24)}\n` +
` frida: ...${SUB100_MP4_HEX.slice(Math.max(0, i - 24), i + 24)}\n` +
` bot len=${out.length / 2}B, frida len=${SUB100_MP4_HEX.length / 2}B`,
);
}
expect(out).toBe(SUB100_MP4_HEX);
});
it('round-trips: encode → decode preserves key fields', () => {
const bytes = protobuf_encode<FlashPrepareUploadReq>(SUB100_MP4_REQ);
const back = protobuf_decode<FlashPrepareUploadReq>(bytes);
expect(back.head?.sub?.sub).toBe(100);
expect(back.payload?.wrapper?.fileInfo?.fileSize).toBe(5843232);
expect(back.payload?.filesetWrap?.fileUuid).toBe('241f5d88-3675-b00a-02a0-0c050a8402ee');
});
});
@@ -0,0 +1,68 @@
import { describe, expect, it } from 'vitest';
import { protobuf_encode, protobuf_decode } from '@snowluma/proton';
import type { FlashSendReq } from '@snowluma/proto-defs/oidb-actions/flash-transfer';
// 0x93d7 send_flash_msg 真实客户端请求 body(frida 抓包,QQ 9.9.26-44343, 2026-06-20)。
// fileset e7453377-c8ea-404e-9285-53aa5fad1982 发送给 uid u_0aHrwL1tyskEWkhChJoeJg。
// byte-oracle:用抓包值构造 req,encode 必须 byte-for-byte 匹配。
const SEND_HEX =
'0a1e0801121a0a18755f30614872774c317479736b45576b6843684a6f654a67122465373435333337372d633865612d343034652d393238352d353361613566616431393832';
const SEND_REQ: FlashSendReq = {
target: { field1: 1, targetUid: { targetUid: 'u_0aHrwL1tyskEWkhChJoeJg' } },
filesetUuid: 'e7453377-c8ea-404e-9285-53aa5fad1982',
};
describe('SendFlashMsg byte-oracle (0x93d7 encode == frida 抓包)', () => {
it('encodes the send capture to the exact wire bytes', () => {
const out = Buffer.from(protobuf_encode<FlashSendReq>(SEND_REQ)).toString('hex');
if (out !== SEND_HEX) {
const n = Math.min(out.length, SEND_HEX.length);
let i = 0;
while (i < n && out[i] === SEND_HEX[i]) {
i++;
}
throw new Error(
`hex mismatch at char ${i} (byte ${i >> 1}):\n` +
` bot: ...${out.slice(Math.max(0, i - 20), i + 20)}\n` +
` frida: ...${SEND_HEX.slice(Math.max(0, i - 20), i + 20)}\n` +
` bot len=${out.length / 2}B, frida len=${SEND_HEX.length / 2}B`,
);
}
expect(out).toBe(SEND_HEX);
});
it('round-trips: encode → decode preserves target + filesetUuid', () => {
const bytes = protobuf_encode<FlashSendReq>(SEND_REQ);
const back = protobuf_decode<FlashSendReq>(bytes);
expect(back.target?.field1).toBe(1);
expect(back.target?.targetUid?.targetUid).toBe('u_0aHrwL1tyskEWkhChJoeJg');
expect(back.filesetUuid).toBe('e7453377-c8ea-404e-9285-53aa5fad1982');
});
});
// 群聊 0x93d7:f1={f1:2, f3:{f1:groupId}}, f2=filesetUuid(groupId 直接用群号,无需转 uid)。
// 真实客户端 frida 抓包(2026-06-20),fileset e7453377 发送给群 1017438661。
const SEND_GROUP_HEX =
'0a0a08021a0608c5c393e503122465373435333337372d633865612d343034652d393238352d353361613566616431393832';
const SEND_GROUP_REQ: FlashSendReq = {
target: { field1: 2, targetGroup: { groupId: 1017438661 } },
filesetUuid: 'e7453377-c8ea-404e-9285-53aa5fad1982',
};
describe('SendFlashMsg byte-oracle (0x93d7 群聊 encode == frida 抓包)', () => {
it('encodes the group send capture to the exact wire bytes', () => {
const out = Buffer.from(protobuf_encode<FlashSendReq>(SEND_GROUP_REQ)).toString('hex');
expect(out).toBe(SEND_GROUP_HEX);
});
it('round-trips: encode → decode preserves groupId', () => {
const back = protobuf_decode<FlashSendReq>(protobuf_encode<FlashSendReq>(SEND_GROUP_REQ));
expect(back.target?.field1).toBe(2);
expect(back.target?.targetGroup?.groupId).toBe(1017438661);
});
});