暴力破解Excel工作表保护密码小工具

文章正文
发布时间:2025-11-19 19:59

[Python] 纯文本查看 复制代码

import win32com.client import tkinter as tk from tkinter import filedialog, ttk, messagebox import threading class ExcelPasswordCrackerGUI: def __init__(self, master): self.master = master master.title("Excel工作表密码破解工具") master.geometry("600x700") # 增加高度以确保所有元素可见 master.configure(bg='#f0f0f0') # 设置背景色 # 设置样式 style = ttk.Style() style.theme_use('default') style.configure('TButton', padding=6, relief="flat", background="#2196F3") style.configure('Horizontal.TProgressbar', troughcolor='#E0E0E0', background='#2196F3', thickness=20) self.file_path = tk.StringVar() self.sheet_index = tk.StringVar(value="0") # 主容器 main_container = tk.Frame(master, bg='#f0f0f0') main_container.pack(expand=True, fill='both', padx=20, pady=20) # 文件选择 self.file_frame = tk.LabelFrame(main_container, text="Excel文件选择", bg='#f0f0f0', fg='#333333', font=('Microsoft YaHei', 10, 'bold')) self.file_frame.pack(pady=10, padx=10, fill="x") self.file_label = tk.Label(self.file_frame, text="文件路径:", bg='#f0f0f0', fg='#333333', font=('Microsoft YaHei', 9)) self.file_label.pack(side="left", padx=5, pady=5) self.file_entry = tk.Entry(self.file_frame, textvariable=self.file_path, width=40, state="readonly") self.file_entry.pack(side="left", padx=5, pady=5, expand=True, fill="x") self.browse_button = ttk.Button(self.file_frame, text="浏览", command=self.browse_file) self.browse_button.pack(side="left", padx=5, pady=5) # 工作表序号 self.sheet_frame = tk.LabelFrame(main_container, text="工作表序号(从0开始)", bg='#f0f0f0', fg='#333333', font=('Microsoft YaHei', 10, 'bold')) self.sheet_frame.pack(pady=5, padx=10, fill="x") self.sheet_label = tk.Label(self.sheet_frame, text="工作表序号:", bg='#f0f0f0', fg='#333333', font=('Microsoft YaHei', 9)) self.sheet_label.pack(side="left", padx=5, pady=5) self.sheet_entry = tk.Entry(self.sheet_frame, textvariable=self.sheet_index, width=10) self.sheet_entry.pack(side="left", padx=5, pady=5) # 进度条 self.progress_frame = tk.LabelFrame(main_container, text="破解进度", bg='#f0f0f0', fg='#333333', font=('Microsoft YaHei', 10, 'bold')) self.progress_frame.pack(pady=5, padx=10, fill="x") self.progress_bar = ttk.Progressbar(self.progress_frame, orient="horizontal", length=300, mode="determinate") self.progress_bar.pack(pady=10, padx=5, expand=True, fill="x") self.progress_label = tk.Label(self.progress_frame, text="0%", bg='#f0f0f0', fg='#333333', font=('Microsoft YaHei', 9, 'bold')) self.progress_label.pack(pady=5) # 结果显示 self.result_frame = tk.LabelFrame(main_container, text="破解结果", bg='#f0f0f0', fg='#333333', font=('Microsoft YaHei', 10, 'bold')) self.result_frame.pack(pady=5, padx=10, fill="both", expand=True) self.result_text = tk.Text(self.result_frame, height=12, state="disabled", wrap="word", font=('Microsoft YaHei', 9), bg='white', fg='#333333') self.result_text.pack(pady=5, padx=5, expand=True, fill="both") # 添加滚动条 scrollbar = tk.Scrollbar(self.result_frame, command=self.result_text.yview) scrollbar.pack(side=tk.RIGHT, fill=tk.Y) self.result_text.config(yscrollcommand=scrollbar.set) # 破解按钮 button_frame = tk.Frame(main_container, bg='#f0f0f0') button_frame.pack(pady=10, fill='x') self.crack_button = ttk.Button(button_frame, text="开始破解", command=self.start_cracking_thread,) self.crack_button.pack(pady=10, ipadx=20) def browse_file(self): filetypes = [("Excel文件", "*.xls *.xlsx"), ("所有文件", "*.*")] path = filedialog.askopenfilename(filetypes=filetypes) if path: self.file_path.set(path) self.update_result("已选择文件: " + path) def update_result(self, message, append=True): self.result_text.config(state="normal") if not append: self.result_text.delete(1.0, tk.END) self.result_text.insert(tk.END, message + "\n") self.result_text.see(tk.END) self.result_text.config(state="disabled") def update_progress(self, value, total): percent = (value / total) * 100 self.progress_bar['value'] = percent self.progress_label.config(text=f"{percent:.2f}%") self.master.update_idletasks() def start_cracking_thread(self): file_path = self.file_path.get() sheet_index_str = self.sheet_index.get() if not file_path: messagebox.showerror("错误", "请选择Excel文件。") return try: sheet_index = int(sheet_index_str) if sheet_index < 0: raise ValueError except ValueError: messagebox.showerror("错误", "请输入有效的工作表序号(非负整数)。") return self.update_result("正在开始破解过程...", append=False) self.crack_button.config(state="disabled") self.progress_bar['value'] = 0 self.progress_label.config(text="0%") # 在单独的线程中运行破解过程以保持GUI响应 cracking_thread = threading.Thread(target=self.crack_excel_password, args=(file_path, sheet_index)) cracking_thread.start() def crack_excel_password(self, file_path, sheet_index): ProtectPass = [] # 生成密码组合(与原始脚本相同的逻辑) a = [] b = [] c = [] for i in range(2048): a.append(list('{:011b}'.format(i))) for i in a: for j in i: b.append(int(j) + 65) c.append(b) b = [] for k in c: m = list(k) m.append(0) for n in range(32, 127): m[len(m) - 1] = n list2 = [chr(i) for i in m] s = ''.join(list2) ProtectPass.append(s) total_passwords = len(ProtectPass) self.progress_bar['maximum'] = 100 try: xlsx = win32com.client.Dispatch('Excel.Application') xlsx.Visible = False wb = xlsx.Workbooks.Open(file_path, False, False, None, Password="") # Check if the sheet index is valid if sheet_index + 1 > wb.Sheets.Count or sheet_index + 1 <= 0: raise IndexError(f"工作表序号 {sheet_index} 超出范围。文件只有 {wb.Sheets.Count} 个工作表。") # 在win32com中,Excel工作表索引从1开始 ws = wb.Sheets(sheet_index + 1) self.master.after(0, lambda: self.update_result( "开始破解工作表保护密码...\n" + f"总共需要尝试 {total_passwords} 个密码组合\n" + "=" * 50, append=False)) found_password = None for idx, EditPass in enumerate(ProtectPass): try: # 尝试使用当前密码解锁工作表保护 ws.Unprotect(EditPass) # 如果没有抛出异常,说明密码正确 found_password = EditPass # 更新进度条到100% self.master.after(0, self.update_progress, total_passwords, total_passwords) self.master.after(0, lambda: self.update_result( "\n密码破解成功!\n" + f"当前尝试:第 {idx+1}/{total_passwords} 个密码\n" + f"成功破解密码:{EditPass}\n" + "=" * 50, append=True)) break except Exception as e: # 密码错误或其他问题 if (idx + 1) % 500 == 0: # 每500次显示一次进度 current_percent = (idx + 1) / total_passwords * 100 self.master.after(0, lambda i=idx, p=current_percent: self.update_result( f"\n当前进度:{p:.2f}%\n" + f"正在尝试第 {i+1}/{total_passwords} 个密码组合...\n", append=True)) finally: # 更新进度条 if (idx + 1) % 100 == 0 or (idx + 1) == total_passwords: self.master.after(0, self.update_progress, idx + 1, total_passwords) if found_password: self.master.after(0, lambda: self.update_result( "\n破解完成!\n" + f"成功找到密码:{found_password}\n" + "=" * 50, append=True)) messagebox.showinfo("成功", f"找到密码: {found_password}") else: self.master.after(0, lambda: self.update_result( "\n破解结束\n" + f"已尝试所有 {total_passwords} 个可能的密码组合\n" + "未能找到正确的密码\n" + "=" * 50, append=True)) messagebox.showerror("失败", "无法找到密码。") except Exception as e: self.master.after(0, lambda: self.update_result(f"错误: {e}", append=False)) messagebox.showerror("错误", f"发生错误: {e}") finally: self.crack_button.config(state="normal") try: if 'wb' in locals() and wb: wb.Close(SaveChanges=False) if 'xlsx' in locals() and xlsx: xlsx.Quit() except Exception as e: print(f"关闭Excel时发生错误: {e}") root = tk.Tk() app = ExcelPasswordCrackerGUI(root) root.mainloop()