全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2997
推到 Plurk!
推到 Facebook!

VxD編程入門教程

 
jackkcg
站務副站長


發表:891
回覆:1050
積分:848
註冊:2002-03-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2002-10-25 13:52:15 IP:61.221.xxx.xxx 未訂閱
此為轉貼資料    VxD編程入門教程     一、Windows 95 DDK的安裝            安裝Windows 95 DDK一般需要先安裝Win32 SDK,原因是Windows 95 DDK  需要Win32 SDK的16位資源編譯器,但是Win32 SDK很大(一整張光碟  的容量),而且國內難以買到,ftp站上也較少見,即使有,下載也很困難。  筆者經過一段時間的摸索,找到了安裝Windows 95 DDK的幾種簡單方法,  現將方法介紹如下:  方法之一:使用第三方資源編譯器  1、修改註冊表,仿真Win32 SDK已經安裝的情況。  建立一個名?WIN32SDK.REG的註冊表文件,內容?:     REGEDIT4     [HKEY_USERS\.Default\Software\Microsoft\Win32SDK]     [HKEY_USERS\.Default\Software\Microsoft\Win32SDK\Directories]  "Install Dir"="C:\\MSTOOLS"     在資源管理器中雙擊此文件,將此文件中的內容添加到註冊表。就可以安  裝Windows 95 DDK了。  2、運行Windows 95 DDK中的SETUP.EXE文件,安裝Windows 95 DDK到  C:\DDK。  3、安裝MASM 6.11到C:\MASM611,安裝完成後將未安裝的Windows 95 DDK  中的MASM611C目錄下的文件覆蓋到C:\MASM611\BIN。  4、安裝Visual C++ 5.0(4.0也可以,但不宜使用6.0)到C:\Program   Files\DevStudio\VC。  5、建立C:\MSTOOLS\BINW16目錄,拷貝資源編譯器。  Windows 95 DDK需要一個能將Win32資源源文件編譯成16位資源的資源  編譯器。如果有Win32 SDK,可以將BINW16目錄下的文件直接拷貝到  C:\MSTOOLS\BINW16,如果沒有Win32 SDK,則可以使用第三方的資源編譯  器,這裏以使用Borland的資源編譯器?例:  準備Turbo MASM 5.0一套,用UNPAK工具解壓縮CMDLINE.PAK文件,找  到下面三個文件:     BRC.EXE  BRCC32.EXE  RW32CORE.DLL     將這三個文件拷貝到C:\MSTOOLS\BINW16,並將BRC.EXE改名?RC.EXE即  可。  6、修改CONFIG.SYS增大環境變數空間。  在CONFIG.SYS文件最後加入一行:     SHELL=C:\WINDOWS\COMMAND.COM /E:8192 /P     7、進入Windows 95 MS-DOS方式,初始化編譯環境(最好建立一個批處  理文件):     C:\MASM611\BINR\NEW-VARS.BAT  C:\DDK\DDKINIT.BAT 32 BASE  (編譯的設備驅動程式不同,參數也不同)  C:\Program Files\DevStudio\VC\bin\VCVARS32.BAT     就可以使用Windows 95 DDK了,連接時出現的警告可以不理會。  方法之二:使用Windows 98 DDK  完整版的Windows 98 DDK(約30M)包括Windows 95 DDK、全套SDK編譯  器和MASM 6.11C彙編器,安裝方法非常簡單:安裝Windows 98 DDK和Visual   C++ 5.0,然後直接運行“Check Build Environment”(編譯帶調試資訊  的設備驅動程式)或者“Free Build Environment”(編譯正式發佈版本  的設備驅動程式)程式項即可。     二、一個攔截Windows 95/98文件操作的VxD     VxD——虛擬設備驅動程式,顧名思義,VxD是用來控制硬體設備的,那?  這裏?什?要講一個攔截Windows 95/98文件操作的VxD呢?其實,VxD  不僅僅可以用來控制硬體設備,因?VxD工作在80386保護模式Ring 0  特權級(最高特權級)上,而一般的應用程式工作在Ring 3特權級(最  低特權級)上,所以VxD可以完成許多API不能完成的功能,例如埠讀  寫、實體記憶體讀寫、中斷調用、API攔截等。正因?如此,VxD在Windows  系統編程中有廣泛用途,其實大家一般都是碰到Windows API不能解決或  者難以解決的問題才考慮編寫VxD解決問題。  這裏介紹的攔截Windows 95/98文件操作的VxD可以用來攔截Windows 95  /98(Windows NT不支援VxD)的所有文件操作,那?這個VxD有什?用  途呢?最大的用途可能是——病毒防火牆,用來對文件操作進行過濾,可  以進行動態病毒檢測和動態殺毒。這個VxD使用的原理和目前流行的CIH  病毒傳染的原理是基本相同的。  (其實大家如果要問我?什?要寫這?一個VxD,那是因?——我是Virus  版的版主啦)  該VxD的檔案名是FILEHOOK.VXD,根源程式(FILEHOOK.ASM)如下:     ;FILEHOOK.VXD--攔截Windows 95/98文件操作的VxD     .386p     .XLIST     INCLUDE VMM.Inc  INCLUDE VWin32.Inc  INCLUDE Shell.Inc     MASM=1     INCLUDE IFS.Inc  INCLUDE IFSMgr.Inc     .LIST     ;VxD聲明     Declare_Virtual_Device   FILEHOOK,1,0,VxD_Control,Undefined_Device_ID,,,     ;保護模式資料段     VxD_DATA_SEG   Prev_File_System_Api_Hook dd 0   In_File_System_Api_Hook db 0   Message1 db 'Open file !',0   Caption1 db 'FILEHOOK',0  VxD_DATA_ENDS     ;保護模式代碼段     VxD_CODE_SEG     ;系統控制過程     BeginProc VxD_Control   Control_Dispatch SYS_DYNAMIC_DEVICE_INIT,VxD_Device_Init   Control_Dispatch SYS_DYNAMIC_DEVICE_EXIT,VxD_Device_Exit   Control_Dispatch W32_DEVICEIOCONTROL,VxD_IOCTL   clc   ret  EndProc VxD_Control     ;IOCTL 控制(設備I/O控制)過程     BeginProc VxD_IOCTL   ;獲取DeviceIoControl控制代碼   mov ecx,[esi.dwIoControlCode]   cmp ecx,1   jz Install_File_System_Api_Hook   cmp ecx,2   jz Uninstall_File_System_Api_Hook   jmp VxD_IOCTL_Exit     ;安裝文件系統API ?子     Install_File_System_Api_Hook:   mov eax,OFFSET32 File_System_Api_Hook   VxDCall IFSMgr_InstallFileSystemApiHook    or eax,eax   jz Error_Handler   ;保存上一個文件系統API ?子地址   mov Prev_File_System_Api_Hook,eax   jmp VxD_IOCTL_Exit     ;移去文件系統API ?子     Uninstall_File_System_Api_Hook:   mov eax,OFFSET32 File_System_Api_Hook   VxDCall IFSMgr_RemoveFileSystemApiHook    cmp eax,0FFFFFFFFH   jz Error_Handler   jmp VxD_IOCTL_Exit     ;IOCTL 控制過程結束     VxD_IOCTL_Exit:   xor eax,eax   clc   ret     ;錯誤處理     Error_Handler:   mov eax,0FFFFFFFFH   stc   ret  EndProc VxD_IOCTL     ;VxD_Device_Exit過程     BeginProc VxD_Device_Exit   clc   ret  EndProc VxD_Device_Exit     ;文件系統API ?子過程(C語言調用方式)     BeginProc File_System_Api_Hook,CCALL   ArgVar FSDFnAddr,DWORD   ArgVar FunctionNum,DWORD   ArgVar Drive,DWORD   ArgVar ResourceFlags,DWORD   ArgVar CodePage,DWORD   ArgVar pir,DWORD   EnterProc   pushad   ;防止重入   cmp byte ptr In_File_System_Api_Hook,00h   jnz Prev_Hook   ;比較是打開文件操作嗎?   cmp dword ptr FunctionNum,IFSFN_OPEN   jnz Prev_Hook   ;設置重入標誌   inc byte ptr In_File_System_Api_Hook   ;取當前VM控制碼   VMMCall Get_Cur_VM_Handle   ;顯示訊息方塊   mov eax,MB_ICONASTERISK+MB_OK   mov ecx,OFFSET32 Message1   mov edi,OFFSET32 Caption1   mov esi,0   mov edx,0   VxDCall Shell_Message   ;取消重入標誌   dec byte ptr In_File_System_Api_Hook     ;轉到上一個文件系統API ?子地址     Prev_Hook:   popad   LeaveProc   mov eax,Prev_File_System_Api_Hook   jmp [eax]   Return  EndProc File_System_Api_Hook     VxD_CODE_ENDS     ;保護模式初始化代碼段     VxD_ICODE_SEG     ;VxD_Device_Init過程     BeginProc VxD_Device_Init   clc   ret  EndProc VxD_Device_Init     VxD_ICODE_ENDS     end     該VxD在設備控制過程(VxD_Control過程)中處理了3個系統控制消息,  分別是SYS_DYNAMIC_DEVICE_INIT(動態VxD初始化)、  SYS_DYNAMIC_DEVICE_EXIT(動態VxD退出)和W32_DEVICEIOCONTROL(設  備I/O控制),對應的消息處理過程分別是VxD_Device_Init、  VxD_Device_Exit和VxD_IOCTL。其中VxD_Device_Init過程和  VxD_Device_Exit過程只清除進位元標誌返回(表示成功),VxD_IOCTL過程  是Windows 95/98應用程式與VxD通信的介面,完成文件系統API?子  的安裝和移去工作,[esi.dwIOControlCode]中是設備I/O控制代碼,該  控制代碼?1時安裝文件系統API?子,?2時移去文件系統API?子。  File_System_Api_Hook是文件系統API?子過程,這裏作?一個簡單的實  例,?子過程判斷是否是打開文件操作,如果是則顯示一個簡單的訊息方塊,  然後跳轉到上一個文件?子(相當於舊的文件系統API入口)。如果需要  擴充功能,可以在該過程中增加代碼。  彙編連接VxD需要一個模組定義文件和一個NMAKE文件(手工彙編連接當  然也可以)。這兩個文件都可以直接用DDK中的GENERIC實例中的模組定  義文件和NMAKE文件修改而成,模組定義文件(FILEHOOK.DEF)如下:     VXD FILEHOOK DYNAMIC     DESCRIPTION 'File System API Hook Program'     SEGMENTS      _LPTEXT     CLASS 'LCODE'   PRELOAD NONDISCARDABLE      _LTEXT      CLASS 'LCODE'   PRELOAD NONDISCARDABLE      _LDATA      CLASS 'LCODE'   PRELOAD NONDISCARDABLE      _TEXT       CLASS 'LCODE'   PRELOAD NONDISCARDABLE      _DATA       CLASS 'LCODE'   PRELOAD NONDISCARDABLE      CONST       CLASS 'LCODE'   PRELOAD NONDISCARDABLE      _TLS        CLASS 'LCODE'   PRELOAD NONDISCARDABLE      _BSS        CLASS 'LCODE'   PRELOAD NONDISCARDABLE      _LMSGTABLE  CLASS 'MCODE'   PRELOAD NONDISCARDABLE IOPL      _LMSGDATA   CLASS 'MCODE'   PRELOAD NONDISCARDABLE IOPL      _IMSGTABLE  CLASS 'MCODE'   PRELOAD DISCARDABLE IOPL      _IMSGDATA   CLASS 'MCODE'   PRELOAD DISCARDABLE IOPL      _ITEXT      CLASS 'ICODE'   DISCARDABLE      _IDATA      CLASS 'ICODE'   DISCARDABLE      _PTEXT      CLASS 'PCODE'   NONDISCARDABLE      _PMSGTABLE  CLASS 'MCODE'   NONDISCARDABLE IOPL      _PMSGDATA   CLASS 'MCODE'   NONDISCARDABLE IOPL      _PDATA      CLASS 'PDATA'   NONDISCARDABLE SHARED      _STEXT      CLASS 'SCODE'   RESIDENT      _SDATA      CLASS 'SCODE'   RESIDENT      _DBOSTART   CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING      _DBOCODE    CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING      _DBODATA    CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING      _16ICODE    CLASS '16ICODE' PRELOAD DISCARDABLE      _RCODE      CLASS 'RCODE'     EXPORTS          FILEHOOK_DDB @1     NMAKE文件(MAKEFILE)如下:     !ifdef MASTER_MAKE  BUILD_BITS=32  BUILD_TYPE=base  !INCLUDE $(DDKROOT)\master.mk  !endif     NAME = filehook     # supply the location of a 16-bit linker     LINK =     #       Definitions for the debug level      !ifdef DEBUG  DDEBUG  =-DDEBLEVEL=1 -DDEBUG  !else  DDEBUG  =-DDEBLEVEL=0  !endif     #       Definitions for MASM 6 Assembler     ASM    = ml  AFLAGS = -coff -DBLD_COFF -DIS_32 -W2 -c -Cx -Zm -DMASM6 $(DDEBUG)  ASMENV = ML  LFLAGS = /VXD /NOD     #       MASM 6 only inference rules     .asm.obj:   set $(ASMENV)=$(AFLAGS)   $(ASM) -Fo$*.obj $<      all : $(NAME).VXD     OBJS = filehook.obj     filehook.obj: filehook.asm     $(NAME).vxd: $(NAME).def $(OBJS)          link @<<$(NAME).lnk  $(LFLAGS)   /OUT:$(NAME).vxd  /MAP:$(NAME).map  /DEF:$(NAME).def  $(OBJS)  <<          mapsym -s -o $(NAME).sym $(NAME).map     clean:   -@del *.obj   -@del *.vxd   -@del *.exp   -@del *.lib   -@del *.map   -@del *.sym     有了這兩個文件,運行NMAKE即可彙編連接VxD。     三、Windows 95/98應用程式與VxD的通信     Windows 95/98應用程式與VxD的通信一般使用DeviceIoControl函數,  這裏給出一個實例根源程式(FHTEST.C)如下:     file://攔截Windows 95/98文件操作測試程式     #include   #include "tchar.h"     #define INSTALL_FILE_SYSTEM_API_HOOK 1  #define UNINSTALL_FILE_SYSTEM_API_HOOK 2     static TCHAR szAppName[]=_T("FHTEST");  static TCHAR szAppTitle[]=_T("攔截Windows 95/98文件操作測試程  序");  static HANDLE hDevice;     LRESULT CALLBACK WndProc(HWND hWnd,UINT Message,WPARAM   wParam,LPARAM lParam);     int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE   hPrevInstance,LPSTR lpCmdLine,int nCmdShow)  {   HWND hWnd;   WNDCLASSEX wcex;   MSG Msg;   file://本程式不能在Windows NT中運行   if(GetVersion()<0x80000000) { MessageBox(NULL,_T("本程式不能在Windows NT中運行! "),szAppTitle,MB_ICONINFORMATION|MB_OK); return FALSE; } if(!hPrevInstance) { wcex.cbSize=sizeof(WNDCLASSEX); wcex. wcex.lpfnWndProc=WndProc; wcex.cbClsExtra=0; wcex.cbWndExtra=0; wcex.hInstance=hInstance; wcex.hIcon=LoadIcon(hInstance,IDI_APPLICATION); wcex.hCursor=LoadCursor(NULL,IDC_ARROW); wcex.hbrBackground=(HBRUSH)(COLOR_WINDOW 1); wcex.lpszMenuName=NULL; wcex.lpszClassName=szAppName; wcex.hIconSm=LoadIcon(hInstance,IDI_APPLICATION); if(!RegisterClassEx(&wcex)) return FALSE; } hWnd=CreateWindow(szAppName,szAppTitle,WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, 0,0,hInstance,NULL); if(!hWnd) return FALSE; ShowWindow(hWnd,nCmdShow); UpdateWindow(hWnd); while(GetMessage(&Msg,0,0,0)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd,UINT Message,WPARAM wParam,LPARAM lParam) { HDC hDC; PAINTSTRUCT ps; DWORD cb; BOOL bResult; switch(Message) { case WM_CREATE: hDevice=CreateFile("\\\\.\\FILEHOOK.VXD",0,0,NULL,0,FILE_FLA G_DELETE_ON_CLOSE,NULL); if(hDevice!=INVALID_HANDLE_VALUE) { bResult=DeviceIoControl(hDevice,INSTALL_FILE_SYSTEM_API_HOOK, NULL,0,NULL,0,&cb,0); if(bResult) MessageBox(hWnd,_T("文件系統API ?子安裝 成功!"),szAppTitle,MB_ICONINFORMATION|MB_OK); else MessageBox(hWnd,_T("不能安裝文件系統API ?子! "),szAppTitle,MB_ICONINFORMATION|MB_OK); } else { MessageBox(hWnd,_T("不能打開FILEHOOK.VXD! "),szAppTitle,MB_ICONINFORMATION|MB_OK); } break; case WM_PAINT: hDC=BeginPaint(hWnd,&ps); EndPaint(hWnd,&ps); break; case WM_DESTROY: if(hDevice!=INVALID_HANDLE_VALUE) { bResult=DeviceIoControl(hDevice,UNINSTALL_FILE_SYSTEM_API_HO OK,NULL,0,NULL,0,&cb,0); if(bResult) MessageBox(hWnd,_T("文件系統API ?子移去 成功!"),szAppTitle,MB_ICONINFORMATION|MB_OK); else MessageBox(hWnd,_T("不能移去文件系統API ?子! "),szAppTitle,MB_ICONINFORMATION|MB_OK); CloseHandle(hDevice); } else { MessageBox(hWnd,_T("不能打開FILEHOOK.VXD! "),szAppTitle,MB_ICONINFORMATION|MB_OK); } PostQuitMessage(0); break; default: return DefWindowProc(hWnd,Message,wParam,lParam); } return 0; } 本程式使用CreateFile函數動態裝載VxD,然後用DeviceIoControl函數 向VxD發送設備I/O控制代碼,安裝和移去文件系統API?子,最後用 CloseHandle函數動態移去VxD。 運行該程式時,如果文件系統API?子安裝成功,會顯示出“文件系統API ?子安裝成功!”的訊息方塊,然後只要進行打開文件操作,就會顯示出“Open File !”的訊息方塊。退出該程式時,如果文件API?子移去成功,會顯示 出“文件API?子移去成功!”的訊息方塊,以後進行打開文件操作時不再 顯示訊息方塊。 四、小結 上述實例演示了一個完整的攔截Windows 95/98文件系統API的VxD和 Windows 95/98應用程式與該VxD通信的方法。該VxD可以作?一個基本 框架,稍作修改即可用於病毒防火牆等軟體。其實VxD的功能遠不止這些, 充分利用VxD的功能可以編寫出許多用API不能編寫出的高級應用程式。 本教程只是一個簡單的VxD編程例子,因?筆者水平所限,加之時間較少, 寫得較?簡單,還請大家見諒,同時也歡迎大家討論。本教程中使用的VMM 功能、VxD功能和API函數請查閱相關手冊或者幫助。
------
**********************************************************
哈哈&兵燹
最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好

Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知
K.表Knowlege 知識,就是本站的標語:Open our mind
系統時間:2024-04-20 23:16:44
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!