using System; using System.Diagnostics; using System.IO; using System.Linq; using System.Management; using System.Security.Cryptography; using System.Text; using System.Windows.Forms; namespace LicenseLib { /// /// C# 离线防破解 + 序列号授权核心类 /// 使用方式见 README.md /// public static class LicenseHelper { // ⚠️ 请修改为你自己的私钥(越长越安全) // 注意:这里展示的是异或加密后的存储方式,实际源码中看不到明文 private static readonly byte[] _privateKeyEncrypted = { 0x4D, 0x79, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x32, 0x30, 0x32, 0x36, 0x30, 0x35, 0x31, 0x38 }; private const byte _xorKey = 0x2A; /// /// 解密获取私钥(运行时才解密,反编译看不到明文) /// private static string GetPrivateKey() { byte[] decrypted = new byte[_privateKeyEncrypted.Length]; for (int i = 0; i < _privateKeyEncrypted.Length; i++) decrypted[i] = (byte)(_privateKeyEncrypted[i] ^ _xorKey); string key = Encoding.UTF8.GetString(decrypted); // 用完清内存 Array.Clear(decrypted, 0, decrypted.Length); return key; } /// /// 获取硬盘序列号 /// private static string GetDiskSN() { try { using (ManagementClass diskClass = new ManagementClass("Win32_LogicalDisk")) { foreach (ManagementObject disk in diskClass.GetInstances()) { string sn = disk["VolumeSerialNumber"]?.ToString() ?? ""; if (!string.IsNullOrEmpty(sn)) return sn; } } } catch { /* 降级处理 */ } return "DISK_UNKNOWN"; } /// /// 获取 CPU 编号 /// private static string GetCpuID() { try { using (ManagementClass mc = new ManagementClass("Win32_Processor")) { foreach (ManagementObject mo in mc.GetInstances()) { string id = mo["ProcessorId"]?.ToString() ?? ""; if (!string.IsNullOrEmpty(id)) return id; } } } catch { /* 降级处理 */ } return "CPU_UNKNOWN"; } /// /// 合成最终机器码(硬盘+CPU 组合 + MD5 压缩) /// public static string GetLocalMachineCode() { string raw = GetDiskSN() + GetCpuID(); using (MD5 md5 = MD5.Create()) { byte[] hash = md5.ComputeHash(Encoding.UTF8.GetBytes(raw)); return BitConverter.ToString(hash).Replace("-", "").ToUpper(); } } /// /// 离线生成注册码(供开发者使用——你在自己电脑上跑这个) /// /// 用户提供的机器码 /// 格式化的注册码 XXXX-XXXX-XXXX-XXXX public static string CreateRegisterCode(string machineCode) { string privateKey = GetPrivateKey(); string raw = machineCode + privateKey; // 用完清私钥内存 Array.Clear(privateKey.ToCharArray(), 0, privateKey.Length); using (SHA256 sha256 = SHA256.Create()) { byte[] hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(raw)); string fullCode = BitConverter.ToString(hash).Replace("-", "").ToUpper(); // 分割成 4 段序列号 return $"{fullCode.Substring(0, 4)}-{fullCode.Substring(4, 4)}-" + $"{fullCode.Substring(8, 4)}-{fullCode.Substring(12, 4)}"; } } /// /// 程序内本地校验序列号 /// /// 用户输入的注册码 /// 本机机器码 /// 是否校验通过 public static bool CheckRegister(string inputCode, string localMachineCode) { if (string.IsNullOrWhiteSpace(inputCode) || string.IsNullOrWhiteSpace(localMachineCode)) return false; // 移除常见分隔符,统一比较 string cleanedInput = inputCode.Replace("-", "").Replace(" ", "").Replace("_", "").ToUpper(); string rightCode = CreateRegisterCode(localMachineCode).Replace("-", "").ToUpper(); bool result = cleanedInput == rightCode; // 故意加一点迷惑性的延时(增加爆破难度) System.Threading.Thread.Sleep(50); return result; } /// /// 保存已授权标志(加密存储到本地文件) /// public static void SaveLicensedFlag() { try { string flagPath = Path.Combine(Application.StartupPath, ".license"); string machineCode = GetLocalMachineCode(); string raw = machineCode + GetPrivateKey() + "LICENSED"; using (SHA256 sha256 = SHA256.Create()) { byte[] hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(raw)); string encoded = Convert.ToBase64String(hash); File.WriteAllText(flagPath, encoded, Encoding.UTF8); } } catch { /* 静默失败,不影响主流程 */ } } /// /// 检查是否已授权 /// public static bool IsLicensed() { try { string flagPath = Path.Combine(Application.StartupPath, ".license"); if (!File.Exists(flagPath)) return false; string stored = File.ReadAllText(flagPath, Encoding.UTF8).Trim(); string machineCode = GetLocalMachineCode(); string raw = machineCode + GetPrivateKey() + "LICENSED"; using (SHA256 sha256 = SHA256.Create()) { byte[] hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(raw)); string expected = Convert.ToBase64String(hash); return stored == expected; } } catch { return false; } } /// /// 清除授权标志(用于反激活/重新授权) /// public static void ClearLicense() { try { string flagPath = Path.Combine(Application.StartupPath, ".license"); if (File.Exists(flagPath)) File.Delete(flagPath); } catch { } } /// /// 防调试检测——必须放在程序最开头调用! /// 检测到调试器时不弹窗、直接退出,增加逆向难度 /// public static void CheckDebugger() { // 1. 检测是否有调试器附加 if (Debugger.IsAttached) Environment.Exit(0); // 2. 检测常见逆向/调试进程 string[] debugProcesses = { "dnspy", "ilspy", "x64dbg", "ollydbg", "ida", "ida64", "windbg", "cheatengine", "de4dot" }; foreach (var proc in debugProcesses) { try { Process[] processes = Process.GetProcessesByName(proc); if (processes.Length > 0) Environment.Exit(0); } catch { } } // 3. 检测程序自身是否被篡改(检查文件 MD5) CheckIntegrity(); } /// /// 程序完整性校验(防止被修改后破解) /// 注:需在编译后计算自身 MD5 填入 _expectedHash /// private static void CheckIntegrity() { // ⚠️ 编译 Release 后,运行一次 GetSelfMd5() 获取哈希值,填到下面 // string expectedHash = "这里填编译后的 MD5"; // string actualHash = GetSelfMd5(); // if (actualHash != expectedHash) // Environment.Exit(0); } /// /// 获取程序自身的 MD5(用于完整性校验配置) /// public static string GetSelfMd5() { try { string path = Application.ExecutablePath; using (FileStream fs = File.OpenRead(path)) using (MD5 md5 = MD5.Create()) { byte[] hash = md5.ComputeHash(fs); return BitConverter.ToString(hash).Replace("-", "").ToUpper(); } } catch { return ""; } } /// /// 防多开检测 /// public static void CheckSingleInstance() { string processName = Process.GetCurrentProcess().ProcessName; Process[] processes = Process.GetProcessesByName(processName); if (processes.Length > 1) Environment.Exit(0); } /// /// 定时完整性巡检(建议放到 Timer 里,每 5-10 分钟执行一次) /// public static void IntegrityPatrol() { // 再次检测调试器 if (Debugger.IsAttached) Environment.Exit(0); // 检测序列号是否还被授权 if (!IsLicensed()) Environment.Exit(0); } } }