BSOne.SFC/Tocsg.Module/Bs1Flt/bs1flt/bs1flt_etc_port_hook.c

635 lines
18 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "precomp.h"
enum
{
etc_ohci1394 = 0,
etc_Serenum,
etc_Parport,
etc_irda,
etc_modem,
etc_maximum
};
static WCHAR* s_etcname[] =
{
L"\\Driver\\ohci1394",
L"\\Driver\\Serenum",
L"\\Driver\\Parport",
L"\\Driver\\irda",
L"\\Driver\\modem",
NULL
};
static BOOLEAN enable_etchook = FALSE;
NTSTATUS Ohci139DeviceControl(PDRIVER_DISPATCH dispatch, PDEVICE_OBJECT deviceObject, PIRP irp);
NTSTATUS SerenumlWrite(PDRIVER_DISPATCH dispatch, PDEVICE_OBJECT deviceObject, PIRP irp);
NTSTATUS ParportWrite(PDRIVER_DISPATCH dispatch, PDEVICE_OBJECT deviceObject, PIRP irp);
NTSTATUS IrdaInternalDeviceControl(PDRIVER_DISPATCH dispatch, PDEVICE_OBJECT deviceObject, PIRP irp);
NTSTATUS ModemWrite(PDRIVER_DISPATCH dispatch, PDEVICE_OBJECT deviceObject, PIRP irp);
NTSTATUS ohci1394HookDispatch_0(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS SerenumHookDispatch_0(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS ParportHookDispatch_0(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS IrdaHookDispatch_0(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS ModemHookDispatch_0(PDEVICE_OBJECT DeviceObject, PIRP Irp);
static PDRIVER_DISPATCH s_ProxyDispatchers[etc_maximum] =
{
ohci1394HookDispatch_0,
SerenumHookDispatch_0,
ParportHookDispatch_0,
IrdaHookDispatch_0,
ModemHookDispatch_0
};
#define OHCI1394_COMMON_HOOK_HANDLERS \
[IRP_MJ_DEVICE_CONTROL] = { NULL, IRP_MJ_DEVICE_CONTROL, TRUE, Ohci139DeviceControl }, \
#define SERENUM_COMMON_HOOK_HANDLERS \
[IRP_MJ_WRITE] = { NULL, IRP_MJ_WRITE, TRUE, SerenumlWrite }, \
#define PARPORT_COMMON_HOOK_HANDLERS \
[IRP_MJ_WRITE] = { NULL, IRP_MJ_WRITE, TRUE, ParportWrite }, \
#define IRDA_COMMON_HOOK_HANDLERS \
[IRP_MJ_INTERNAL_DEVICE_CONTROL] = { NULL, IRP_MJ_INTERNAL_DEVICE_CONTROL, TRUE, IrdaInternalDeviceControl }, \
#define MODEM_COMMON_HOOK_HANDLERS \
[IRP_MJ_WRITE] = { NULL, IRP_MJ_WRITE, TRUE, ModemWrite }, \
static HOOK_CONTEXT g_EtcHookContexts[etc_maximum] =
{
{ NULL, FALSE, 0, { OHCI1394_COMMON_HOOK_HANDLERS } },
{ NULL, FALSE, 0, { SERENUM_COMMON_HOOK_HANDLERS } },
{ NULL, FALSE, 0, { PARPORT_COMMON_HOOK_HANDLERS } },
{ NULL, FALSE, 0, { IRDA_COMMON_HOOK_HANDLERS } },
{ NULL, FALSE, 0, { MODEM_COMMON_HOOK_HANDLERS } },
};
NTSTATUS Ohci139DeviceControl(PDRIVER_DISPATCH dispatch, PDEVICE_OBJECT deviceObject, PIRP irp)
{
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION irpstack = IoGetCurrentIrpStackLocation(irp);
ULONG controlCode = irpstack->Parameters.DeviceIoControl.IoControlCode;
ULONG ProcessId = 0;
ULONG state = 0;
ULONG policyLog = 0;
char szProcessName[20] = { 0, };
wchar_t processName[50] = { 0, };
wchar_t notice[50] = { 0, };
if (!g_bs1Flt.IsAttached || !enable_etchook)
return dispatch(deviceObject, irp);
ProcessId = HandleToULong(PsGetCurrentProcessId());
UGetProcessName(szProcessName);
state = GetPolicyState(BDC_1394);
policyLog = IsPolicyLog(BDC_1394);
if (state == DISABLE)
{
KLogEx(DEBUG_TRACE_INFO, "block!!!");
if (policyLog)
{
RtlStringCbPrintfW(processName, sizeof(processName), L"%S", szProcessName);
RtlStringCbPrintfW(notice, sizeof(notice), L"1394 Blocked control(%x)", controlCode);
SetLog(NULL, NULL, LOG_POLICY, BDC_1394, state, 0, processName, notice);
}
irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
irp->IoStatus.Information = 0;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_INVALID_DEVICE_REQUEST;
}
status = dispatch(deviceObject, irp);
return status;
}
NTSTATUS SerenumlWrite(PDRIVER_DISPATCH dispatch, PDEVICE_OBJECT deviceObject, PIRP irp)
{
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION irpstack = IoGetCurrentIrpStackLocation(irp);
ULONG len = irpstack->Parameters.Write.Length;
ULONG ProcessId = 0;
ULONG state = 0;
ULONG policyLog = 0;
char szProcessName[20] = { 0, };
wchar_t processName[50] = { 0, };
wchar_t notice[50] = { 0, };
if (!g_bs1Flt.IsAttached || !enable_etchook)
return dispatch(deviceObject, irp);
ProcessId = HandleToULong(PsGetCurrentProcessId());
UGetProcessName(szProcessName);
state = GetPolicyState(BDC_SERIAL);
policyLog = IsPolicyLog(BDC_SERIAL);
if (state == DISABLE)
{
KLogEx(DEBUG_TRACE_INFO, "block!!!");
if (policyLog)
{
RtlStringCbPrintfW(processName, sizeof(processName), L"%S", szProcessName);
RtlStringCbPrintfW(notice, sizeof(notice), L"Serial Blocked len(%x)", len);
SetLog(NULL, NULL, LOG_POLICY, BDC_SERIAL, state, 0, processName, notice);
}
irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
irp->IoStatus.Information = 0;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
}
status = dispatch(deviceObject, irp);
return status;
}
NTSTATUS ParportWrite(PDRIVER_DISPATCH dispatch, PDEVICE_OBJECT deviceObject, PIRP irp)
{
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION irpstack = IoGetCurrentIrpStackLocation(irp);
ULONG len = irpstack->Parameters.Write.Length;
ULONG ProcessId = 0;
ULONG state = 0;
ULONG policyLog = 0;
char szProcessName[20] = { 0, };
wchar_t processName[50] = { 0, };
wchar_t notice[50] = { 0, };
if (!g_bs1Flt.IsAttached || !enable_etchook)
return dispatch(deviceObject, irp);
ProcessId = HandleToULong(PsGetCurrentProcessId());
UGetProcessName(szProcessName);
state = GetPolicyState(BDC_PARALLEL);
policyLog = IsPolicyLog(BDC_PARALLEL);
if (state == DISABLE)
{
KLogEx(DEBUG_TRACE_INFO, "block!!!");
if (policyLog)
{
RtlStringCbPrintfW(processName, sizeof(processName), L"%S", szProcessName);
RtlStringCbPrintfW(notice, sizeof(notice), L"Parport Blocked len(%x)", len);
SetLog(NULL, NULL, LOG_POLICY, BDC_PARALLEL, state, 0, processName, notice);
}
irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
irp->IoStatus.Information = 0;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
}
status = dispatch(deviceObject, irp);
return status;
}
static PFILE_OBJECT gFileObject = NULL;
NTSTATUS IrdaInternalDeviceControl(PDRIVER_DISPATCH dispatch, PDEVICE_OBJECT deviceObject, PIRP irp)
{
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION irpstack = IoGetCurrentIrpStackLocation(irp);
ULONG len = irpstack->Parameters.DeviceIoControl.InputBufferLength;
PFILE_OBJECT pFileObject = irpstack->FileObject;
ULONG ProcessId = 0;
ULONG state = 0;
ULONG policyLog = 0;
PCHAR pBuffer = NULL;
char szProcessName[20] = { 0, };
wchar_t processName[50] = { 0, };
wchar_t notice[50] = { 0, };
if (!g_bs1Flt.IsAttached || !enable_etchook)
return dispatch(deviceObject, irp);
ProcessId = HandleToULong(PsGetCurrentProcessId());
UGetProcessName(szProcessName);
state = GetPolicyState(BDC_IRDA);
policyLog = IsPolicyLog(BDC_IRDA);
if (state == DISABLE)
{
KLogEx(DEBUG_TRACE_INFO, "block!!!");
if (policyLog)
{
RtlStringCbPrintfW(processName, sizeof(processName), L"%S", szProcessName);
RtlStringCbPrintfW(notice, sizeof(notice), L"Irda Blocked len(%x)", len);
SetLog(NULL, NULL, LOG_POLICY, BDC_IRDA, state, 0, processName, notice);
}
irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
irp->IoStatus.Information = 0;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_INVALID_DEVICE_REQUEST;
}
if(!policyLog)
return dispatch(deviceObject, irp);
if (!irp->MdlAddress || !irp->MdlAddress->ByteCount || !irpstack->FileObject)
return dispatch(deviceObject, irp);
pBuffer = MmGetSystemAddressForMdl(irp->MdlAddress);
if (!pBuffer)
return dispatch(deviceObject, irp);
__try
{
RtlStringCbPrintfW(processName, sizeof(processName), L"%S", szProcessName);
POBEX_COMMON_HEADER pCommon = (POBEX_COMMON_HEADER)pBuffer;
KLogEx(DEBUG_TRACE_INFO, "Opcode(%X)", pCommon->Opcode);
switch (pCommon->Opcode)
{
case OBEX_OPCODE_CONNECT:
{
KLogEx(DEBUG_TRACE_INFO, "OBEX_OPCODE_CONNECT(%p)", pFileObject);
POBEX_CONNECT_PACKET pConn = (POBEX_CONNECT_PACKET)pBuffer;
USHORT hostPacketLen = 0;
USHORT hostMaxPktSize = 0;
if (irp->MdlAddress->ByteCount < sizeof(OBEX_CONNECT_PACKET))
{
KLogEx(DEBUG_TRACE_INFO, "Data too short for OBEX Connect");
break;
}
hostPacketLen = SWAP_USHORT(pConn->PacketLength);
hostMaxPktSize = SWAP_USHORT(pConn->MaxPacketSize);
RtlStringCbPrintfW(notice, sizeof(notice),
L"OBEX_OPCODE_CONNECT, hostPacketLen(%d), version(0x%x), flag(%d), hostMaxPktSize(%d)",
hostPacketLen, pConn->Version, pConn->Flags, hostMaxPktSize);
KLogEx(DEBUG_TRACE_INFO, "file blocked, (%S)", notice);
SetLog(NULL, NULL, LOG_POLICY, BDC_IRDA, state, 0, processName, notice);
gFileObject = pFileObject;
}
break;
case OBEX_OPCODE_DISCONNECT: // Disconnect
{
KLogEx(DEBUG_TRACE_INFO, "OBEX_OPCODE_DISCONNECT(%p)", pFileObject);
RtlStringCbPrintfW(notice, sizeof(notice),
L"OBEX_OPCODE_DISCONNECT, ByteCount(%d)", irp->MdlAddress->ByteCount);
KLogEx(DEBUG_TRACE_INFO, "(%S)", notice);
SetLog(NULL, NULL, LOG_POLICY, BDC_IRDA, state, 0, processName, notice);
gFileObject = NULL;
}
break;
case OBEX_OPCODE_PUT: // Put
case OBEX_OPCODE_PUT_FINAL: // Put Final
{
KLogEx(DEBUG_TRACE_INFO, "OBEX_OPCODE_PUT,OBEX_OPCODE_PUT_FINAL(%p)", pFileObject);
ULONG currentOffset = 3;
WCHAR szFileName[260] = { 0 };
ULONG packetLen = irp->MdlAddress->ByteCount;
PUCHAR pData = (PUCHAR)pBuffer;
if (gFileObject != pFileObject)
break;
while (currentOffset < packetLen)
{
UCHAR headerId = pData[currentOffset];
if (currentOffset + 3 > packetLen)
break;
// OBEX <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> 2<><32>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٸ<EFBFBD>
// 00xxxxxx: Unicode String (Length <20><><EFBFBD><EFBFBD>) -> Name <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// 01xxxxxx: Byte Sequence (Length <20><><EFBFBD><EFBFBD>)
// 10xxxxxx: 1 Byte Value (Length <20>ʵ<EFBFBD> <20><><EFBFBD><EFBFBD>)
// 11xxxxxx: 4 Byte Value (Length <20>ʵ<EFBFBD> <20><><EFBFBD><EFBFBD>)
if (headerId == OBEX_OPCODE_NAME) // 0x01: <20><><EFBFBD>ϸ<EFBFBD> <20>߰<EFBFBD>!
{
USHORT headerLen = 0;
// Length <20>ʵ<EFBFBD><CAB5><EFBFBD> Big Endian (2 bytes)
((PUCHAR)&headerLen)[1] = pData[currentOffset + 1];
((PUCHAR)&headerLen)[0] = pData[currentOffset + 2];
// <20><><EFBFBD><EFBFBD> <20≯<EFBFBD> <20><><EFBFBD><EFBFBD> = <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - (ID 1byte + Length 2bytes)
// OBEX Name<6D><65> Null-terminated Unicode<64><65> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2<><32><EFBFBD><EFBFBD>Ʈ 0x00 0x00 <20><><EFBFBD><EFBFBD>)
if (headerLen > 5 && (currentOffset + headerLen <= packetLen))
{
ULONG nameByteLen = headerLen - 3; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڿ<EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ <20><> (<28><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 3<><33><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD>)
if (nameByteLen >= sizeof(szFileName))
nameByteLen = sizeof(szFileName) - 2;
// <20><><EFBFBD>ϸ<EFBFBD> <20><><EFBFBD><EFBFBD> (pData + offset + 3)
RtlCopyMemory(szFileName, &pData[currentOffset + 3], nameByteLen);
for (ULONG k = 0; k < nameByteLen / 2; k++)
szFileName[k] = SWAP_USHORT(szFileName[k]);
szFileName[nameByteLen / 2] = 0;
KLogEx(DEBUG_TRACE_INFO, "File Name Found: %ws", szFileName);
RtlStringCbPrintfW(notice, sizeof(notice), L"File Transfer: %s, packetLen: %d", szFileName, packetLen);
}
break; // <20≯<EFBFBD><CCB8><EFBFBD> ã<><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD>ȭ)
}
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̵<EFBFBD><CCB5>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
if ((headerId & 0xC0) == 0x00 || (headerId & 0xC0) == 0x40)
{
// Length <20>ʵ尡 <20>ִ<EFBFBD> Ÿ<><C5B8> (String, Sequence)
USHORT chunkLen = 0;
((PUCHAR)&chunkLen)[1] = pData[currentOffset + 1];
((PUCHAR)&chunkLen)[0] = pData[currentOffset + 2];
if (chunkLen == 0) break; // <20><><EFBFBD>ѷ<EFBFBD><D1B7><EFBFBD> <20><><EFBFBD><EFBFBD>
currentOffset += chunkLen;
}
else if ((headerId & 0xC0) == 0x80)
{
// 1 Byte Value (<28><> 2<><32><EFBFBD><EFBFBD>Ʈ: ID + Value)
currentOffset += 2;
}
else if ((headerId & 0xC0) == 0xC0)
{
// 4 Byte Value (<28><> 5<><35><EFBFBD><EFBFBD>Ʈ: ID + Value 4bytes)
currentOffset += 5;
}
}
if (notice[0] == 0)
RtlStringCbPrintfW(notice, sizeof(notice), L"File Transfer: unknown, packetLen: %d", packetLen);
SetLog(NULL, NULL, LOG_POLICY, BDC_IRDA, state, 0, processName, notice);
}
break;
case OBEX_OPCODE_OK:
KLogEx(DEBUG_TRACE_INFO, "OBEX_OPCODE_OK");
break;
case OBEX_OPCODE_CONTINUE:
KLogEx(DEBUG_TRACE_INFO, "OBEX_OPCODE_CONTINUE");
break;
case OBEX_OPCODE_BODY:
KLogEx(DEBUG_TRACE_INFO, "OBEX_OPCODE_BODY");
break;
case OBEX_OPCODE_END_BODY:
KLogEx(DEBUG_TRACE_INFO, "OBEX_OPCODE_END_BODY");
break;
case OBEX_OPCODE_VERSION:
KLogEx(DEBUG_TRACE_INFO, "OBEX_OPCODE_VERSION");
break;
case OBEX_OPCODE_CONN_FLAGS:
KLogEx(DEBUG_TRACE_INFO, "OBEX_OPCODE_CONN_FLAGS");
break;
case OBEX_OPCODE_NAME:
KLogEx(DEBUG_TRACE_INFO, "OBEX_OPCODE_NAME");
break;
case OBEX_OPCODE_LENGTH:
KLogEx(DEBUG_TRACE_INFO, "OBEX_OPCODE_LENGTH");
break;
default:
KLogEx(DEBUG_TRACE_INFO, "default OBEX_OPCODE");
break;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
NTSTATUS exceptStatus = GetExceptionCode();
KLogEx(DEBUG_TRACE_ERROR, "Exception accessing buffer: 0x%X", exceptStatus);
}
status = dispatch(deviceObject, irp);
return status;
}
NTSTATUS ModemWrite(PDRIVER_DISPATCH dispatch, PDEVICE_OBJECT deviceObject, PIRP irp)
{
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION irpstack = IoGetCurrentIrpStackLocation(irp);
ULONG len = irpstack->Parameters.Write.Length;
ULONG ProcessId = 0;
ULONG state = 0;
ULONG policyLog = 0;
char szProcessName[20] = { 0, };
wchar_t processName[50] = { 0, };
wchar_t notice[50] = { 0, };
if (!g_bs1Flt.IsAttached || !enable_etchook)
return dispatch(deviceObject, irp);
ProcessId = HandleToULong(PsGetCurrentProcessId());
UGetProcessName(szProcessName);
state = GetPolicyState(BDC_MODEM);
policyLog = IsPolicyLog(BDC_MODEM);
if (state == DISABLE)
{
KLogEx(DEBUG_TRACE_INFO, "block!!!");
if (policyLog)
{
RtlStringCbPrintfW(processName, sizeof(processName), L"%S", szProcessName);
RtlStringCbPrintfW(notice, sizeof(notice), L"Modem Blocked len(%x)", len);
SetLog(NULL, NULL, LOG_POLICY, BDC_MODEM, state, 0, processName, notice);
}
irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
irp->IoStatus.Information = 0;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
}
status = dispatch(deviceObject, irp);
return status;
}
NTSTATUS EtcHookDispatch_Common(ULONG ContextIndex, PDEVICE_OBJECT deviceObject, PIRP irp)
{
NTSTATUS NtStatus = STATUS_SUCCESS;
PIO_STACK_LOCATION irpstack = IoGetCurrentIrpStackLocation(irp);
ULONG id = irpstack->MajorFunction;
PHOOK_CONTEXT pCtx = NULL;
if (ContextIndex >= etc_maximum)
{
return STATUS_UNSUCCESSFUL;
}
InterlockedIncrement((volatile LONG*)&g_EtcHookContexts[ContextIndex].IrpEnterCount);
pCtx = &g_EtcHookContexts[ContextIndex];
if (pCtx->IsHooked &&
pCtx->HookHandlers[id].IsHook &&
pCtx->HookHandlers[id].Work)
{
NtStatus = pCtx->HookHandlers[id].Work(pCtx->HookHandlers[id].pOrgHandler, deviceObject, irp);
}
else
{
NtStatus = STATUS_UNSUCCESSFUL;
}
InterlockedDecrement((volatile LONG*)&g_EtcHookContexts[ContextIndex].IrpEnterCount);
return NtStatus;
}
NTSTATUS ohci1394HookDispatch_0(PDEVICE_OBJECT deviceObject, PIRP irp)
{
return EtcHookDispatch_Common(etc_ohci1394, deviceObject, irp);
}
NTSTATUS SerenumHookDispatch_0(PDEVICE_OBJECT deviceObject, PIRP irp)
{
return EtcHookDispatch_Common(etc_Serenum, deviceObject, irp);
}
NTSTATUS ParportHookDispatch_0(PDEVICE_OBJECT deviceObject, PIRP irp)
{
return EtcHookDispatch_Common(etc_Parport, deviceObject, irp);
}
NTSTATUS IrdaHookDispatch_0(PDEVICE_OBJECT deviceObject, PIRP irp)
{
return EtcHookDispatch_Common(etc_irda, deviceObject, irp);
}
NTSTATUS ModemHookDispatch_0(PDEVICE_OBJECT deviceObject, PIRP irp)
{
return EtcHookDispatch_Common(etc_modem, deviceObject, irp);
}
NTSTATUS EtcIrpHookInit()
{
WCHAR* name = NULL;
ULONG i, mi;
PDRIVER_OBJECT obj = NULL;
PHOOK_CONTEXT hook = NULL;
for (i = 0; i < etc_maximum; i++)
{
hook = &g_EtcHookContexts[i];
if (hook->IsHooked)
continue;
name = s_etcname[i];
if (name == NULL)
continue;
KLogEx(DEBUG_TRACE_INFO, "Target driver(%S)\n", name);
obj = SearchDriverObject(name);
if (!obj)
{
KLogEx(DEBUG_TRACE_ERROR, "Not found object (%S)\n", name);
continue;
}
hook->DriverObject = obj;
for (mi = 0; mi < IRP_MJ_MAXIMUM_FUNCTION + 1; mi++)
{
if (!hook->HookHandlers[mi].IsHook)
continue;
if (obj->MajorFunction[mi] == s_ProxyDispatchers[i])
continue;
hook->HookHandlers[mi].pOrgHandler = obj->MajorFunction[mi];
if (hook->HookHandlers[mi].pOrgHandler == NULL)
continue;
InterlockedExchangePointer((PVOID)&obj->MajorFunction[mi], (PVOID)s_ProxyDispatchers[i]);
KLogEx(DEBUG_TRACE_INFO, "[Hook] %S MJ:%d Org:%p New:%p\n",
name, mi, hook->HookHandlers[mi].pOrgHandler, s_ProxyDispatchers[i]);
}
hook->IsHooked = TRUE;
enable_etchook = TRUE;
}
KLogEx(DEBUG_TRACE_INFO, "complete\n");
return STATUS_SUCCESS;
}
NTSTATUS EtcIrpHookCleanup()
{
ULONG i, mi;
LARGE_INTEGER WaitTime;
PHOOK_CONTEXT hook = NULL;
PDRIVER_DISPATCH pCurrentHandler = NULL;
enable_etchook = FALSE;
KLogEx(DEBUG_TRACE_INFO, "Started...\n");
for (i = 0; i < etc_maximum; i++)
{
hook = &g_EtcHookContexts[i];
if (!hook->IsHooked || !hook->DriverObject)
continue;
KLogEx(DEBUG_TRACE_INFO, "Unhooking Driver Index: %d\n", i);
for (mi = 0; mi <= IRP_MJ_MAXIMUM_FUNCTION; mi++)
{
if (!hook->HookHandlers[mi].IsHook)
continue;
if (hook->HookHandlers[mi].pOrgHandler == NULL)
continue;
pCurrentHandler = (PDRIVER_DISPATCH)InterlockedExchangePointer(
(PVOID)&hook->DriverObject->MajorFunction[mi],
(PVOID)hook->HookHandlers[mi].pOrgHandler
);
hook->HookHandlers[mi].pOrgHandler = NULL;
}
WaitTime.QuadPart = -50 * 1000 * 10; // 50ms <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
while (hook->IrpEnterCount > 0)
{
KLogEx(DEBUG_TRACE_INFO, "Waiting for active IRPs... Count: %d\n", hook->IrpEnterCount);
KeDelayExecutionThread(KernelMode, FALSE, &WaitTime);
}
// <20><><EFBFBD><EFBFBD> <20>ʱ<EFBFBD>ȭ
hook->IsHooked = FALSE;
hook->DriverObject = NULL;
//RtlZeroMemory(pCtx->HookHandlers, sizeof(pCtx->HookHandlers));
}
WaitTime.QuadPart = -500 * 1000 * 10;
KeDelayExecutionThread(KernelMode, FALSE, &WaitTime);
KLogEx(DEBUG_TRACE_INFO, "Complete.\n");
return STATUS_SUCCESS;
}