C++ code colored by C++2HTML
				;**************************************************************************************************
;Author:dge/D哥
;Date :2006.7.20
;**************************************************************************************************
;f:\masm32\bin\ml /nologo /c /coff HookAPI.asm
;C:\>f:\masm32\bin\link /nologo /driver /base:0x10000 /align:32 /out:HookAPI.sys /subsystem:native HookAPI.obj
.386 . model flat , stdcall
option casemap
: none ;************************************************************************************************** include f:\masm32\include\w2k\ntstatus.inc include f:\masm32\include\w2k\ntddk.inc include f:\masm32\include\w2k\ntoskrnl.inc includelib f:\masm32\lib\w2k\ntoskrnl.lib include f:\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 ;**************************************************************************************************