75 lines
2.2 KiB
Python
75 lines
2.2 KiB
Python
"""Decrypt/encrypt xxbb details 7zAES wires (show.html / *.js)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import shutil
|
|
import subprocess
|
|
import tempfile
|
|
from pathlib import Path
|
|
|
|
try:
|
|
import py7zr
|
|
except ImportError as exc: # pragma: no cover
|
|
raise SystemExit(f"py7zr import failed: {exc}. pip install py7zr") from exc
|
|
|
|
SEVEN_ZIP_PASSWORD = "202800cfb1ad3de68e11239dcc26c30b"
|
|
# Matches original corepayload.js wire size closely (~521913).
|
|
_7Z_PACK_FILTER = "LZMA2"
|
|
|
|
|
|
def _find_7z() -> str:
|
|
for name in ("7z", "7za"):
|
|
path = shutil.which(name)
|
|
if path:
|
|
return path
|
|
raise SystemExit(
|
|
"7z required to pack xxbb details archives. Install p7zip / 7-Zip."
|
|
)
|
|
|
|
|
|
def extract_member(archive: bytes, *, password: str = SEVEN_ZIP_PASSWORD) -> tuple[str, bytes]:
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
root = Path(tmp)
|
|
arc = root / "in.7z"
|
|
arc.write_bytes(archive)
|
|
with py7zr.SevenZipFile(arc, mode="r", password=password) as handle:
|
|
names = handle.getnames()
|
|
if len(names) != 1:
|
|
raise SystemExit(f"expected one archive member, got {names!r}")
|
|
handle.extractall(path=root)
|
|
member = names[0]
|
|
data = (root / member).read_bytes()
|
|
return Path(member).name, data
|
|
|
|
|
|
def make_passworded_7z(
|
|
member_name: str,
|
|
payload: bytes,
|
|
*,
|
|
password: str = SEVEN_ZIP_PASSWORD,
|
|
) -> bytes:
|
|
arc_name = Path(member_name).name
|
|
seven = _find_7z()
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
archive = Path(tmp) / "out.7z"
|
|
cmd = [
|
|
seven,
|
|
"a",
|
|
"-t7z",
|
|
f"-m0={_7Z_PACK_FILTER}",
|
|
"-mhe=on",
|
|
f"-p{password}",
|
|
f"-si{arc_name}",
|
|
"-y",
|
|
"-bso0",
|
|
"-bsp0",
|
|
str(archive),
|
|
]
|
|
proc = subprocess.run(cmd, input=payload, capture_output=True)
|
|
if proc.returncode != 0 or not archive.is_file():
|
|
detail = (proc.stderr or proc.stdout or b"").decode("utf-8", "replace").strip()
|
|
raise RuntimeError(
|
|
f"7z -si pack failed (code {proc.returncode}): {detail or 'no output'}"
|
|
)
|
|
return archive.read_bytes()
|