probe-format.js 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. // 探针:0xa4 0x05 是不是某种压缩/编码 wrapper
  2. const fs = require('fs');
  3. const zlib = require('zlib');
  4. const target = process.argv[2];
  5. const raw = fs.readFileSync(target);
  6. console.log('File:', target);
  7. console.log('Size:', raw.length);
  8. console.log('First 32 bytes:', raw.subarray(0, 32).toString('hex'));
  9. // 1. 尝试 brotli 解压整段
  10. try {
  11. const d = zlib.brotliDecompressSync(raw);
  12. console.log('[brotli full]: OK, decompressed to', d.length, 'bytes');
  13. console.log(' first 32:', d.subarray(0, 32).toString('hex'));
  14. } catch (e) {
  15. console.log('[brotli full] FAIL:', e.message);
  16. }
  17. // 2. 尝试跳过前 N 字节 brotli 解压
  18. for (let skip of [0, 1, 2, 4, 8]) {
  19. try {
  20. const d = zlib.brotliDecompressSync(raw.subarray(skip));
  21. console.log(`[brotli skip=${skip}]: OK, ${d.length} bytes, first 16: ${d.subarray(0, 16).toString('hex')}`);
  22. } catch (e) { /* skip */ }
  23. }
  24. // 3. 尝试 gzip 解压
  25. for (let skip of [0, 2, 4]) {
  26. try {
  27. const d = zlib.gunzipSync(raw.subarray(skip));
  28. console.log(`[gzip skip=${skip}]: OK, ${d.length} bytes`);
  29. } catch (e) { /* skip */ }
  30. }
  31. // 4. 看 V8 字节码的 source hash (字节 8-12 LE) 是否合理
  32. const MAGIC = Buffer.from([0xde, 0xc0]);
  33. for (let off = 0; off < 6; off++) {
  34. if (raw.subarray(off + 2, off + 4).equals(MAGIC) || raw.subarray(off, off + 2).equals(MAGIC)) {
  35. console.log(`V8 magic at offset ${off}`);
  36. if (off + 12 <= raw.length) {
  37. const sourceHash = raw.readUInt32LE(off + 8);
  38. const flagHash = raw.readUInt32LE(off + 12);
  39. console.log(` source hash (should be source length): ${sourceHash}`);
  40. console.log(` flag hash: 0x${flagHash.toString(16)}`);
  41. }
  42. }
  43. }