import os, subprocess, shutil, sys src = '/data/data/com.tencent.mm/MicroMsg/653cdc2320abb089e149a3f7a7683fcf/EnMicroMsg.db' work_dir = '/data/data/com.termux/files/home/hermes_work_wal' if os.path.exists(work_dir): shutil.rmtree(work_dir) os.makedirs(work_dir, exist_ok=True) # Copy DB + WAL + SHM for suffix in ['', '-wal', '-shm']: s = src + suffix dst = os.path.join(work_dir, os.path.basename(s)) if os.path.exists(s): shutil.copy(s, dst) print(f'copied {s} -> {dst} size={os.path.getsize(dst)}') else: print(f'not found: {s}') # List files with permissions print('\nFiles in work_dir:') for f in os.listdir(work_dir): p = os.path.join(work_dir, f) import stat st = os.stat(p) print(f' {f}: size={st.st_size} mode={oct(st.st_mode)} uid={st.st_uid} gid={st.st_gid}') # Try decrypt with WAL present enc = os.path.join(work_dir, 'EnMicroMsg.db') plain = '/data/data/com.termux/files/home/EnMicroMsg_wal_test.db' if os.path.exists(plain): os.remove(plain) sql = """PRAGMA key = "e03ce81"; PRAGMA cipher_compatibility = 1; PRAGMA cipher_page_size = 1024; ATTACH DATABASE '/data/data/com.termux/files/home/EnMicroMsg_wal_test.db' AS plain KEY ''; SELECT sqlcipher_export('plain'); DETACH DATABASE plain; .quit """ r = subprocess.run( ['/data/data/com.termux/files/usr/bin/sqlcipher', enc], input=sql, capture_output=True, text=True, timeout=60 ) print(f'\nDecrypt with WAL: rc={r.returncode}') print(f'stderr={r.stderr!r}') print(f'plain exists={os.path.exists(plain)}') if os.path.exists(plain): print(f'plain size={os.path.getsize(plain)}') # Now try after removing WAL for suffix in ['-wal', '-shm']: f = os.path.join(work_dir, 'EnMicroMsg.db' + suffix) if os.path.exists(f): os.remove(f) print(f'\nremoved {f}') plain2 = '/data/data/com.termux/files/home/EnMicroMsg_nowal_test.db' if os.path.exists(plain2): os.remove(plain2) sql2 = """PRAGMA key = "e03ce81"; PRAGMA cipher_compatibility = 1; PRAGMA cipher_page_size = 1024; ATTACH DATABASE '/data/data/com.termux/files/home/EnMicroMsg_nowal_test.db' AS plain KEY ''; SELECT sqlcipher_export('plain'); DETACH DATABASE plain; .quit """ r2 = subprocess.run( ['/data/data/com.termux/files/usr/bin/sqlcipher', enc], input=sql2, capture_output=True, text=True, timeout=60 ) print(f'\nDecrypt without WAL: rc={r2.returncode}') print(f'stderr={r2.stderr!r}') print(f'plain exists={os.path.exists(plain2)}') if os.path.exists(plain2): print(f'plain size={os.path.getsize(plain2)}')