傳統安裝需完整 Win32 SDK(難取得),提供兩種替代方案:
WIN32SDK.REG 偽裝 SDK 已安裝(指向 C:\MSTOOLS)。C:\DDK、MASM 6.11 至 C:\MASM611、VC++ 5.0 至預設路徑。C:\MSTOOLS\BINW16,放入 Borland 資源編譯器三檔(BRC.EXE→RC.EXE、BRCC32.EXE、RW32CORE.DLL)。CONFIG.SYS 加入 SHELL=C:\WINDOWS\COMMAND.COM /E:8192 /P 擴大環境變數空間。NEW-VARS.BAT → DDKINIT.BAT 32 BASE → VCVARS32.BAT。Check/Free Build Environment 即可。VxD 運行於 Ring 0(最高特權),可完成 API 無法做到的事:埠讀寫、實體記憶體存取、中斷呼叫、API 掛鉤。本範例攔截 Win9x 所有檔案操作,核心用途:病毒防火牆(動態掃毒/過濾)。原理類似 CIH 病毒感染機制。
\Device\Filemon):與 GUI 程式通訊,接收掛載分區、啟用/停用監控等指令。DriverEntry 關鍵流程IoCreateDevice,標記 Type = GUIINTERFACE。IoCreateSymbolicLink(\DosDevices\Filemon) 供 Win32 開啟。MajorFunction 至 FilemonDispatch。FastIOHook。FilemonGetProcessNameOffset() 掃描 KPEB 取得進程名稱偏移(系統進程名 "System" 為特徵)。FilemonDispatch 路由邏輯if (DeviceExtension->Type == GUIINTERFACE)
return FilemonDeviceRoutine(DeviceObject, Irp); // GUI 控制碼
else
return FilemonHookRoutine(DeviceObject, Irp); // 檔案系統掛鉤
FilemonHookRoutineGETPATHNAME 巨集 → FilemonGetFullPath)。MajorFunction(IRP_MJ_CREATE/READ/WRITE…)記錄操作資訊。*NextStack = *CurrentStack(未用 IoCopy/IoSkip)。FileObject->FileName(相對路徑)與 RelatedFileObject 組合。IRP_MJ_QUERY_INFORMATION 取得 FileNameInformation。FilemonGetFullPath 以條件判斷區分上述情境,代碼較長但邏輯清晰。
針對 IRP_MJ_CREATE_NAMED_PIPE、IRP_MJ_CREATE_MAILSLOT 判斷並加上前綴(\\.\pipe\、\\.\mailslot\)。
使用 DeviceIoControl:
hDevice = CreateFile("\\\\.\\FILEHOOK.VXD", 0, 0, NULL, 0, FILE_FLAG_DELETE_ON_CLOSE, NULL);
DeviceIoControl(hDevice, INSTALL_HOOK, NULL,0, NULL,0, &cb, 0); // 安裝掛鉤
DeviceIoControl(hDevice, UNINSTALL_HOOK, NULL,0, NULL,0, &cb, 0); // 移除掛鉤
CloseHandle(hDevice);
執行後,任何開啟檔案動作皆彈出 "Open file!" 訊息框,驗證攔截生效。
提供標準 FILEHOOK.DEF(段屬性、匯出 FILEHOOK_DDB)與 MAKEFILE(MASM 6.11C 編譯規則、Link 參數 /VXD /NOD、產生 .vxd/.map/.sym)。
本教學展示完整的檔案系統 API 掛鉤 VxD 框架,可作為病毒防火牆等安全軟體基礎。VxD 功能遠不止於此,善用 Ring 0 特權可開發 API 無法實現的高階應用。受限於篇幅與筆者水平,僅作為入門引導,歡迎交流探討。