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

軟體保護核心技術:CRC32 循環冗餘檢驗原理與組合語言實作

     編輯:組合語言

前言

花指令易被破解,CRC32 校驗提供更強韌的完整性保護。本文從數學原理推導 CRC 運算,詳細說明查表法實作,並提供完整 Win32 組合語言範例(含 CRC32 表生成、字串校驗、對話框介面),可直接整合至軟體保護體系。

CRC 數學原理:模二多項式除法

一般除法 vs CRC 除法

一般二進位除法:1001 (9) / 0011 (3) = 0011 餘 0000

CRC 除法:減法替換為 XOR,無借位無進位。

被除數: 11110 (30)
除數  : 1001  (9, poly=1001, 寬度W=3)
------------------------
11110
1001  ← XOR (最高位對齊)
----
01100
 1001  ← XOR
 ----
 01010
  1001  ← XOR
 ----
  0011  ← 餘數 = 3 = CRC 值

關鍵規則

  1. 除數 poly 最高位必為 1,寬度 W = 最高位位置 (如 1001 → W=3)。
  2. 計算前,被除數 (位串) 尾端補 W 個 0。
  3. 僅當當前最高位為 1 才執行 XOR,否則左移一位。
  4. 最終餘數 (W 位) 即為 CRC 值。

工程實作:查表法 (Table-Driven)

CRC-32 多項式

標準 0xEDB88320 (反轉形式),對應多項式 x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1。

表生成演算法 (256 DWORD)

for i = 0 .. 255:
    crc = i
    repeat 8 times:
        if (crc & 1) == 1:
            crc = (crc >> 1) ^ 0xEDB88320
        else:
            crc = crc >> 1
    table[i] = crc

資料校驗演算法

crc = 0xFFFFFFFF
for each byte b in data:
    index = (crc ^ b) & 0xFF
    crc = (crc >> 8) ^ table[index]
crc = NOT crc

C 碼對應:

temp = (oldcrc ^ abyte) & 0x000000FF
crc = ((oldcrc >> 8) & 0x00FFFFFF) ^ crc32tbl[temp]

完整 Win32 組合語言實作

資料區

.const
IDC_BUTTON_OPEN equ 3000
IDC_EDIT_INPUT  equ 3001

.data
szDlgName   db "lc_dialog", 0
szTitle     db "CRC demo by LC", 0
szTemplate  db "字串 \"%s\" 的 CRC32 值是:%X", 0
crc32tbl    dd 256 dup(0)
szBuffer    db 255 dup(0)

.data?
szText      db 300 dup(?)

CRC32 表生成 init_crc32table

init_crc32table proc
    mov ecx, 256
    mov edx, 0EDB88320h
$BigLoop:
    lea eax, [ecx-1]        ; i = ecx-1
    push ecx
    mov ecx, 8
$SmallLoop:
    shr eax, 1
    jnc @F
    xor eax, edx            ; 多項式
@@:
    dec ecx
    jne $SmallLoop
    pop ecx
    mov [crc32tbl+ecx*4-4], eax
    dec ecx
    jne $BigLoop
    ret
init_crc32table endp

字串 CRC32 計算 arraycrc32

; 入口: EBX = 字串起始位址 (以 0 結尾)
; 出口: EAX = CRC32 值
arraycrc32 proc
    mov eax, -1             ; 初始值 0xFFFFFFFF
    or ebx, ebx
    jz $Done
@@:
    mov dl, [ebx]
    or dl, dl
    je $Done                ; 遇 0 結束
    xor dl, al              ; (crc ^ byte) & 0xFF
    movzx edx, dl
    shr eax, 8              ; crc >> 8
    xor eax, [crc32tbl+edx*4] ; ^ table[index]
    inc ebx
    jmp @B
$Done:
    not eax                 ; 反轉
    ret
arraycrc32 endp

視窗程序片段

.if uMsg == WM_COMMAND
    mov eax, wParam
    mov edx, eax
    shr edx, 16
    movzx eax, ax
    .if edx == BN_CLICKED
        .if eax == IDC_BUTTON_OPEN || eax == IDOK
            invoke GetDlgItemText, hWnd, IDC_EDIT_INPUT, addr szBuffer, 255
            invoke init_crc32table
            lea ebx, szBuffer
            invoke arraycrc32
            invoke wsprintf, addr szText, addr szTemplate, addr szBuffer, eax
            invoke MessageBox, hWnd, addr szText, addr szTitle, MB_OK
        .endif
    .endif
.endif

資源腳本 (.rc)

LC_DIALOG DIALOGEX 10, 10, 195, 60
STYLE DS_SETFONT | DS_CENTER | WS_MINIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "lc's assembly framework"
FONT 9, "新細明體", 0, 0, 0x0
BEGIN
    LTEXT "請輸入一個字串(區分大小寫):", IDC_STATIC, 11, 7, 130, 10
    EDITTEXT IDC_EDIT_INPUT, 11, 20, 173, 12, ES_AUTOHSCROLL
    DEFPUSHBUTTON "Ca&lc", IDC_BUTTON_OPEN, 71, 39, 52, 15
END

整合至軟體保護的策略

  1. 編譯後計算:Release 建置完成,對 .exe 檔案 (排除 PE 標頭、校驗和欄位) 計算 CRC32,寫入資源區或特定位置。
  2. 執行時自我驗證:程式啟動、關鍵功能進入點、定時器回呼中,重新計算檔案映像 CRC32,與內建值比對。
  3. 差異處理:不匹配 → 記錄日誌、限制功能、延遲退出、通知伺服器,避免立即彈窗 讓破解者定位檢查點。
  4. 多重交叉驗證:關鍵函數各自內嵌 CRC32 常數,相互檢查,形成保護網。

效能考量

  • 表生成:256 × 8 迴圈,組合語言 < 0.1ms,可每次啟動動態生成或編譯期內嵌。
  • 校驗速度:~1-2 GB/s (現代 CPU),對完整 EXE (通常 < 10MB) 只需幾毫秒。
  • 記憶體:表 1KB,程式碼 < 500 位元組,極輕量。

總結

CRC32 以嚴格的數學特性(單位元組變化導致校驗值劇烈改變)提供高強度完整性保護。查表法實作兼顧速度與程式碼簡潔,本文提供的組合語言範例可直接嵌入 Win32 專案,結合隨機檢查、多點交叉驗證、反除錯技術,構建商業級軟體保護體系的核心基石。

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