635 lines
18 KiB
C
635 lines
18 KiB
C
#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;
|
||
}
|
||
|