使用file_column生成uuid图片名称

import tkinter as tk from tkinter import ttk, filedialog, messagebox, scrolledtext import random import string import hashlib import os import base64 import time import winreg import shutil import datetime import ctypes import uuid # 添加uuid模块用于生成唯一ID class DLLProtectorApp: def __init__(self, root): self.root = root self.root.title("DLL保护工具 - 加密、混淆与授权激活系统") self.root.geometry("1000x800") self.root.configure(bg='#2c3e50') # 创建标签页 self.tab_control = ttk.Notebook(root) # 加密标签页 self.encrypt_tab = ttk.Frame(self.tab_control) self.tab_control.add(self.encrypt_tab, text='DLL加密') # 混淆标签页 self.obfuscate_tab = ttk.Frame(self.tab_control) self.tab_control.add(self.obfuscate_tab, text='代码混淆') # 授权标签页 self.license_tab = ttk.Frame(self.tab_control) self.tab_control.add(self.license_tab, text='授权管理') self.tab_control.pack(expand=1, fill="both", padx=10, pady=10) # 初始化UI self.create_encrypt_tab() self.create_obfuscate_tab() self.create_license_tab() # 初始化状态变量 self.encrypt_files = [] self.obfuscate_files = [] self.license_key = "" self.activation_date = None # 激活时间 self.expiry_date = None # 到期时间 self.usage_count = 0 # 功能使用次数计数器 self.max_usage_count = 0 # 最大使用次数 self.time_limit_days = 0 # 时间限制天数 self.permanent_license_shown = False # 标记永久授权是否已显示 self.machine_id = self.generate_unique_id() # 生成唯一ID号用于所有嵌入授权的DLL文件 # 创建状态栏 self.status_var = tk.StringVar() self.status_var.set("就绪") self.status_bar = tk.Label(root, textvariable=self.status_var, bd=1, relief=tk.SUNKEN, anchor=tk.W, bg='#34495e', fg='white') self.status_bar.pack(side=tk.BOTTOM, fill=tk.X) def generate_unique_id(self): """生成唯一ID号用于所有嵌入授权的DLL文件""" return str(uuid.uuid4()).replace("-", "")[:16].upper() def create_encrypt_tab(self): tab = self.encrypt_tab # 标题 title = tk.Label(tab, text="DLL文件加密", font=("Arial", 16, "bold"), bg='#2c3e50', fg='#ecf0f1') title.pack(pady=15) # 文件选择区域 - 支持多文件选择 file_frame = tk.LabelFrame(tab, text="选择DLL文件 (可多选)", bg='#2c3e50', fg='#ecf0f1') file_frame.pack(fill=tk.X, padx=20, pady=10) # 使用ScrolledText显示选中的文件列表 self.encrypt_file_listbox = scrolledtext.ScrolledText(file_frame, height=5, bg='#34495e', fg='#ecf0f1', insertbackground='white') self.encrypt_file_listbox.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) self.encrypt_file_listbox.config(state=tk.DISABLED) # 文件操作按钮 btn_frame = tk.Frame(file_frame, bg='#2c3e50') btn_frame.pack(fill=tk.X, pady=5) browse_btn = tk.Button(btn_frame, text="添加文件...", command=self.browse_encrypt_files, bg='#3498db', fg='white') browse_btn.pack(side=tk.LEFT, padx=5) clear_btn = tk.Button(btn_frame, text="清空列表", command=self.clear_encrypt_file_list, bg='#e74c3c', fg='white') clear_btn.pack(side=tk.LEFT, padx=5) # 加密选项区域 options_frame = tk.LabelFrame(tab, text="加密选项", bg='#2c3e50', fg='#ecf0f1') options_frame.pack(fill=tk.X, padx=20, pady=10) tk.Label(options_frame, text="加密强度:", bg='#2c3e50', fg='#ecf0f1').grid(row=0, column=0, padx=5, pady=5, sticky=tk.W) self.encryption_level = tk.StringVar(value="AES-256") levels = ["AES-128", "AES-192", "AES-256", "Blowfish", "Twofish"] level_menu = ttk.Combobox(options_frame, textvariable=self.encryption_level, values=levels, state="readonly", width=15) level_menu.grid(row=0, column=1, padx=5, pady=5, sticky=tk.W) tk.Label(options_frame, text="输出目录:", bg='#2c3e50', fg='#ecf0f1').grid(row=1, column=0, padx=5, pady=5, sticky=tk.W) self.encrypt_output_dir = tk.StringVar(value=os.path.join(os.path.expanduser("~"), "encrypted")) output_entry = tk.Entry(options_frame, textvariable=self.encrypt_output_dir, width=50) output_entry.grid(row=1, column=1, padx=5, pady=5, sticky=tk.W) browse_dir_btn = tk.Button(options_frame, text="浏览...", command=self.browse_encrypt_output_dir, bg='#3498db', fg='white') browse_dir_btn.grid(row=1, column=2, padx=5, pady=5) # 加密按钮 encrypt_btn = tk.Button(tab, text="批量加密文件", command=self.encrypt_files, bg='#2ecc71', fg='white', font=("Arial", 12), height=2, width=20) encrypt_btn.pack(pady=20) # 状态显示 self.encrypt_status = tk.Label(tab, text="", bg='#2c3e50', fg='#e74c3c') self.encrypt_status.pack(pady=10) def create_obfuscate_tab(self): tab = self.obfuscate_tab # 标题 title = tk.Label(tab, text="代码混淆", font=("Arial", 16, "bold"), bg='#2c3e50', fg='#ecf0f1') title.pack(pady=15) # 文件选择区域 - 支持多文件选择 file_frame = tk.LabelFrame(tab, text="选择DLL文件 (可多选)", bg='#2c3e50', fg='#ecf0f1') file_frame.pack(fill=tk.X, padx=20, pady=10) # 使用ScrolledText显示选中的文件列表 self.obfuscate_file_listbox = scrolledtext.ScrolledText(file_frame, height=5, bg='#34495e', fg='#ecf0f1', insertbackground='white') self.obfuscate_file_listbox.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) self.obfuscate_file_listbox.config(state=tk.DISABLED) # 文件操作按钮 btn_frame = tk.Frame(file_frame, bg='#2c3e50') btn_frame.pack(fill=tk.X, pady=5) browse_btn = tk.Button(btn_frame, text="添加文件...", command=self.browse_obfuscate_files, bg='#3498db', fg='white') browse_btn.pack(side=tk.LEFT, padx=5) clear_btn = tk.Button(btn_frame, text="清空列表", command=self.clear_obfuscate_file_list, bg='#e74c3c', fg='white') clear_btn.pack(side=tk.LEFT, padx=5) # 混淆选项 options_frame = tk.LabelFrame(tab, text="混淆设置", bg='#2c3e50', fg='#ecf0f1') options_frame.pack(fill=tk.X, padx=20, pady=10) # 混淆方法 tk.Label(options_frame, text="混淆方法:", bg='#2c3e50', fg='#ecf0f1').grid(row=0, column=0, padx=5, pady=5, sticky=tk.W) self.obf_method = tk.StringVar(value="名称混淆") methods = ["名称混淆", "控制流混淆", "字符串加密", "指令替换", "全混淆模式"] method_menu = ttk.Combobox(options_frame, textvariable=self.obf_method, values=methods, state="readonly", width=15) method_menu.grid(row=0, column=1, padx=5, pady=5, sticky=tk.W) method_menu.bind("<<ComboboxSelected>>", self.update_preview) # 混淆强度 tk.Label(options_frame, text="混淆强度:", bg='#2c3e50', fg='#ecf0f1').grid(row=1, column=0, padx=5, pady=5, sticky=tk.W) self.obf_strength = tk.IntVar(value=5) strength_scale = tk.Scale(options_frame, variable=self.obf_strength, from_=1, to=10, orient=tk.HORIZONTAL, bg='#2c3e50', fg='#ecf0f1', highlightbackground='#2c3e50', command=lambda e: self.update_preview()) strength_scale.grid(row=1, column=1, padx=5, pady=5, sticky=tk.W) # 输出目录 tk.Label(options_frame, text="输出目录:", bg='#2c3e50', fg='#ecf0f1').grid(row=2, column=0, padx=5, pady=5, sticky=tk.W) self.obfuscate_output_dir = tk.StringVar(value=os.path.join(os.path.expanduser("~"), "obfuscated")) output_entry = tk.Entry(options_frame, textvariable=self.obfuscate_output_dir, width=50) output_entry.grid(row=2, column=1, padx=5, pady=5, sticky=tk.W) browse_dir_btn = tk.Button(options_frame, text="浏览...", command=self.browse_obfuscate_output_dir, bg='#3498db', fg='white') browse_dir_btn.grid(row=2, column=2, padx=5, pady=5) # 混淆按钮 obfuscate_btn = tk.Button(tab, text="批量混淆文件", command=self.obfuscate_files, bg='#9b59b6', fg='white', font=("Arial", 12), height=2, width=20) obfuscate_btn.pack(pady=20) # 混淆预览 preview_frame = tk.LabelFrame(tab, text="混淆预览", bg='#2c3e50', fg='#ecf0f1') preview_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=10) self.preview_text = tk.Text(preview_frame, height=10, bg='#34495e', fg='#ecf0f1', insertbackground='white') self.preview_text.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) # 设置初始预览 self.update_preview() def create_license_tab(self): tab = self.license_tab # 标题 title = tk.Label(tab, text="授权管理系统", font=("Arial", 16, "bold"), bg='#2c3e50', fg='#ecf0f1') title.pack(pady=15) # 授权信息区域 info_frame = tk.LabelFrame(tab, text="授权信息", bg='#2c3e50', fg='#ecf0f1') info_frame.pack(fill=tk.X, padx=20, pady=10) tk.Label(info_frame, text="授权密钥:", bg='#2c3e50', fg='#ecf0f1').grid(row=0, column=0, padx=5, pady=5, sticky=tk.W) self.license_entry = tk.Entry(info_frame, width=50) self.license_entry.grid(row=0, column=1, padx=5, pady=5, sticky=tk.W) generate_btn = tk.Button(info_frame, text="生成密钥", command=self.generate_license, bg='#3498db', fg='white') generate_btn.grid(row=0, column=2, padx=5, pady=5) # 机器码显示 tk.Label(info_frame, text="机器码:", bg='#2c3e50', fg='#ecf0f1').grid(row=1, column=0, padx=5, pady=5, sticky=tk.W) self.machine_id_var = tk.StringVar() self.machine_id_var.set(self.machine_id) # 显示生成的唯一ID machine_entry = tk.Entry(info_frame, textvariable=self.machine_id_var, width=50, state='readonly', fg='#3498db') machine_entry.grid(row=1, column=1, padx=5, pady=5, sticky=tk.W) # 添加复制机器码按钮 copy_machine_id_btn = tk.Button(info_frame, text="复制机器码", command=self.copy_machine_id, bg='#9b59b6', fg='white') copy_machine_id_btn.grid(row=1, column=2, padx=5, pady=5) tk.Label(info_frame, text="授权类型:", bg='#2c3e50', fg='#ecf0f1').grid(row=2, column=0, padx=5, pady=5, sticky=tk.W) self.license_type = tk.StringVar(value="永久") license_frame = tk.Frame(info_frame, bg='#2c3e50') license_frame.grid(row=2, column=1, padx=5, pady=5, sticky=tk.W) # 永久授权单选按钮 permanent_radio = tk.Radiobutton(license_frame, text="永久授权", variable=self.license_type, value="永久", bg='#2c3e50', fg='#ecf0f1', selectcolor='#34495e') permanent_radio.pack(side=tk.LEFT, padx=10) # 试用期单选按钮 trial_radio = tk.Radiobutton(license_frame, text="试用期", variable=self.license_type, value="试用期", bg='#2c3e50', fg='#ecf0f1', selectcolor='#34495e') trial_radio.pack(side=tk.LEFT, padx=10) # 试用期天数输入框 self.trial_days = tk.StringVar(value="3") self.trial_days_entry = tk.Entry(license_frame, textvariable=self.trial_days, width=5, state=tk.NORMAL) self.trial_days_entry.pack(side=tk.LEFT, padx=5) # 添加天数标签 tk.Label(license_frame, text="天", bg='#2c3e50', fg='#ecf0f1').pack(side=tk.LEFT) # 绑定授权类型改变事件 self.license_type.trace_add("write", self.update_license_type_ui) # 授权功能区域 func_frame = tk.LabelFrame(tab, text="授权功能", bg='#2c3e50', fg='#ecf0f1') func_frame.pack(fill=tk.X, padx=20, pady=10) bind_btn = tk.Button(func_frame, text="绑定机器", command=self.bind_to_machine, bg='#e67e22', fg='white', width=15) bind_btn.grid(row=0, column=0, padx=10, pady=10) embed_btn = tk.Button(func_frame, text="嵌入授权", command=self.embed_license, bg='#1abc9c', fg='white', width=15) embed_btn.grid(row=0, column=1, padx=10, pady=10) check_btn = tk.Button(func_frame, text="检查授权", command=self.check_license, bg='#f1c40f', fg='white', width=15) check_btn.grid(row=0, column=2, padx=10, pady=10) # 授权日志 log_frame = tk.LabelFrame(tab, text="授权日志", bg='#2c3e50', fg='#ecf0f1') log_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=10) self.log_text = tk.Text(log_frame, height=10, bg='#34495e', fg='#ecf0f1', insertbackground='white') self.log_text.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) self.log_text.insert(tk.END, "系统启动...\n") self.log_text.insert(tk.END, "就绪\n") self.log_text.config(state=tk.DISABLED) def copy_machine_id(self): """复制机器码到剪贴板""" self.root.clipboard_clear() self.root.clipboard_append(self.machine_id) self.status_var.set("机器码已复制到剪贴板") self.log_action("机器码已复制到剪贴板") def browse_encrypt_files(self): file_paths = filedialog.askopenfilenames( title="选择DLL文件", filetypes=[("DLL Files", "*.dll"), ("All Files", "*.*")] ) if file_paths: self.encrypt_files = list(file_paths) self.update_encrypt_file_list() self.status_var.set(f"已添加 {len(file_paths)} 个加密文件") self.log_action(f"已添加 {len(file_paths)} 个加密文件") def browse_obfuscate_files(self): file_paths = filedialog.askopenfilenames( title="选择DLL文件", filetypes=[("DLL Files", "*.dll"), ("All Files", "*.*")] ) if file_paths: self.obfuscate_files = list(file_paths) self.update_obfuscate_file_list() self.status_var.set(f"已添加 {len(file_paths)} 个混淆文件") self.log_action(f"已添加 {len(file_paths)} 个混淆文件") def browse_encrypt_output_dir(self): dir_path = filedialog.askdirectory(title="选择输出目录") if dir_path: self.encrypt_output_dir.set(dir_path) self.log_action(f"设置加密输出目录: {dir_path}") def browse_obfuscate_output_dir(self): dir_path = filedialog.askdirectory(title="选择输出目录") if dir_path: self.obfuscate_output_dir.set(dir_path) self.log_action(f"设置混淆输出目录: {dir_path}") def clear_encrypt_file_list(self): self.encrypt_files = [] self.update_encrypt_file_list() self.status_var.set("加密文件列表已清空") self.log_action("加密文件列表已清空") def clear_obfuscate_file_list(self): self.obfuscate_files = [] self.update_obfuscate_file_list() self.status_var.set("混淆文件列表已清空") self.log_action("混淆文件列表已清空") def update_encrypt_file_list(self): self.encrypt_file_listbox.config(state=tk.NORMAL) self.encrypt_file_listbox.delete(1.0, tk.END) if self.encrypt_files: for i, file_path in enumerate(self.encrypt_files, 1): self.encrypt_file_listbox.insert(tk.END, f"{i}. {file_path}\n") else: self.encrypt_file_listbox.insert(tk.END, "没有选择文件\n") self.encrypt_file_listbox.insert(tk.END, "请点击'添加文件'按钮选择DLL文件") self.encrypt_file_listbox.config(state=tk.DISABLED) def update_obfuscate_file_list(self): self.obfuscate_file_listbox.config(state=tk.NORMAL) self.obfuscate_file_listbox.delete(1.0, tk.END) if self.obfuscate_files: for i, file_path in enumerate(self.obfuscate_files, 1): self.obfuscate_file_listbox.insert(tk.END, f"{i}. {file_path}\n") else: self.obfuscate_file_listbox.insert(tk.END, "没有选择文件\n") self.obfuscate_file_listbox.insert(tk.END, "请点击'添加文件'按钮选择DLL文件") self.obfuscate_file_listbox.config(state=tk.DISABLED) def simple_aes_encrypt(self, data, key): """简单的AES加密实现""" key_hash = hashlib.sha256(key).digest() iv = os.urandom(16) cipher = hashlib.pbkdf2_hmac('sha256', key_hash, iv, 100000, dklen=32) encrypted = bytearray() for i in range(len(data)): encrypted.append(data[i] ^ cipher[i % len(cipher)]) return iv + bytes(encrypted) def encrypt_files(self): if not self.encrypt_files: messagebox.showerror("错误", "请先选择至少一个DLL文件") self.log_action("加密失败: 未选择文件") return output_dir = self.encrypt_output_dir.get() if not output_dir: messagebox.showerror("错误", "请指定输出目录") self.log_action("加密失败: 未指定输出目录") return # 确保输出目录存在 if not os.path.exists(output_dir): os.makedirs(output_dir) try: # 创建加密子目录 encrypted_dir = os.path.join(output_dir, "encrypted") if not os.path.exists(encrypted_dir): os.makedirs(encrypted_dir) encryption_method = self.encryption_level.get() success_count = 0 self.encrypt_status.config(text="批量加密中...", fg='#f39c12') self.log_action(f"开始批量加密文件 ({encryption_method})") self.root.update() for file_path in self.encrypt_files: try: # 获取原文件名 base_name = os.path.basename(file_path) # 生成输出路径 (在encrypted子目录下,使用原文件名) output_path = os.path.join(encrypted_dir, base_name) # 生成加密密钥 key = os.urandom(32) # 读取文件内容 with open(file_path, 'rb') as f: data = f.read() # 加密数据 encrypted_data = self.simple_aes_encrypt(data, key) # 保存加密后的文件 with open(output_path, 'wb') as f: f.write(encrypted_data) # 保存密钥 key_file = os.path.join(encrypted_dir, f"{base_name}.key") with open(key_file, 'wb') as f: f.write(key) success_count += 1 self.log_action(f"已加密: {base_name} -> {output_path}") self.log_action(f"密钥已保存: {os.path.basename(key_file)}") except Exception as e: self.log_action(f"加密失败 {os.path.basename(file_path)}: {str(e)}") self.encrypt_status.config( text=f"批量加密完成!成功: {success_count}/{len(self.encrypt_files)} 个文件", fg='#2ecc71' if success_count > 0 else '#e74c3c' ) self.status_var.set( f"批量加密完成 - 成功: {success_count}/{len(self.encrypt_files)}" ) self.log_action(f"批量加密完成! 成功: {success_count}/{len(self.encrypt_files)}") if success_count > 0: messagebox.showinfo( "批量加密完成", f"成功加密 {success_count} 个文件\n输出目录: {encrypted_dir}" ) else: messagebox.showerror( "加密失败", "所有文件加密失败,请查看日志" ) except Exception as e: messagebox.showerror("加密错误", str(e)) self.encrypt_status.config(text="批量加密失败", fg='#e74c3c') self.log_action(f"批量加密失败: {str(e)}") def update_preview(self, event=None): """根据混淆设置更新预览""" method = self.obf_method.get() strength = self.obf_strength.get() self.preview_text.config(state=tk.NORMAL) self.preview_text.delete(1.0, tk.END) # 原始代码示例 self.preview_text.insert(tk.END, "// 原始代码示例\n") self.preview_text.insert(tk.END, "public int Calculate(int a, int b) {\n") self.preview_text.insert(tk.END, " return a * b + 10;\n") self.preview_text.insert(tk.END, "}\n\n") # 混淆后代码示例 self.preview_text.insert(tk.END, f"// 混淆后代码示例 ({method}, 强度: {strength}/10)\n") # 根据混淆方法和强度生成不同的混淆代码 if method == "名称混淆": self.preview_text.insert(tk.END, f"public int {self.generate_obf_name('Calculate', strength)}(int {self.generate_obf_name('a', strength)}, int {self.generate_obf_name('b', strength)}) {{\n") self.preview_text.insert(tk.END, f" return {self.generate_obf_name('a', strength)} * {self.generate_obf_name('b', strength)} + 10;\n") self.preview_text.insert(tk.END, "}\n") elif method == "控制流混淆": self.preview_text.insert(tk.END, "public int Calculate(int a, int b) {\n") self.preview_text.insert(tk.END, " int result;\n") self.preview_text.insert(tk.END, " if (a > 0) {\n") if strength > 5: self.preview_text.insert(tk.END, " int temp = b;\n") self.preview_text.insert(tk.END, " for (int i = 0; i < 1; i++) {\n") self.preview_text.insert(tk.END, " temp = a * temp;\n") self.preview_text.insert(tk.END, " }\n") self.preview_text.insert(tk.END, " result = temp + 10;\n") else: self.preview_text.insert(tk.END, " result = a * b + 10;\n") self.preview_text.insert(tk.END, " } else {\n") self.preview_text.insert(tk.END, " result = b * a + 10;\n") self.preview_text.insert(tk.END, " }\n") self.preview_text.insert(tk.END, " return result;\n") self.preview_text.insert(tk.END, "}\n") elif method == "字符串加密": self.preview_text.insert(tk.END, "public int Calculate(int a, int b) {\n") self.preview_text.insert(tk.END, " // 字符串被加密\n") self.preview_text.insert(tk.END, " string debugInfo = DecryptString(\"0x4A3F2B1C\");\n") self.preview_text.insert(tk.END, " return a * b + 10;\n") self.preview_text.insert(tk.END, "}\n") elif method == "指令替换": self.preview_text.insert(tk.END, "public int Calculate(int a, int b) {\n") self.preview_text.insert(tk.END, " // 指令被替换\n") if strength > 7: self.preview_text.insert(tk.END, " int result = (a << 2) - a + b * 3 + 10;\n") else: self.preview_text.insert(tk.END, " int result = a * b + 10;\n") self.preview_text.insert(tk.END, " return result;\n") self.preview_text.insert(tk.END, "}\n") else: # 全混淆模式 self.preview_text.insert(tk.END, f"public int {self.generate_obf_name('Calculate', strength)}(int {self.generate_obf_name('a', strength)}, int {self.generate_obf_name('b', strength)}) {{\n") self.preview_text.insert(tk.END, " // 全混淆模式\n") self.preview_text.insert(tk.END, " int result;\n") self.preview_text.insert(tk.END, " if (a > 0) {\n") self.preview_text.insert(tk.END, " result = a * b + 10;\n") self.preview_text.insert(tk.END, " } else {\n") self.preview_text.insert(tk.END, " result = b * a + 10;\n") self.preview_text.insert(tk.END, " }\n") self.preview_text.insert(tk.END, " // 添加垃圾指令\n") self.preview_text.insert(tk.END, " int unused = 0;\n") self.preview_text.insert(tk.END, " for (int i = 0; i < 10; i++) {\n") self.preview_text.insert(tk.END, " unused += i;\n") self.preview_text.insert(tk.END, " }\n") self.preview_text.insert(tk.END, " return result;\n") self.preview_text.insert(tk.END, "}\n") self.preview_text.config(state=tk.DISABLED) def generate_obf_name(self, base_name, strength): """生成混淆后的名称""" # 根据混淆强度增加名称的复杂度 prefix = "obf_" if strength < 5 else "mangled_" suffix = f"_{random.randint(100, 999)}" if strength > 3 else "" # 高混淆强度使用随机字符串 if strength > 7: return ''.join(random.choices(string.ascii_letters, k=8)) return f"{prefix}{base_name}{suffix}" def obfuscate_files(self): if not self.obfuscate_files: messagebox.showerror("错误", "请先选择至少一个DLL文件") self.log_action("混淆失败: 未选择文件") return output_dir = self.obfuscate_output_dir.get() if not output_dir: messagebox.showerror("错误", "请指定输出目录") self.log_action("混淆失败: 未指定输出目录") return # 确保输出目录存在 if not os.path.exists(output_dir): os.makedirs(output_dir) try: # 获取混淆设置 method = self.obf_method.get() strength = self.obf_strength.get() success_count = 0 self.log_action(f"开始批量混淆文件 (方法: {method}, 强度: {strength}/10)") # 创建结果显示窗口 result_window = tk.Toplevel(self.root) result_window.title("混淆处理结果") result_window.geometry("400x300") result_window.resizable(False, False) result_window.transient(self.root) result_window.grab_set() # 创建结果显示文本区域 result_frame = tk.Frame(result_window) result_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10) result_label = tk.Label(result_frame, text="批量混淆完成", font=("Arial", 14, "bold")) result_label.pack(pady=10) result_text = scrolledtext.ScrolledText(result_frame, height=10) result_text.pack(fill=tk.BOTH, expand=True) # 添加处理结果 result_text.insert(tk.END, f"成功处理: 0/{len(self.obfuscate_files)} 个文件\n") result_text.insert(tk.END, "------------------------------------\n") result_text.see(tk.END) result_text.config(state=tk.DISABLED) # 处理文件 for idx, file_path in enumerate(self.obfuscate_files): try: # 获取原文件名 base_name = os.path.basename(file_path) # 生成输出路径 (使用原文件名) output_path = os.path.join(output_dir, base_name) # 模拟混淆过程 self.log_action(f"开始混淆: {base_name}") self.log_action(f"混淆方法: {method}, 强度: {strength}/10") # 这里应该是实际的混淆代码 # 为了演示,我们只是复制文件并添加日志 shutil.copy(file_path, output_path) self.log_action(f"混淆完成! 输出文件: {output_path}") success_count += 1 # 更新结果窗口 result_text.config(state=tk.NORMAL) result_text.insert(tk.END, f"成功: {base_name}\n") result_text.see(tk.END) result_text.config(state=tk.DISABLED) result_text.update() except Exception as e: self.log_action(f"混淆失败 {base_name}: {str(e)}") # 更新结果窗口 result_text.config(state=tk.NORMAL) result_text.insert(tk.END, f"失败: {base_name} - {str(e)}\n") result_text.see(tk.END) result_text.config(state=tk.DISABLED) result_text.update() # 更新结果标题 result_label.config(text=f"批量混淆完成! 成功: {success_count}/{len(self.obfuscate_files)}") # 添加确定按钮 ok_btn = tk.Button(result_window, text="确定", width=10, command=result_window.destroy) ok_btn.pack(pady=10) self.status_var.set(f"混淆完成: {success_count}/{len(self.obfuscate_files)}") self.log_action(f"批量混淆完成! 成功处理 {success_count}/{len(self.obfuscate_files)} 个文件") except Exception as e: messagebox.showerror("混淆错误", str(e)) self.log_action(f"批量混淆失败: {str(e)}") def generate_license(self): key = ''.join(random.choices(string.ascii_uppercase + string.digits, k=25)) key = '-'.join([key[i:i+5] for i in range(0, len(key), 5)]) self.license_key = key self.license_entry.delete(0, tk.END) self.license_entry.insert(0, key) self.activation_date = time.time() license_type = self.license_type.get() self.log_action(f"已生成{license_type}授权密钥: {key}") def update_license_type_ui(self, *args): """根据选择的授权类型更新UI""" license_type = self.license_type.get() if license_type == "试用期": self.trial_days_entry.config(state=tk.NORMAL) else: self.trial_days_entry.config(state=tk.NORMAL) def bind_to_machine(self): if not self.license_key: messagebox.showerror("错误", "请先生成授权密钥") return license_type = self.license_type.get() self.activation_date = time.time() # 重置使用次数 self.usage_count = 0 # 获取授权设置 if license_type == "试用期": try: self.time_limit_days = int(self.trial_days.get()) if self.time_limit_days < 1: messagebox.showerror("错误", "试用期天数必须大于0") return self.expiry_date = self.activation_date + self.time_limit_days * 24 * 3600 except: messagebox.showerror("错误", "请输入有效的试用期天数") return else: # 永久授权 self.expiry_date = None self.time_limit_days = 0 self.permanent_license_shown = False # 重置永久授权显示标记 self.log_action(f"授权密钥已绑定到机器: {self.machine_id}") self.log_action(f"授权类型: {license_type}") if license_type == "试用期": expiry_date_str = time.strftime("%Y-%m-%d %H:%M", time.localtime(self.expiry_date)) message = f"试用期授权已绑定\n机器码: {self.machine_id}\n激活时间: {time.strftime('%Y-%m-%d %H:%M', time.localtime(self.activation_date))}\n到期时间: {expiry_date_str}\n有效期: {self.time_limit_days}天" else: message = f"永久授权已绑定\n机器码: {self.machine_id}\n激活时间: {time.strftime('%Y-%m-%d %H:%M', time.localtime(self.activation_date))}" messagebox.showinfo("成功", message) def generate_license_module(self, output_dir): """生成授权检查模块的Python代码""" license_code = f'''# -*- coding: utf-8 -*- import ctypes import os import sys import time import hashlib import winreg class LicenseManager: def __init__(self): self.license_key = "{self.license_key}" self.machine_id = "{self.machine_id}" self.license_type = "{self.license_type.get()}" self.activation_date = {self.activation_date} self.expiry_date = {self.expiry_date if self.expiry_date else 'None'} # CAD运行时自动检查授权 self.check_license_on_cad_start() def get_current_machine_id(self): """获取当前机器标识符""" try: key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\\\\Microsoft\\\\Cryptography") machine_guid, _ = winreg.QueryValueEx(key, "MachineGuid") winreg.CloseKey(key) return hashlib.sha256(machine_guid.encode()).hexdigest()[:16].upper() except Exception: return hashlib.sha256(b"fallback_machine_id").hexdigest()[:16].upper() def check_license_on_cad_start(self): """CAD启动时自动检查授权""" current_machine_id = self.get_current_machine_id() # 检查机器码是否匹配 if current_machine_id != self.machine_id: self.show_message("授权错误", "机器码不匹配!\\n当前机器: " + current_machine_id) return False # 检查试用期是否过期 if self.license_type == "试用期": current_time = time.time() if current_time > self.expiry_date: self.show_message("授权过期", "试用期已结束!") return False # 显示授权信息 self.show_license_info() return True def show_license_info(self): """显示授权信息""" if self.license_type == "试用期": # 计算剩余时间 current_time = time.time() remaining_seconds = self.expiry_date - current_time remaining_days = int(remaining_seconds // (24 * 3600)) remaining_seconds %= (24 * 3600) remaining_hours = int(remaining_seconds // 3600) remaining_seconds %= 3600 remaining_minutes = int(remaining_seconds // 60) message = ( "试用期授权已激活\\n" f"机器码: {self.machine_id}\\n" f"激活时间: {time.strftime('%Y-%m-%d %H:%M', time.localtime(self.activation_date))}\\n" f"到期时间: {time.strftime('%Y-%m-%d %H:%M', time.localtime(self.expiry_date))}\\n" f"剩余时间: {remaining_days}天 {remaining_hours}小时 {remaining_minutes}分钟" ) self.show_message("授权信息", message) else: message = ( "永久授权已激活\\n" f"机器码: {self.machine_id}\\n" f"激活时间: {time.strftime('%Y-%m-%d %H:%M', time.localtime(self.activation_date))}" ) self.show_message("授权信息", message) def show_message(self, title, message): """在CAD中显示消息框""" # 使用ctypes创建Windows消息框 ctypes.windll.user32.MessageBoxW(0, message, title, 0) # CAD加载时自动执行 if __name__ == "__main__": license_mgr = LicenseManager() ''' # 保存授权模块 license_path = os.path.join(output_dir, "dll_license_checker.py") with open(license_path, 'w', encoding='utf-8') as f: f.write(license_code) return license_path def embed_license(self): if not self.license_key: messagebox.showerror("错误", "请先生成授权密钥") return if not self.obfuscate_files: messagebox.showerror("错误", "请先选择要嵌入授权的DLL文件") return try: # 获取输出目录 output_dir = self.obfuscate_output_dir.get() if not output_dir: messagebox.showerror("错误", "请指定输出目录") return # 确保输出目录存在 if not os.path.exists(output_dir): os.makedirs(output_dir) # 生成授权检查模块 license_module_path = self.generate_license_module(output_dir) # 初始化剩余天数 remaining_days = 0 # 模拟嵌入授权信息 license_type = self.license_type.get() self.log_action("正在将授权信息嵌入DLL...") self.log_action(f"授权模块已生成: {os.path.basename(license_module_path)}") self.log_action(f"使用的唯一ID号: {self.machine_id}") # 在试用期情况下,正确计算剩余天数 if license_type == "试用期": # 确保有到期时间 if self.expiry_date is None: self.log_action("错误:试用期授权,但到期时间为空!") messagebox.showerror("错误", "试用期授权,但到期时间为空!") return # 计算剩余时间 current_time = time.time() remaining_seconds = self.expiry_date - current_time # 如果剩余秒数小于0,则按0处理 if remaining_seconds < 0: remaining_seconds = 0 # 计算剩余天数 remaining_days = int(remaining_seconds // (24 * 3600)) self.log_action(f"授权类型: {license_type}, 天数: {self.time_limit_days}, 剩余天数: {remaining_days}") else: self.log_action(f"授权类型: {license_type}") if self.activation_date: activation_time = time.strftime('%Y-%m-%d %H:%M', time.localtime(self.activation_date)) self.log_action(f"激活时间: {activation_time}") # 为每个文件嵌入授权信息 for file_path in self.obfuscate_files: base_name = os.path.basename(file_path) # 在实际应用中,这里应该修改DLL文件嵌入授权信息 # 为演示目的,我们创建一个同名的.lic文件 lic_file = os.path.join(output_dir, f"{base_name}.lic") with open(lic_file, 'w') as f: f.write(f"LicenseKey: {self.license_key}\n") f.write(f"MachineID: {self.machine_id}\n") f.write(f"Type: {license_type}\n") f.write(f"Activation: {self.activation_date}\n") if self.expiry_date: f.write(f"Expiry: {self.expiry_date}\n") self.log_action(f"已为 {base_name} 创建授权文件: {os.path.basename(lic_file)}") self.log_action("授权信息嵌入完成!") messagebox.showinfo( "成功", f"授权信息已成功嵌入 {len(self.obfuscate_files)} 个DLL文件\n" f"授权检查模块: dll_license_checker.py\n" f"使用的唯一ID号: {self.machine_id}\n" "在CAD中加载DLL时会自动显示授权信息" ) except Exception as e: messagebox.showerror("嵌入错误", str(e)) self.log_action(f"嵌入授权失败: {str(e)}") def check_license(self): if not self.license_key: messagebox.showerror("错误", "请先生成授权密钥") return if not self.activation_date: messagebox.showwarning("警告", "授权尚未激活,请先绑定机器") return # 获取当前时间 current_time = time.time() license_type = self.license_type.get() activation_time_str = time.strftime('%Y-%m-%d %H:%M', time.localtime(self.activation_date)) self.log_action("正在检查授权状态...") self.log_action(f"授权密钥: {self.license_key}") self.log_action(f"授权类型: {license_type}") self.log_action(f"激活时间: {activation_time_str}") self.log_action(f"唯一ID号: {self.machine_id}") # 根据授权类型检查状态 if license_type == "试用期": # 计算剩余时间 expiry_time = self.expiry_date remaining_seconds = expiry_time - current_time if remaining_seconds <= 0: status = "已过期" self.log_action("授权状态: 已过期") message = f"试用期授权已过期!" else: # 计算剩余天数、小时和分钟 remaining_days = int(remaining_seconds // (24 * 3600)) remaining_seconds %= (24 * 3600) remaining_hours = int(remaining_seconds // 3600) remaining_seconds %= 3600 remaining_minutes = int(remaining_seconds // 60) status = f"有效 (剩余 {remaining_days}天 {remaining_hours}小时 {remaining_minutes}分钟)" self.log_action(f"授权状态: {status}") expiry_date_str = time.strftime("%Y-%m-%d %H:%M", time.localtime(expiry_time)) # 显示总天数 total_days = self.time_limit_days message = f"试用期授权有效\n激活时间: {activation_time_str}\n到期时间: {expiry_date_str}\n总天数: {total_days}天\n剩余时间: {remaining_days}天 {remaining_hours}小时 {remaining_minutes}分钟" else: # 永久授权 status = "永久有效" self.log_action("授权状态: 永久有效") message = f"永久授权有效\n激活时间: {activation_time_str}\n唯一ID号: {self.machine_id}" # 显示检查结果 messagebox.showinfo("授权检查", message) def log_action(self, message): self.log_text.config(state=tk.NORMAL) self.log_text.insert(tk.END, message + "\n") self.log_text.see(tk.END) self.log_text.config(state=tk.DISABLED) if __name__ == "__main__": root = tk.Tk() app = DLLProtectorApp(root) root.mainloop() 以上代码存在以下问题: Python 3.14.0a1 (tags/v3.14.0a1:8cdaca8, Oct 15 2024, 20:08:21) [MSC v.1941 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license()" for more information. =================== RESTART: C:\Users\卓越生活\Desktop\DLL授权信息.py ================== =================== RESTART: C:\Users\卓越生活\Desktop\DLL授权信息.py ================== Traceback (most recent call last): File "C:\Users\卓越生活\Desktop\DLL授权信息.py", line 923, in <module> app = DLLProtectorApp(root) File "C:\Users\卓越生活\Desktop\DLL授权信息.py", line 42, in __init__ self.create_license_tab() File "C:\Users\卓越生活\Desktop\DLL授权信息.py", line 213, in create_license_tab self.machine_id_var.set(self.machine_id) # 显示生成的唯一ID AttributeError: 'DLLProtectorApp' object has no attribute 'machine_id'. Did you mean: 'machine_id_var'?
最新发布
08-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值