首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >安卓模拟器一键导入Fiddler证书脚本开发记录

安卓模拟器一键导入Fiddler证书脚本开发记录

原创
作者头像
高老师
发布2025-08-17 17:04:20
发布2025-08-17 17:04:20
20100
代码可运行
举报
运行总次数:0
代码可运行

安卓模拟器一键导入Fiddler证书脚本开发记录

项目概述

安卓模拟器一键导入Fiddler证书脚本是一个专门为Android模拟器设计的自动化工具,主要用于将Fiddler的根证书一键安装到模拟器的系统证书目录中,从而实现HTTPS抓包功能。该项目包含命令行版本和图形界面版本,支持多种安装方案和自动检测功能,让证书导入过程变得简单高效。

技术要点分析

1. 核心功能

  • 一键导入: 点击按钮即可完成证书导入全过程
  • 证书自动检测: 自动查找Fiddler根证书文件,无需手动指定
  • ADB路径智能识别: 支持雷电、MUMU等多种模拟器的ADB路径自动检测
  • 多方案证书安装: 系统目录、用户目录、SD卡目录三种安装方案,确保兼容性
  • 权限自动管理: 自动获取root权限并重新挂载系统分区
  • 图形界面: 基于tkinter的直观GUI界面,操作简单
  • 一键打包: 支持PyInstaller打包成独立exe文件,便于分发

2. 技术架构

2.1 命令行版本 (install_fiddler_cert.py)
代码语言:python
代码运行次数:0
运行
复制
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(): 验证证书安装结果
2.2 图形界面版本 (install_fiddler_cert_gui.py)
代码语言:python
代码运行次数:0
运行
复制
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特性:

  • 文件选择对话框
  • 实时日志显示
  • 多线程安装过程
  • 进度反馈
  • 错误处理
2.3 打包脚本 (build_exe.py)
代码语言:python
代码运行次数:0
运行
复制
def build_exe():
    """使用PyInstaller打包GUI程序为exe文件"""
    cmd = [
        "pyinstaller",
        "--name=Fiddler证书安装器",
        "--onefile",
        "--windowed",
        "--icon=icon.ico",
        "--add-data=FiddlerRoot.cer;.",
        "--clean",
        "--noconfirm",
        str(gui_script)
    ]

3. 关键技术实现

3.1 ADB路径智能检测
代码语言:python
代码运行次数:0
运行
复制
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路径")
3.2 证书文件自动检测
代码语言:python
代码运行次数:0
运行
复制
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已安装并导出了根证书")
3.3 多方案证书安装
代码语言:python
代码运行次数:0
运行
复制
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
3.4 GUI多线程实现
代码语言:python
代码运行次数:0
运行
复制
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)

4. 开发步骤详解

步骤1: 需求分析与设计

核心需求: 开发一个能够一键导入Fiddler证书到安卓模拟器的自动化工具

功能设计:

  • 自动检测ADB路径和证书文件
  • 一键完成证书导入全过程
  • 支持多种安卓模拟器(雷电、MUMU等)
  • 提供图形界面和命令行两种使用方式
  • 支持打包成独立exe文件
步骤2: 项目初始化
代码语言:bash
复制
# 创建项目目录
mkdir android-fiddler-cert-installer
cd android-fiddler-cert-installer

# 创建虚拟环境
python -m venv venv
venv\Scripts\activate     # Windows

# 安装依赖
pip install -r requirements.txt
步骤3: 实现核心自动化逻辑

创建 install_fiddler_cert.py 文件,实现一键导入的核心逻辑:

代码语言:python
代码运行次数:0
运行
复制
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
    
    # 实现各个核心方法...
步骤4: 实现一键操作GUI界面

创建 install_fiddler_cert_gui.py 文件,实现图形化一键操作界面:

代码语言:python
代码运行次数:0
运行
复制
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和事件处理方法...
步骤5: 实现一键打包功能

创建 build_exe.py 文件,实现一键打包成exe功能:

代码语言:python
代码运行次数:0
运行
复制
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
步骤6: 测试和优化
代码语言:bash
复制
# 测试命令行版本一键导入
python install_fiddler_cert.py

# 测试GUI版本一键导入
python install_fiddler_cert_gui.py

# 测试一键打包功能
python build_exe.py

优化重点:

  • 增强自动检测能力,支持更多模拟器
  • 优化错误处理,提供更友好的错误提示
  • 改进多线程处理,避免界面卡顿
  • 增加日志记录,便于问题排查

5. 项目结构

代码语言:bash
复制
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文件

6. 技术难点和解决方案

6.1 ADB路径检测

难点: 不同模拟器的ADB路径不同,需要智能检测。

解决方案: 实现多路径检测机制,支持常见模拟器路径和环境变量检测。

6.2 系统权限获取

难点: 需要root权限才能修改系统证书目录。

解决方案: 使用adb root命令获取root权限,然后重新挂载系统分区。

6.3 多方案安装

难点: 不同Android版本的系统权限和目录结构可能不同。

解决方案: 实现多种安装方案,按优先级尝试,确保兼容性。

6.4 GUI多线程

难点: 安装过程可能耗时较长,需要避免界面卡顿。

解决方案: 使用多线程处理安装过程,通过消息队列更新UI。

7. 使用说明

7.1 命令行版本 - 一键导入
代码语言:bash
复制
# 基本用法 - 自动检测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"

特点: 无需手动配置,自动检测环境,一键完成证书导入

7.2 GUI版本 - 图形化一键操作
代码语言:bash
复制
# 启动GUI
python install_fiddler_cert_gui.py

一键操作步骤:

  1. 启动程序,自动检测ADB和证书文件
  2. 确认文件路径正确(如需修改可手动选择)
  3. 点击"一键导入证书"按钮
  4. 等待自动完成导入过程
  5. 重启安卓模拟器使证书生效

优势: 操作简单,界面友好,实时显示导入进度

7.3 一键打包成EXE
代码语言:bash
复制
# 使用一键打包脚本
python build_exe.py

# 或直接使用PyInstaller
pyinstaller --name="安卓模拟器Fiddler证书导入器" --onefile --windowed --clean --noconfirm install_fiddler_cert_gui.py

打包特点:

  • 自动检测并安装依赖
  • 自动清理之前的构建文件
  • 生成独立的exe文件,无需Python环境
  • 便于分发和使用

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 安卓模拟器一键导入Fiddler证书脚本开发记录
    • 项目概述
    • 技术要点分析
      • 1. 核心功能
      • 2. 技术架构
      • 3. 关键技术实现
      • 4. 开发步骤详解
      • 5. 项目结构
      • 6. 技术难点和解决方案
      • 7. 使用说明
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档