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

CDCheck:組合語言實作的光碟機驅動器檢測與磁碟序號驗證

     編輯:組合語言

前言:遊戲/軟體防拷貝的經典手段 — 光碟驗證

在光碟機普及的 90 年代,許多遊戲與大型軟體採用「檢查光碟是否在驅動器中」作為簡易防拷貝機制。CDCheck 即為此類邏輯的組合語言實作:掃描系統所有磁碟機,透過 MSCDEX (Microsoft CD-ROM Extensions) 識別光碟機,再讀取磁碟區序號 (Volume Serial Number) 比對預設值,判斷「正確光碟」是否插入。程式碼極精簡 (約 100 位元組),展示了 INT 2Fh MSCDEX 介面、INT 21h, 440Dh IOCTL 讀取序號、裝置驅動程式互動等核心技術。

程式流程

  1. 檢查 MSCDEX 是否安裝:INT 2Fh, AX=1500h,回傳 BX≠0 表示已安裝。
  2. 掃描磁碟機 A: 至 P: (對應 1..16):迴圈 EDI = 10h → 1,每次呼叫 INT 2Fh, AX=150Bh, CX=驅動器號,若 AX≠0 表示該驅動器為 MSCDEX 控制的光碟機。
  3. 讀取磁碟區序號:對光碟機發送 INT 21h, AX=440Dh (IOCTL 區塊裝置控制),子功能 CH=8, CL=66h (讀取序號),緩衝區 info 接收資料。
  4. 比對序號:取 info+2 起的 DWORD (Volume Serial Number),比對硬編碼值 0FFB7F724h。匹配 → 顯示 "Right CD";掃描完無匹配 → "Wrong CD"。
  5. 輸出結果並結束:INT 21h, AH=09h 列印訊息,INT 21h, AH=4Ch 退出。

關鍵技術細節

1. MSCDEX 介面 (INT 2Fh, 多工器/網路/光碟功能)

mov eax, 1500h     ; MSCDEX 安裝檢查
int 2fh
test ebx, ebx
jz exit            ; 未安裝
mov edi, 10h       ; 從驅動器 16 (P:) 往下掃描
nextloop:
mov ecx, edi
mov ax, 150Bh      ; 驅動器是否為 CD-ROM
int 2fh
test ax, ax
jz continue        ; 非光碟機,檢查下一個

MSCDEX 將光碟機對應到邏輯磁碟機代號,150Bh 可查詢指定驅動器是否為其管理的 CD-ROM。此介面為 DOS 時代光碟機存取的標準抽象層。

2. IOCTL 讀取磁碟區序號 (INT 21h, 440Dh)

mov ax, 440Dh
mov dx, offset info
mov bl, 5          ; 驅動器號 (1=A, 5=E 等,此處 BL=驅動器代號)
mov ch, 8          ; 類別: 區塊裝置
mov cl, 66h        ; 功能: 取得磁碟區序號
int 21h
mov eax, dword ptr [info+2]  ; 序號位於緩衝區偏移 2
cmp eax, 0FFB7F724h

INT 21h, 44h (IOCTL) 子功能 0Dh 為區塊裝置控制。CL=66h 對應 Get Volume Serial Number。緩衝區結構:前 2 位元組為資訊等級,接著 4 位元組序號。此序號在格式化時產生,理論上唯一,常用於軟體綁定授權。

3. 驅動器代號與掃描順序

程式以 EDI = 10h (16) 開始遞減,對應驅動器代號 16 (P:) 至 1 (A:)。實際上 MSCDEX 通常指派較高代號 (如 E: F: G:) 給光碟機,故從高往低掃描較快找到目標。

完整原始碼

.model small
.stack 100h
.386
.data
info db 30 dup (0)
right db 'Right CD$'
wrong db 'Wrong CD$'
nomscdex db 'MSCDEX not installed$'
.code
mov ax, @data
mov ds,ax
mov es,ax
lea edx, nomscdex
xor ebx,ebx
mov eax, 1500h
int 2fh
test ebx,ebx
jz exit
mov edi,10h
nextloop:
mov ecx,edi
mov ax, 150Bh
int 2fh
test ax,ax
jz continue
mov ax, 440Dh
mov dx, offset info
mov bl,5
mov ch,8
mov cl,66h
int 21h
mov eax, dword ptr [info+2]
cmp eax, 0FFB7F724h
jnz continue
lea edx, right
jmp exit
continue:
dec edi
jnz nextloop
lea edx, wrong
exit:
mov ah, 9h
int 21h
mov ax,4C00h
int 21h
end

安全性分析與繞過手法 (僅供防禦研究)

  • 靜態分析:序號 0FFB7F724h 硬編碼在 .EXE 中,十六進位編輯器可直接修改為目標光碟序號,或將 JNZ continue 改為 JMP exit 強制通過。
  • 動態攔截:TSR/裝置驅動程式 Hook INT 2Fh/21h,偽造 150Bh 回傳 AX≠0 並偽造 440Dh 緩衝區序號。
  • 虛擬光碟機:Daemon Tools / Alcohol 120% 等模擬光碟機,掛載 ISO 映像即可產生相同序號。
  • 現代觀點:單純序號比對屬「安全性極低」的客戶端驗證,易遭逆向繞過。現代軟體授權採用非對稱加密簽章、硬體指紋綁定、線上驗證、代碼虛擬化保護等多層防禦。

教學價值

  • 展示 MSCDEX 程式設計介面 (INT 2Fh 15xxh 系列) 的實際呼叫方式。
  • 示範 IOCTL (INT 21h, 44h) 區塊裝置控制 讀取磁碟區屬性的標準流程。
  • 體現 裝置驅動程式抽象層:應用程式無需知道具體硬體 (IDE/SCSI/專有介面),統一透過 MSCDEX + IOCTL 存取。
  • 極簡 .model small + .386 程式結構,適合 32 位元指令 (EAX, EDI) 在 16 位元段中混合使用的教學範例。

CDCheck 雖屬防拷貝邏輯,其核心技術 — 列舉裝置、識別類型、查詢屬性 — 是所有系統管理工具、備份軟體、磁碟診斷程式的基礎操作。研讀此程式碼有助於理解 DOS/Windows 9x 時代的儲存裝置抽象架構。

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