首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

共享軟體註冊加密實戰:硬體綁定、注冊機、多點驗證全流程

     編輯:關於C++

引言

共享軟體 (Shareware) 透過「試用期限制」或「功能限制 + 註冊碼解鎖」商業化。本文基於 Win9x/NT 時代實戰經驗,系統闡述 **硬體資訊採集 → 註冊機生成碼 → 客戶端驗證 → 多點防破解** 完整工程鏈路。雖作業系統變遷,核心思想 (硬體指紋、非對稱/單向函數、分散驗證點) 至今仍具參考價值。

一、註冊源:硬體指紋採集

選擇原則

  • **唯一性**:不同機器碼不同。
  • **穩定性**:重裝 OS、升級驅動不變。
  • **可讀性**:Ring 3 應用層可無特權讀取。
  • **跨平台一致性**:Win9x/NT/XP/7/10/11 皆可讀。

經典來源 (歷史)

  1. **BIOS ROM 區 `F000:FFF5~FFFF`** : 主機出廠日期 + 機型標識 (筆者採用)。
  2. **主板序列號 (SMBIOS Type 1/2/3)** : `wmic baseboard get serialnumber`。
  3. **硬碟序列號** : `IOCTL_STORAGE_QUERY_PROPERTY` / `GetVolumeInformation` (邏輯卷號易變,物理序列號較穩)。
  4. **MAC 地址** : `GetAdaptersAddresses` (虛擬網卡/換網卡會變,需篩選實體網卡)。
  5. **CPU ID** : `__cpuid` 葉功能 (現代 CPU 皆支援)。

採集代碼範例 (BIOS ROM 讀取,Win9x 實模式/NT 保護模式通用)


// 保護模式需透過選擇子映射物理記憶體
UINT Sel1, Sel2;
__asm mov Sel1, ds;                 // 以資料段為模板
Sel2 = AllocSelector(Sel1);         // 分配新選擇子
SetSelectorBase(Sel2, 0xF0000);     // 物理基址 F0000h (F000:0000)
SetSelectorLimit(Sel2, 0xFFFF);     // 64KB 限制
BYTE* pRom = (BYTE*)((Sel2 << 16) | 0xFFF5); // F000:FFF5
// 讀取 pRom[0]~pRom[10] 等關鍵位元組
FreeSelector(Sel2);                 // 釋放選擇子 (系統上限 8192)

現代替代:WMI (`SELECT SerialNumber FROM Win32_BaseBoard`)、`SetupDiGetDeviceRegistryProperty` (硬碟)、`GetAdaptersAddresses` (MAC) —— 純 Ring 3、無需驅動、跨版本穩定。

一級加密 (混淆原始指紋)


for (i=0; i<5; i++)
    keyrom[i] = (*(pRom+i) + 0x1818) ^ 0x5858;  // 簡單可逆混淆
sprintf(buf, "KEYID:%04X%04X%04X%04X%04X", keyrom[0]...keyrom[4]);
// 產生 20 字元十六進位字串,用戶回報給開發者

二、註冊機:開發者端生成授權碼

雙模式架構

  1. **遠端模式** (`RegKey.exe KEYID:...`):接收用戶回報字串,解碼 → 核心演算法 → 輸出註冊碼。
  2. **本地模式** (`RegKey.exe` 直執):**直接讀取本機 BIOS/硬體** 生成碼,方便開發者自測/內部部署。

核心演算法範例 (單向雜湊風格,不可逆)


DWORD sum = 0x1234, sum1 = 0x7456;
for (j=0; j<4; j++) {           // 產生 4 組 = 16 字元
    for (i=0; i<5; i++) {       // 融合 5 組指紋
        sum  += keyrom[i];
        sum1 += keyrom[i];
    }
    sum  ^= 0x1234 << j;        // 位移異或擴散
    sum1 ^= 0x7456 << j;
    sprintf(WinKey  + j*4, "%04X", sum);
    sprintf(DosKey  + j*4, "%04X", sum1);
}
// WinKey: Windows 版註冊碼;DosKey: DOS/舊版相容碼
  • **不可逆性**:從註冊碼無法反推 `keyrom`,防止鑰匙生成器。
  • **擴散性**:單比特指紋變化導致整串註冊碼雪崩變化。
  • **參數化**:魔數 `0x1234/0x7456/0x1818/0x5858` 應為專案專屬常數,編譯期注入。

三、客戶端驗證:運行時再生成比對

核心邏輯

  1. 讀取硬體指紋 (同註冊機本地模式)。
  2. 跑相同演算法產生 **內部預期註冊碼**。
  3. 對使用者輸入的註冊碼 **二次加密** (防內存掃描直接比對)。
  4. 比對一致 → 寫入持久化存儲 (註冊表/檔案/資源區) → 解鎖功能。

關鍵代碼片段


