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

用 C++Builder Indy MD5 元件實作軟體自我保護

     編輯:關於C++

隨著「共享軟體+註冊碼」模式普及,防止程式被破解或竄改成為開發者必修課。利用 MD5 雜湊值驗證執行檔完整性是經典且有效的手段。本文示範如何在 C++Builder 中使用 Indy 元件庫內建的 TIdHashMessageDigest5 計算自身 MD5,並搭配組合鍵過濾技巧提升效能與安全性。

為何選擇 Indy MD5 元件?

  • Windows CryptoAPI 雖快但介面繁瑣,需處理 CryptAcquireContext、CryptCreateHash 等一連串函式。
  • Indy 的 TIdHashMessageDigest5 封裝良好,幾行程式碼即可完成雜湊計算。
  • 缺點:僅能處理以 null 結尾的字串,且大檔案速度較慢;解決方案為「關鍵碼過濾」——只對關鍵指令區塊(如跳轉、空操作指令)計算雜湊,大幅縮減資料量並自動過濾 null 字元。

核心演算法流程

  1. 以 TFileStream 讀取自身執行檔(Application->ExeName)至緩衝區。
  2. 使用內嵌組合語言掃描緩衝區,仅保留機器碼在 0x70~0x91 之間的位元組(涵蓋 JZ/JNZ、NOP 等關鍵指令),並補上結束符。
  3. 呼叫 IdHashMessageDigest5->Reset()、CodeString()、CompletedInput() 取得 16 位元組 MD5 值。
  4. 與預先儲存的正確雜湊比對,不符即判定被竄改。

關鍵程式碼片段

bool __fastcall CalcSelfMD5(char* fname, char* result) {
    TFileStream* fs = new TFileStream(fname, fmOpenRead);
    int size = fs->Read(buffer, MAX_SIZE);
    delete fs;
    if (size <= 1) return false;

    _asm {
        mov ecx, size-1
        mov ebx, buffer
        mov edx, buffer
    filter_loop:
        mov al, [ebx]
        cmp al, 0x70; jb skip
        cmp al, 0x91; jnb skip
        mov [edx], al; inc edx
    skip:
        inc ebx; dec ecx; jnz filter_loop
        mov byte ptr [edx+1], 0
    }

    IdHashMessageDigest5->Reset();
    IdHashMessageDigest5->AutoCompleteInput = false;
    IdHashMessageDigest5->CodeString(buffer);
    AnsiString md5 = IdHashMessageDigest5->CompletedInput();
    if (md5.Length() == 16) {
        memcpy(result, md5.c_str(), 16);
        return true;
    }
    return false;
}

進階防護策略

  • 靜態雜湊比對:將正確 MD5 寫入註冊檔或外部授權檔,啟動時比對。
  • 動態解密入口點:以正確 MD5 作為金鑰解密真正的 EntryPoint,破解者修改檔案即無法正確解密。
  • 搭配殼工具:完成自我驗證後再用 ASProtect/ASPack 加殼;脫殼會破壞雜湊,導致程式拒絕執行,嚇退大多數初級破解者。
「軟體保護與破解永遠是矛與盾的博弈,目標不是絕對不可破,而是把 99% 的菜鳥擋在門外;若真被高手盯上,恭喜你——證明你的軟體有價值。」
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved