Last active
August 7, 2026 17:16
-
-
Save wdormann/70e456ecaf15a6522e9343fd264bc322 to your computer and use it in GitHub Desktop.
Extract uMatrix rules from Local Extension Settings directory
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| """ | |
| Extract uMatrix settings from Chrome's chrome.storage.local LevelDB. | |
| """ | |
| import plyvel | |
| import json | |
| import sys | |
| import os | |
| DB_PATH = sys.argv[1] if len(sys.argv) > 1 else os.path.expanduser(".") | |
| OUTPUT_MAP = { | |
| "userMatrix": "umatrix-rules.txt", # My rules | |
| "userSettings": "umatrix-settings.json", # General settings | |
| "rawSettings": "umatrix-raw-settings.json", | |
| "liveHostsFiles": "umatrix-hosts-meta.json", | |
| "selectedHostsFiles": "umatrix-selected-hosts.json", | |
| "externalHostsFiles": "umatrix-external-hosts.json", | |
| "userHosts": "umatrix-user-hosts.txt", | |
| "userRecipes": "umatrix-user-recipes.txt", | |
| } | |
| def decode_value(raw_bytes): | |
| try: | |
| return json.loads(raw_bytes) | |
| except (json.JSONDecodeError, UnicodeDecodeError): | |
| return raw_bytes.decode("utf-8", errors="ignore") | |
| def clean_text(data): | |
| if isinstance(data, str): | |
| text = data.replace("\\n", "\n") | |
| text = text.replace("\\t", "\t") | |
| text = text.replace("\\r", "") | |
| text = text.replace("\\\\", "\\") | |
| text = text.replace("\x00", "").replace("\r", "") | |
| lines = [line.rstrip() for line in text.split("\n")] | |
| return "\n".join(lines) | |
| elif isinstance(data, list): | |
| return "\n".join(str(x) for x in data) | |
| elif isinstance(data, dict): | |
| return json.dumps(data, indent=2) | |
| else: | |
| return str(data) | |
| def main(): | |
| if not os.path.isdir(DB_PATH): | |
| print(f"Error: '{DB_PATH}' is not a directory.") | |
| sys.exit(1) | |
| db = plyvel.DB(DB_PATH, create_if_missing=False) | |
| found = set() | |
| for key, value in db: | |
| key_str = key.decode("utf-8", errors="ignore") | |
| data = decode_value(value) | |
| if key_str in OUTPUT_MAP: | |
| out_file = OUTPUT_MAP[key_str] | |
| cleaned = clean_text(data) | |
| with open(out_file, "w", encoding="utf-8") as f: | |
| f.write(cleaned) | |
| lines = cleaned.count("\n") if "\n" in cleaned else 0 | |
| print(f" [+] {key_str:25s} -> {out_file} ({lines} lines)") | |
| found.add(key_str) | |
| else: | |
| preview = str(data)[:120].replace("\n", " ") | |
| print(f" [-] {key_str:25s} : {preview}...") | |
| db.close() | |
| print() | |
| if "userMatrix" in found: | |
| print("Import into uMatrix:") | |
| print(" Dashboard -> My rules -> Import from file -> select umatrix-rules.txt") | |
| else: | |
| print("No userMatrix found. Check the [-] lines for actual key names.") | |
| if __name__ == "__main__": | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment