隨著「共享軟體+註冊碼」模式普及,防止程式被破解或竄改成為開發者必修課。利用 MD5 雜湊值驗證執行檔完整性是經典且有效的手段。本文示範如何在 C++Builder 中使用 Indy 元件庫內建的 TIdHashMessageDigest5 計算自身 MD5,並搭配組合鍵過濾技巧提升效能與安全性。
CryptAcquireContext、CryptCreateHash 等一連串函式。TIdHashMessageDigest5 封裝良好,幾行程式碼即可完成雜湊計算。TFileStream 讀取自身執行檔(Application->ExeName)至緩衝區。0x70~0x91 之間的位元組(涵蓋 JZ/JNZ、NOP 等關鍵指令),並補上結束符。IdHashMessageDigest5->Reset()、CodeString()、CompletedInput() 取得 16 位元組 MD5 值。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;
}
EntryPoint,破解者修改檔案即無法正確解密。「軟體保護與破解永遠是矛與盾的博弈,目標不是絕對不可破,而是把 99% 的菜鳥擋在門外;若真被高手盯上,恭喜你——證明你的軟體有價值。」