// 內部產生預期碼
UINT ImeCmpKey() {
    // ... 讀取硬體指紋 ...
    for (j=0; j<4; j++) {
        for (i=0; i<5; i++) sum += (pRom[3+i] + 0x1818) ^ 0x5858;
        sum ^= 0x1234 << j;
        wsprintf(ExpectedKey + j*4, "%04X", sum);
    }
    // 二次加密預期碼 (簡單位運算)
    for (i=16; i>0; i--) ExpectedKey[16-i] ^= (BYTE)i;

    // 比對使用者輸入 (已同樣二次加密)
    for (i=0; i<16; i++) if (ExpectedKey[i] != UserKey[i]) break;
    return (i==16) ? 0 : -1;  // 0=成功
}

四、註冊點:分散式驗證佈防

**原則**:驗證邏輯 **不集中在單一函數**,而是散佈在高價值功能點、啟動路徑、關鍵資料流中。

典型佈防點

類型位置觸發條件失敗行為
啟動檢查`WinMain` / `InitInstance`每次啟動進入試用模式/倒計時
使用次數限制核心功能入口計數器超閾值 (如 `UseNum >= 0x3F80`)強制驗證/鎖定
高級功能門檻進階模組入口用戶點擊付費功能彈註冊對話框/降級
資料完整性儲存/匯出/列印關鍵資料寫入前攔截/加浮水印
定時心跳背景執行緒每 N 分鐘偵測記憶體修改/時間回滾

代碼範例


// 點 1: 使用次數門檻
if (lpImeL->UseNum >= 0x3F80) {
    if (ImeCmpKey() != 0) { sImeG.ZcFlag = TRUE; } // 未註冊
    else { sImeG.ZcFlag = FALSE; lpImeL->UseNum = 0; } // 重置計數
} else lpImeL->UseNum += sImeG.iWord;

// 點 2: 核心功能硬性驗證
if (ImeCmpKey() != 0) { sImeG.ZcFlag = TRUE; return; }
else { sImeG.ZcFlag = FALSE; lpImeL->UseNum = 0; }

五、註冊口:使用者介面與持久化

  • **多入口**:設定視窗、功能鎖定彈窗、啟動畫面、命令列參數 `/register KEY`。
  • **輸入處理**:支援退格、複製貼上、大小寫不敏感、即時視覺回饋 (光標/掩碼)。
  • **二次加密存儲**:註冊碼寫入檔案/註冊表前 **再次加密** (如異或 `0xAA`、位置打亂),防止「複製註冊檔到別台機器」生效。
  • **寫入位置隨機化**:偏移量 `0x12345L` 等非常數,或分散在多個檔案/資源區塊。

持久化範例


HFILE h = _lopen(szPath, OF_READWRITE);
_llseek(h, 0x12345L, SEEK_SET);   // 非標準偏移
_lwrite(h, EncryptedKey, 16);     // 僅寫 16 字元核心碼
_lclose(h);

六、防破解加固清單

層面措施
靜態分析關鍵字串加密、控制流扁平化、虛假分支、去除符號表、UPX/VMProtect 殼
動態調試`IsDebuggerPresent`、`CheckRemoteDebuggerPresent`、時序檢測 (RDTSC)、硬體斷點檢測 (DR0-DR7)
記憶體掃描關鍵資料加密存儲、運行時解密即用即銷、關鍵比對分散在多個函數
時間/環境系統時間回滾檢測 (對比 BIOS 時間/網路時間)、虛擬機檢測 (CPUID 葉 0x40000000)、沙箱檢測
網路驗證關鍵功能需線上驗證 (License Server)、離線授權檔簽名 (ECDSA/RSA)、硬體指紋雲端比對

七、現代化架構建議 (2024+)

  1. 非對稱加密授權:開發者持私鑰簽名 `(硬體指紋 + 到期日 + 功能位元組)`,客戶端僅持公鑰驗證簽名 —— **徹底杜絕註冊機洩露風險**。
  2. 硬體指紋組合:CPU ID + 主板序列號 + 硬碟序列號 + MAC (取穩定子集) → SHA-256 → 截取 128 bit 作為 `DeviceID`。
  3. 授權格式標準化:JSON Web Token (JWT) 或自定義 TLV 結構,含 `iss`/`sub`/`exp`/`features`/`hwf` 欄位。
  4. 離線授權檔:簽名後的授權檔 `.lic`,用戶雙擊/拖入即導入,無需手動輸入長串碼。
  5. 遙測與分析:啟動/驗證/失敗事件上報 (用戶同意前提),掌握盜版率、轉化率、地區分布。

總結

共享軟體註冊體系的核心不是「無法破解」,而是 **「提高破解成本超過購買成本」**。硬體指紋綁定 + 不可逆演算法 + 分散驗證點 + 二次加密存儲 + 多層反調試 構成纏繞防禦體系。現代架構應升級為 **非對稱簽名授權 + 離線授權檔 + 雲端風控**,將「註冊機」轉型為「授權簽名服務」,從根源消除私鑰洩露風險,同時提供更優雅的用戶體驗。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved