Hook API監視驅動的加載_ASM Hook API監視驅動的加載_ASM

轉自:http://blog.csdn.net/iiprogram/archive/2007/09/06/1774026.aspx

;**************************************************************************************************
;Author:dge/D哥
;Date  :2006.7.20
;**************************************************************************************************
;@echo off
;goto make

.386
.model flat, stdcall
option casemap:none

;**************************************************************************************************
include d:/masm32/include/w2k/ntstatus.inc
include d:/masm32/include/w2k/ntddk.inc
include d:/masm32/include/w2k/ntoskrnl.inc
includelib d:/masm32/lib/w2k/ntoskrnl.lib
include d:/masm32/Macros/Strings.mac

;**************************************************************************************************
.data
;保存地址
dwOldNtLoadDriver   dd            ?
dwAddr              dd            ?
dwDriverName        ANSI_STRING  
.const
CCOUNTED_UNICODE_STRING "//Device//devHookApi", g_usDeviceName, 4
CCOUNTED_UNICODE_STRING "//??//slHookApi", g_usSymbolicLinkName, 4
CCOUNTED_UNICODE_STRING "ZwLoadDriver", g_usRoutineAddr, 4
   
;**************************************************************************************************
.code
;讓這個函數在NtLoadDriver的調用時被執行以實現監視
NewNtLoadDriver     proc  lpDriverName:PUNICODE_STRING
                    
      pushad
;      int 3
;                   invoke DbgPrint, $CTA0("/nEntry into NEW/n")
      invoke RtlUnicodeStringToAnsiString, addr dwDriverName, lpDriverName,TRUE
      invoke DbgPrint, $CTA0("/nDriverName: %s.sys/n"), dwDriverName.Buffer
      popad
      ;調用原函數
      push   lpDriverName
      call   dwOldNtLoadDriver
    
                    ret

NewNtLoadDriver     endp

;**************************************************************************************************
HookFunction        proc

                    pushad
;      int 3
;      invoke DbgPrint, $CTA0("/nEntry into hoookfunction/n")
                    ;下面是用KeServiceDescriptorTabled導出符號獲得數組的基地址,這個數組中包含有NtXXXX函數的入口地址。
      mov eax, KeServiceDescriptorTable
             mov esi, [eax]
      mov esi, [esi]
      ;用MmGetSystemRoutineAddress來獲得函數ZwLoadDriver的地址。並從這個函數地址後面的第2個字節中取得服務號。從而
      ;獲得以服務號爲下標的數組元素。
             invoke MmGetSystemRoutineAddress,addr g_usRoutineAddr
      inc eax
      movzx ecx,byte ptr[eax]
      sal ecx,2                   
      add esi,ecx
      mov dwAddr,esi 
      mov edi,dword ptr[esi]
      ;保存舊的函數地址。
      mov dwOldNtLoadDriver,edi
                    mov edi,offset NewNtLoadDriver
      ;修改入口地址
      cli
      mov dword ptr[esi],edi
      sti
      popad
                    mov eax, STATUS_SUCCESS

      ret

HookFunction     endp

;**************************************************************************************************                                
DispatchCreateClose proc pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP

             mov eax, pIrp
             assume eax:ptr _IRP
             mov [eax].IoStatus.Status, STATUS_SUCCESS
             and [eax].IoStatus.Information, 0
             assume eax:nothing 

             invoke  IoCompleteRequest, pIrp, IO_NO_INCREMENT
             mov eax, STATUS_SUCCESS

             ret

DispatchCreateClose endp

;**************************************************************************************************
DriverUnload        proc pDriverObject:PDRIVER_OBJECT
;必須保存環境,否則後果很嚴重。在這個函數中恢復被修改的地址。
 
                   pushad
;             int 3
;                   invoke DbgPrint, $CTA0("/nEntry into DriverUnload /n")
                    mov esi,dwAddr
             mov eax,dwOldNtLoadDriver
                    cli
             mov dword ptr[esi],eax
             sti
                    invoke IoDeleteSymbolicLink, addr g_usSymbolicLinkName
             mov eax,pDriverObject
             invoke IoDeleteDevice, (DRIVER_OBJECT PTR [eax]).DeviceObject              
             popad

             ret

DriverUnload endp

;**************************************************************************************************
DriverEntry         proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING
                    local status:NTSTATUS
      local pDeviceObject:PDEVICE_OBJECT

;                   int 3
;             invoke DbgPrint, $CTA0("/nEntry into DriverEntry/n")
             mov status, STATUS_DEVICE_CONFIGURATION_ERROR
                    invoke IoCreateDevice, pDriverObject, 0, addr g_usDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, addr pDeviceObject
             .if eax == STATUS_SUCCESS
                 invoke IoCreateSymbolicLink, addr g_usSymbolicLinkName, addr g_usDeviceName
                 .if eax == STATUS_SUCCESS
                     mov eax, pDriverObject
                     assume eax:ptr DRIVER_OBJECT
                     mov [eax].DriverUnload,            offset DriverUnload
                     mov [eax].MajorFunction[IRP_MJ_Create*(sizeof PVOID)],        offset DispatchCreateClose
                     mov [eax].MajorFunction[IRP_MJ_CLOSE*(sizeof PVOID)],         offset DispatchCreateClose
           
       assume eax:nothing
                                          invoke HookFunction
            
                     mov status, STATUS_SUCCESS
                 .else
                                          invoke IoDeleteDevice, pDeviceObject
                 .endif
             .endif
             mov eax, status

             ret

DriverEntry         endp

end DriverEntry

;**************************************************************************************************

:make

set drv=HooKapi

d:/masm32/bin/ml /nologo /c /coff %drv%.bat
d:/masm32/bin/link /nologo /driver /base:0x10000 /align:32 /out:%drv%.sys /subsystem:native %drv%.obj

del %drv%.obj

echo.
pause
參考:Undocumented Windows NT
感謝:非常感謝cardmagic大俠的幫助 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章