安卓模拟器一键导入Fiddler证书脚本是一个专门为Android模拟器设计的自动化工具,主要用于将Fiddler的根证书一键安装到模拟器的系统证书目录中,从而实现HTTPS抓包功能。该项目包含命令行版本和图形界面版本,支持多种安装方案和自动检测功能,让证书导入过程变得简单高效。
class FiddlerCertInstaller:
def __init__(self, adb_path=None, ldplayer_path=None):
self.adb_path = adb_path or self._find_adb_path(ldplayer_path)
self.fiddler_cert_path = self._find_fiddler_cert()
self.cert_filename = "FiddlerRoot.cer"
self.android_cert_dir = "/system/etc/security/cacerts/"
self.android_cert_path = f"{self.android_cert_dir}{self.cert_filename}"
核心方法:
_find_adb_path()
: 智能查找ADB可执行文件路径_find_fiddler_cert()
: 自动检测Fiddler根证书位置check_device_connection()
: 检查设备连接状态remount_system()
: 重新挂载系统分区为可写install_certificate()
: 执行证书安装流程verify_installation()
: 验证证书安装结果class FiddlerCertInstallerGUI:
def __init__(self, root):
self.root = root
self.root.title("Fiddler证书安装器")
self.root.geometry("600x500")
self.root.resizable(True, True)
# 变量
self.adb_path = tk.StringVar()
self.cert_path = tk.StringVar()
self.install_thread = None
self.message_queue = queue.Queue()
GUI特性:
def build_exe():
"""使用PyInstaller打包GUI程序为exe文件"""
cmd = [
"pyinstaller",
"--name=Fiddler证书安装器",
"--onefile",
"--windowed",
"--icon=icon.ico",
"--add-data=FiddlerRoot.cer;.",
"--clean",
"--noconfirm",
str(gui_script)
]
def _find_adb_path(self, ldplayer_path=None):
"""查找adb.exe路径"""
possible_paths = []
# 用户提供的路径作为最高优先级
user_adb_path = r"C:\Program Files\Netease\MuMu Player 12\shell\adb.exe"
if os.path.exists(user_adb_path):
possible_paths.append(user_adb_path)
# 如果指定了雷电模拟器路径
if ldplayer_path:
possible_paths.extend([
os.path.join(ldplayer_path, "adb.exe"),
os.path.join(ldplayer_path, "ldadb.exe"),
os.path.join(ldplayer_path, "tools", "adb.exe")
])
# 常见的雷电模拟器安装路径
ldplayer_paths = [
r"C:\leidian\LDPlayer9",
r"C:\Program Files\LDPlayer\LDPlayer4.0",
r"C:\Program Files\LDPlayer\LDPlayer3.0",
r"C:\Program Files\LDPlayer\LDPlayer9.0",
r"D:\LDPlayer\LDPlayer4.0",
r"D:\LDPlayer\LDPlayer9.0",
r"C:\LDPlayer\LDPlayer4.0",
r"C:\LDPlayer\LDPlayer9.0",
]
for ld_path in ldplayer_paths:
if os.path.exists(ld_path):
possible_paths.extend([
os.path.join(ld_path, "adb.exe"),
os.path.join(ld_path, "ldadb.exe"),
os.path.join(ld_path, "tools", "adb.exe")
])
# 检查PATH环境变量
possible_paths.append("adb.exe")
for path in possible_paths:
try:
result = subprocess.run([path, "version"], capture_output=True, text=True, timeout=5)
if result.returncode == 0:
print(f"找到adb.exe: {path}")
return path
except (subprocess.TimeoutExpired, FileNotFoundError, subprocess.SubprocessError):
continue
raise FileNotFoundError("无法找到adb.exe,请手动指定adb路径")
def _find_fiddler_cert(self):
"""查找Fiddler根证书"""
possible_paths = [
"FiddlerRoot.cer", # 当前目录
os.path.join(os.getcwd(), "FiddlerRoot.cer"), # 当前工作目录
os.path.expanduser("~/Documents/Fiddler2/FiddlerRoot.cer"),
os.path.expanduser("~/Documents/Fiddler/FiddlerRoot.cer"),
r"C:\Program Files (x86)\Fiddler2\FiddlerRoot.cer",
r"C:\Program Files\Fiddler\FiddlerRoot.cer",
]
for path in possible_paths:
if os.path.exists(path):
print(f"找到Fiddler证书: {path}")
return path
# 尝试从注册表获取Fiddler安装路径
try:
import winreg
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\Fiddler.exe")
fiddler_path = winreg.QueryValueEx(key, "Path")[0]
cert_path = os.path.join(fiddler_path, "FiddlerRoot.cer")
if os.path.exists(cert_path):
print(f"从注册表找到Fiddler证书: {cert_path}")
return cert_path
except (ImportError, WindowsError):
pass
raise FileNotFoundError("无法找到Fiddler根证书,请确保Fiddler已安装并导出了根证书")
def install_certificate(self):
"""安装Fiddler证书到系统证书目录"""
# 检查设备连接
if not self.check_device_connection():
return False
# 重新挂载系统分区
if not self.remount_system():
print("无法重新挂载系统分区,请确保模拟器已root")
return False
# 上传证书到模拟器临时目录
temp_cert_path = "/data/local/tmp/FiddlerRoot.cer"
if not self.run_adb_command(["push", self.fiddler_cert_path, temp_cert_path]):
print("证书上传失败")
return False
# 方法1: 尝试直接复制到系统证书目录
if self.run_adb_command(["shell", "cp", temp_cert_path, self.android_cert_path]):
print("证书移动到系统目录成功")
self.run_adb_command(["shell", "chmod", "644", self.android_cert_path])
self.run_adb_command(["shell", "rm", "-f", temp_cert_path])
return True
# 方法2: 尝试使用mv命令
if self.run_adb_command(["shell", "mv", temp_cert_path, self.android_cert_path]):
print("证书移动到系统目录成功")
self.run_adb_command(["shell", "chmod", "644", self.android_cert_path])
return True
# 方法3: 尝试安装到用户证书目录
user_cert_dir = "/data/misc/user/0/cacerts-added/"
user_cert_path = f"{user_cert_dir}{self.cert_filename}"
if self.run_adb_command(["shell", "cp", temp_cert_path, user_cert_path]):
print("证书已安装到用户证书目录")
self.run_adb_command(["shell", "rm", "-f", temp_cert_path])
return True
# 方法4: 尝试保存到SD卡目录
sd_card_path = "/sdcard/Download/FiddlerRoot.cer"
if self.run_adb_command(["shell", "cp", temp_cert_path, sd_card_path]):
print(f"证书已保存到SD卡: {sd_card_path}")
print("请在模拟器中手动安装证书")
self.run_adb_command(["shell", "rm", "-f", temp_cert_path])
return True
return False
def start_installation(self):
"""开始安装证书"""
# 检查文件路径
adb_file = self.adb_path.get()
cert_file = self.cert_path.get()
if not adb_file or not cert_file:
messagebox.showerror("错误", "请选择ADB.exe文件和证书文件")
return
# 禁用安装按钮,防止重复点击
for widget in self.root.winfo_children():
if isinstance(widget, ttk.Frame):
for child in widget.winfo_children():
if isinstance(child, ttk.Button) and child.cget("text") == "安装证书":
child.config(state="disabled")
break
# 在新线程中运行安装过程
self.install_thread = threading.Thread(target=self.run_installation, args=(adb_file, cert_file))
self.install_thread.daemon = True
self.install_thread.start()
def run_installation(self, adb_file, cert_file):
"""运行安装过程"""
try:
installer = FiddlerCertInstaller(adb_path=adb_file)
installer.fiddler_cert_path = cert_file
installer.log_callback = self.log
success = installer.run()
if success:
self.log("\n=== 安装完成 ===")
self.log("请重启模拟器以使证书生效")
self.root.after(0, lambda: messagebox.showinfo("成功", "证书安装成功!请重启模拟器以使证书生效。"))
else:
self.log("\n=== 安装失败 ===")
self.root.after(0, lambda: messagebox.showerror("错误", "证书安装失败,请查看日志了解详细信息。"))
except Exception as e:
self.log(f"安装过程中发生错误: {e}")
self.root.after(0, lambda: messagebox.showerror("错误", f"安装过程中发生错误: {e}"))
finally:
# 重新启用安装按钮
self.root.after(0, self.enable_install_button)
核心需求: 开发一个能够一键导入Fiddler证书到安卓模拟器的自动化工具
功能设计:
# 创建项目目录
mkdir android-fiddler-cert-installer
cd android-fiddler-cert-installer
# 创建虚拟环境
python -m venv venv
venv\Scripts\activate # Windows
# 安装依赖
pip install -r requirements.txt
创建 install_fiddler_cert.py
文件,实现一键导入的核心逻辑:
import os
import subprocess
import sys
import shutil
from pathlib import Path
class FiddlerCertInstaller:
def __init__(self, adb_path=None, ldplayer_path=None):
# 自动初始化参数
self.adb_path = adb_path or self._find_adb_path(ldplayer_path)
self.fiddler_cert_path = self._find_fiddler_cert()
self.cert_filename = "FiddlerRoot.cer"
self.android_cert_dir = "/system/etc/security/cacerts/"
self.android_cert_path = f"{self.android_cert_dir}{self.cert_filename}"
def run(self):
"""一键执行完整的证书导入流程"""
try:
print("=== 安卓模拟器一键导入Fiddler证书 ===")
print(f"ADB路径: {self.adb_path}")
print(f"Fiddler证书路径: {self.fiddler_cert_path}")
print()
if self.install_certificate():
self.verify_installation()
print("\n=== 证书导入完成 ===")
print("请重启模拟器以使证书生效")
return True
else:
print("\n=== 证书导入失败 ===")
return False
except Exception as e:
print(f"导入过程中发生错误: {e}")
return False
# 实现各个核心方法...
创建 install_fiddler_cert_gui.py
文件,实现图形化一键操作界面:
import tkinter as tk
from tkinter import ttk, filedialog, messagebox, scrolledtext
import threading
import queue
class FiddlerCertInstallerGUI:
def __init__(self, root):
self.root = root
self.root.title("安卓模拟器一键导入Fiddler证书")
self.root.geometry("600x500")
self.root.resizable(True, True)
# 初始化变量
self.adb_path = tk.StringVar()
self.cert_path = tk.StringVar()
self.install_thread = None
self.message_queue = queue.Queue()
# 自动检测文件
self._auto_detect_files()
# 设置UI
self.setup_ui()
self.process_queue()
def _auto_detect_files(self):
"""自动检测ADB和证书文件"""
# 自动检测证书文件
current_dir = os.getcwd()
for file in os.listdir(current_dir):
if file.lower().endswith(('.cer', '.crt')):
self.cert_path.set(os.path.join(current_dir, file))
break
# 自动检测ADB文件
default_adb = os.path.join(current_dir, "adb.exe")
if os.path.exists(default_adb):
self.adb_path.set(default_adb)
def start_installation(self):
"""一键开始证书导入"""
# 检查文件路径
adb_file = self.adb_path.get()
cert_file = self.cert_path.get()
if not adb_file or not cert_file:
messagebox.showerror("错误", "请选择ADB.exe文件和证书文件")
return
# 禁用按钮,防止重复点击
self._disable_install_button()
# 清空日志
self.clear_log()
self.log("=== 开始一键导入Fiddler证书 ===")
# 在新线程中运行导入过程
self.install_thread = threading.Thread(target=self.run_installation, args=(adb_file, cert_file))
self.install_thread.daemon = True
self.install_thread.start()
# 实现UI和事件处理方法...
创建 build_exe.py
文件,实现一键打包成exe功能:
import os
import subprocess
import sys
import shutil
from pathlib import Path
def build_exe():
"""一键打包GUI程序为exe文件"""
print("=== 开始一键打包安卓模拟器Fiddler证书导入器 ===")
# 自动检查并安装PyInstaller
try:
import PyInstaller
print("PyInstaller已安装")
except ImportError:
print("PyInstaller未安装,正在自动安装...")
subprocess.run([sys.executable, "-m", "pip", "install", "pyinstaller"], check=True)
print("PyInstaller安装完成")
# 自动清理之前的构建
current_dir = Path.cwd()
dist_dir = current_dir / "dist"
build_dir = current_dir / "build"
if dist_dir.exists():
print("自动清理之前的dist目录...")
shutil.rmtree(dist_dir)
if build_dir.exists():
print("自动清理之前的build目录...")
shutil.rmtree(build_dir)
# 一键打包命令
cmd = [
"pyinstaller",
"--name=安卓模拟器Fiddler证书导入器",
"--onefile",
"--windowed",
"--clean",
"--noconfirm",
"install_fiddler_cert_gui.py"
]
print(f"执行一键打包命令: {' '.join(cmd)}")
try:
# 执行打包
result = subprocess.run(cmd, check=True, capture_output=True, text=True)
print("一键打包成功!")
# 检查生成的exe文件
exe_path = dist_dir / "安卓模拟器Fiddler证书导入器.exe"
if exe_path.exists():
print(f"\nEXE文件已生成: {exe_path}")
print(f"文件大小: {exe_path.stat().st_size / 1024 / 1024:.2f} MB")
return True
else:
print("错误: 未找到生成的exe文件")
return False
except subprocess.CalledProcessError as e:
print(f"一键打包失败: {e}")
return False
# 测试命令行版本一键导入
python install_fiddler_cert.py
# 测试GUI版本一键导入
python install_fiddler_cert_gui.py
# 测试一键打包功能
python build_exe.py
优化重点:
android-fiddler-cert-installer/
├── install_fiddler_cert.py # 命令行版本 - 一键导入核心逻辑
├── install_fiddler_cert_gui.py # GUI版本 - 图形化一键操作界面
├── build_exe.py # 一键打包脚本
├── requirements.txt # 依赖列表
├── FiddlerRoot.cer # 默认Fiddler证书文件
├── setup.py # setuptools配置
├── readme.md # 项目说明文档
└── dist/ # 打包输出目录
└── 安卓模拟器Fiddler证书导入器.exe # 一键导入工具exe文件
难点: 不同模拟器的ADB路径不同,需要智能检测。
解决方案: 实现多路径检测机制,支持常见模拟器路径和环境变量检测。
难点: 需要root权限才能修改系统证书目录。
解决方案: 使用adb root
命令获取root权限,然后重新挂载系统分区。
难点: 不同Android版本的系统权限和目录结构可能不同。
解决方案: 实现多种安装方案,按优先级尝试,确保兼容性。
难点: 安装过程可能耗时较长,需要避免界面卡顿。
解决方案: 使用多线程处理安装过程,通过消息队列更新UI。
# 基本用法 - 自动检测ADB和证书文件
python install_fiddler_cert.py
# 指定ADB路径 - 支持雷电、MUMU等模拟器
python install_fiddler_cert.py --adb "C:\Program Files\LDPlayer\LDPlayer4.0\adb.exe"
# 指定证书路径
python install_fiddler_cert.py --cert "FiddlerRoot.cer"
# 指定模拟器路径
python install_fiddler_cert.py --ldplayer "C:\Program Files\LDPlayer\LDPlayer4.0"
特点: 无需手动配置,自动检测环境,一键完成证书导入
# 启动GUI
python install_fiddler_cert_gui.py
一键操作步骤:
优势: 操作简单,界面友好,实时显示导入进度
# 使用一键打包脚本
python build_exe.py
# 或直接使用PyInstaller
pyinstaller --name="安卓模拟器Fiddler证书导入器" --onefile --windowed --clean --noconfirm install_fiddler_cert_gui.py
打包特点:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。