decode_env.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. """Decode 996box env.json files and write results to decode_env_output.txt.
  2. Finds the base64 payload dynamically, handles non-UTF-8 bytes, and
  3. saves results to a file (avoids Windows console encoding issues).
  4. """
  5. import base64
  6. import json
  7. from pathlib import Path
  8. OUT_FILE = Path("decode_env_output.txt")
  9. SENSITIVE_KEYS = ("sign", "key", "token", "password", "pwd")
  10. def try_decode(b64_candidate: str) -> dict | None:
  11. try:
  12. padded = b64_candidate + "=" * (-len(b64_candidate) % 4)
  13. decoded = base64.urlsafe_b64decode(padded)
  14. obj = json.loads(decoded.decode("utf-8", errors="replace"))
  15. if isinstance(obj, dict):
  16. return obj
  17. except Exception:
  18. return None
  19. return None
  20. def show(path: Path, lines: list[str]) -> None:
  21. lines.append(f"=== {path} ===")
  22. if not path.exists():
  23. lines.append(" not found")
  24. lines.append("")
  25. return
  26. raw = path.read_bytes()
  27. lines.append(f" size: {len(raw)} bytes")
  28. # Show first 40 bytes as hex + repr to handle non-UTF-8
  29. lines.append(f" first 40 bytes (hex): {raw[:40].hex()}")
  30. lines.append(f" first 40 bytes (repr): {raw[:40]!r}")
  31. text = raw.decode("utf-8", errors="replace")
  32. # Find base64 payload start (MeyJ = base64url of '{"')
  33. for marker_idx, marker in enumerate(("MeyJ", "eyJ", "{")):
  34. idx = text.find(marker)
  35. if idx < 0:
  36. continue
  37. b64 = text[idx:].rstrip()
  38. if marker == "{":
  39. # Try raw JSON parse
  40. try:
  41. obj = json.loads(b64)
  42. if isinstance(obj, dict):
  43. lines.append(f" parsed as raw JSON from position {idx}")
  44. lines.append(f" keys: {list(obj.keys())}")
  45. for k, v in obj.items():
  46. is_sensitive = any(s in k.lower() for s in SENSITIVE_KEYS)
  47. if is_sensitive and isinstance(v, str):
  48. lines.append(f" {k}: ***REDACTED*** (len={len(v)})")
  49. else:
  50. sv = str(v)
  51. display = sv[:120] + ("..." if len(sv) > 120 else "")
  52. lines.append(f" {k}: {display}")
  53. lines.append("")
  54. return
  55. except Exception:
  56. pass
  57. else:
  58. obj = try_decode(b64)
  59. if obj is not None:
  60. lines.append(f" decoded via base64url from position {idx} ({len(b64)} chars)")
  61. lines.append(f" decoded keys: {list(obj.keys())}")
  62. for k, v in obj.items():
  63. is_sensitive = any(s in k.lower() for s in SENSITIVE_KEYS)
  64. if is_sensitive and isinstance(v, str):
  65. lines.append(f" {k}: ***REDACTED*** (len={len(v)})")
  66. else:
  67. sv = str(v)
  68. display = sv[:120] + ("..." if len(sv) > 120 else "")
  69. lines.append(f" {k}: {display}")
  70. lines.append("")
  71. return
  72. # Last resort: show the raw text truncated
  73. lines.append(" could not decode; raw text (truncated):")
  74. lines.append(f" {text[:200]!r}")
  75. lines.append("")
  76. def main() -> int:
  77. lines: list[str] = []
  78. lines.append("996box env.json decoder output")
  79. lines.append("=" * 60)
  80. lines.append("")
  81. for path_str in [
  82. r"D:\ProgramFiles\996box\GameBoxDownload\1\env.json",
  83. r"D:\ProgramFiles\996box\GameBoxDownload\1\cq\env.json",
  84. ]:
  85. show(Path(path_str), lines)
  86. OUT_FILE.write_text("\n".join(lines), encoding="utf-8")
  87. print(f"output written to: {OUT_FILE.resolve()}")
  88. print(f"file size: {OUT_FILE.stat().st_size} bytes")
  89. return 0
  90. if __name__ == "__main__":
  91. import sys
  92. sys.exit(main())