feat: implement Zalo database extraction and schema analysis script via ADB
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
import os
|
||||
import subprocess
|
||||
import logging
|
||||
import sqlite3
|
||||
import shutil
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
|
||||
def run_adb_command(command: str):
|
||||
"""Chạy lệnh ADB shell và trả về kết quả"""
|
||||
full_cmd = f"adb shell {command}"
|
||||
try:
|
||||
result = subprocess.run(full_cmd, shell=True, check=True, capture_output=True, text=True)
|
||||
return result.stdout.strip()
|
||||
except subprocess.CalledProcessError as e:
|
||||
return None
|
||||
|
||||
def analyze_zalo():
|
||||
logging.info("BẮT ĐẦU TRÍCH XUẤT DATABASE ZALO (PULL VỀ SERVER)")
|
||||
# Đảm bảo kết nối
|
||||
subprocess.run("adb connect 10.160.138.2:5555", shell=True, capture_output=True)
|
||||
|
||||
# Tạo thư mục chứa db
|
||||
os.makedirs("zalo_dbs", exist_ok=True)
|
||||
|
||||
# Lấy danh sách các UID (thư mục) trong databases
|
||||
zalo_db_path = "/data/data/com.zing.zalo/databases"
|
||||
ls_output = run_adb_command(f"su -c 'ls -l {zalo_db_path}'")
|
||||
|
||||
if not ls_output:
|
||||
logging.error("Không thể truy cập thư mục Zalo. Kiểm tra lại quyền Root.")
|
||||
return
|
||||
|
||||
# Tìm các thư mục có tên là số (UID)
|
||||
uid_folders = []
|
||||
for line in ls_output.split('\n'):
|
||||
if line.startswith('d'): # là thư mục
|
||||
parts = line.split()
|
||||
folder_name = parts[-1]
|
||||
if folder_name.isdigit():
|
||||
uid_folders.append(folder_name)
|
||||
|
||||
if not uid_folders:
|
||||
logging.error("Không tìm thấy thư mục UID nào của Zalo!")
|
||||
return
|
||||
|
||||
logging.info(f"Tìm thấy các thư mục tài khoản Zalo: {uid_folders}")
|
||||
|
||||
with open("zalo_schema_dump.txt", "w", encoding="utf-8") as f:
|
||||
f.write("=== DUMP CẤU TRÚC DATABASE ZALO ===\n")
|
||||
|
||||
for uid in uid_folders:
|
||||
logging.info(f"Đang xử lý tài khoản: {uid}")
|
||||
# Liệt kê các file trong thư mục UID
|
||||
files_in_uid = run_adb_command(f"su -c 'ls {zalo_db_path}/{uid}/'")
|
||||
if not files_in_uid: continue
|
||||
|
||||
for db_file in files_in_uid.split('\n'):
|
||||
db_file = db_file.strip()
|
||||
if not db_file or not db_file.endswith('.db'): continue
|
||||
|
||||
logging.info(f"Phát hiện file DB: {db_file}")
|
||||
|
||||
# Copy file ra sdcard để có thể pull về
|
||||
run_adb_command(f"su -c 'cp {zalo_db_path}/{uid}/{db_file} /sdcard/temp_zalo_{db_file}'")
|
||||
run_adb_command(f"su -c 'chmod 666 /sdcard/temp_zalo_{db_file}'")
|
||||
|
||||
# Pull file về server
|
||||
local_path = os.path.join("zalo_dbs", f"{uid}_{db_file}")
|
||||
subprocess.run(f"adb pull /sdcard/temp_zalo_{db_file} {local_path}", shell=True, capture_output=True)
|
||||
run_adb_command(f"su -c 'rm /sdcard/temp_zalo_{db_file}'") # Xóa file tạm
|
||||
|
||||
if os.path.exists(local_path):
|
||||
logging.info(f"Đã kéo file về thành công: {local_path}. Đang phân tích...")
|
||||
try:
|
||||
conn = sqlite3.connect(local_path)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Lấy danh sách các bảng
|
||||
cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
|
||||
tables = cursor.fetchall()
|
||||
|
||||
if tables:
|
||||
with open("zalo_schema_dump.txt", "a", encoding="utf-8") as f:
|
||||
f.write(f"\n\n--- Cấu trúc file: {db_file} (Tài khoản {uid}) ---\n")
|
||||
f.write(f"Danh sách bảng: {[t[0] for t in tables]}\n")
|
||||
|
||||
for table_tuple in tables:
|
||||
table_name = table_tuple[0]
|
||||
if "msg" in table_name.lower() or "chat" in table_name.lower() or "group" in table_name.lower():
|
||||
cursor.execute(f"PRAGMA table_info({table_name});")
|
||||
columns = cursor.fetchall()
|
||||
f.write(f"\nBảng '{table_name}':\n")
|
||||
for col in columns:
|
||||
f.write(f" - {col[1]} ({col[2]})\n")
|
||||
conn.close()
|
||||
except Exception as e:
|
||||
logging.warning(f"Lỗi khi đọc file SQLite {local_path}: {str(e)}")
|
||||
|
||||
logging.info("Hoàn tất! Hãy gửi cho tôi nội dung file zalo_schema_dump.txt để phân tích.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
analyze_zalo()
|
||||
Reference in New Issue
Block a user