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

663 lines
18 KiB
C
Raw 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
{
bluetooth_btkrnl = 0,
bluetooth_rfcomm,
bluetooth_btwusb,
bluetooth_bthusb,
bluetooth_maximum
};
static WCHAR* s_bthname[] =
{
L"\\Driver\\BTKRNL",
L"\\Driver\\RFCOMM",
L"\\Driver\\BTWUSB",
L"\\Driver\\BTHUSB",
NULL
};
static BOOLEAN enable_bluetoothhook = FALSE;
NTSTATUS BtkrnHookDispatch(PDEVICE_OBJECT deviceObject, PIRP irp);
NTSTATUS RfcommHookDispatch(PDEVICE_OBJECT deviceObject, PIRP irp);
NTSTATUS BtwusbHookDispatch(PDEVICE_OBJECT deviceObject, PIRP irp);
NTSTATUS BthusbHookDispatch(PDEVICE_OBJECT deviceObject, PIRP irp);
static PDRIVER_DISPATCH s_ProxyDispatchers[bluetooth_maximum] =
{
BtkrnHookDispatch,
RfcommHookDispatch,
BtwusbHookDispatch,
BthusbHookDispatch
};
NTSTATUS BtkrnlDeviceIoControl(PDRIVER_DISPATCH dispath, PDEVICE_OBJECT deviceObject, PIRP irp);
NTSTATUS RfcommInternalDeviceIoControl(PDRIVER_DISPATCH dispath, PDEVICE_OBJECT deviceObject, PIRP irp);
NTSTATUS BtwusbDeviceIoControl(PDRIVER_DISPATCH dispath, PDEVICE_OBJECT deviceObject, PIRP irp);
NTSTATUS BthusbDeviceIoControl(PDRIVER_DISPATCH dispath, PDEVICE_OBJECT deviceObject, PIRP irp);
#define BTKRNL_COMMON_HOOK_HANDLERS \
[IRP_MJ_DEVICE_CONTROL] = { NULL, IRP_MJ_DEVICE_CONTROL, TRUE, BtkrnlDeviceIoControl }, \
#define RFCOMM_COMMON_HOOK_HANDLERS \
[IRP_MJ_INTERNAL_DEVICE_CONTROL] = { NULL, IRP_MJ_INTERNAL_DEVICE_CONTROL, TRUE, RfcommInternalDeviceIoControl }, \
#define BTWUSB_COMMON_HOOK_HANDLERS \
[IRP_MJ_DEVICE_CONTROL] = { NULL, IRP_MJ_DEVICE_CONTROL, TRUE, BtwusbDeviceIoControl }, \
#define BTHUSB_COMMON_HOOK_HANDLERS \
[IRP_MJ_DEVICE_CONTROL] = { NULL, IRP_MJ_DEVICE_CONTROL, TRUE, BthusbDeviceIoControl }, \
static HOOK_CONTEXT g_BlueToothHookContexts[bluetooth_maximum] =
{
{ NULL, FALSE, 0, { BTKRNL_COMMON_HOOK_HANDLERS } },
{ NULL, FALSE, 0, { RFCOMM_COMMON_HOOK_HANDLERS } },
{ NULL, FALSE, 0, { BTWUSB_COMMON_HOOK_HANDLERS } },
{ NULL, FALSE, 0, { BTHUSB_COMMON_HOOK_HANDLERS } }
};
NTSTATUS BlueToothHookDispatch_Common(ULONG ContextIndex, PDEVICE_OBJECT deviceObject, PIRP irp)
{
NTSTATUS NtStatus = STATUS_SUCCESS;
PIO_STACK_LOCATION pCurrentIoStack = IoGetCurrentIrpStackLocation(irp);
ULONG id = pCurrentIoStack->MajorFunction;
PHOOK_CONTEXT hook = NULL;
PDRIVER_DISPATCH pOrgHandler = NULL;
if (ContextIndex >= bluetooth_maximum)
return STATUS_UNSUCCESSFUL;
InterlockedIncrement((volatile LONG*)&g_BlueToothHookContexts[ContextIndex].IrpEnterCount);
hook = &g_BlueToothHookContexts[ContextIndex];
// 2. <20><>ŷ <20><>ȿ<EFBFBD><C8BF> <20>˻<EFBFBD>
if (hook->IsHooked &&
hook->HookHandlers[id].IsHook &&
hook->HookHandlers[id].Work)
{
pOrgHandler = hook->HookHandlers[id].pOrgHandler;
NtStatus = hook->HookHandlers[id].Work(
pOrgHandler,
deviceObject,
irp
);
}
else
{
NtStatus = STATUS_UNSUCCESSFUL;
}
InterlockedDecrement((volatile LONG*)&g_BlueToothHookContexts[ContextIndex].IrpEnterCount);
return NtStatus;
}
NTSTATUS BtkrnHookDispatch(PDEVICE_OBJECT deviceObject, PIRP irp)
{
return BlueToothHookDispatch_Common(bluetooth_btkrnl, deviceObject, irp);
}
NTSTATUS RfcommHookDispatch(PDEVICE_OBJECT deviceObject, PIRP irp)
{
return BlueToothHookDispatch_Common(bluetooth_rfcomm, deviceObject, irp);
}
NTSTATUS BtwusbHookDispatch(PDEVICE_OBJECT deviceObject, PIRP irp)
{
return BlueToothHookDispatch_Common(bluetooth_btwusb, deviceObject, irp);
}
NTSTATUS BthusbHookDispatch(PDEVICE_OBJECT deviceObject, PIRP irp)
{
return BlueToothHookDispatch_Common(bluetooth_bthusb, deviceObject, irp);
}
/**
@brief <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ŷ<EFBFBD>Լ<EFBFBD>
*/
NTSTATUS BtkrnlDeviceIoControl(PDRIVER_DISPATCH dispath, PDEVICE_OBJECT deviceObject, PIRP irp)
{
PIO_STACK_LOCATION irpstack = IoGetCurrentIrpStackLocation(irp);
ULONG buffSize = irpstack->Parameters.DeviceIoControl.InputBufferLength;
ULONG controlCode = irpstack->Parameters.DeviceIoControl.IoControlCode;
ULONG state = 0;
WCHAR processName[50] = { 0, };
ULONG processId = 0;
ULONG policyLog = 0;
char szProcessName[20] = { 0, };
if (!g_bs1Flt.IsAttached)
goto $BtkrnlCleanup;
if (!enable_bluetoothhook)
goto $BtkrnlCleanup;
processId = HandleToULong(PsGetCurrentProcessId());
UGetProcessName(szProcessName);
state = GetPolicyState(BDC_BLUETOOTH);
policyLog = IsPolicyLog(BDC_BLUETOOTH);
if (state == DISABLE)
{
// <20><><EFBFBD><EFBFBD> ũ<><C5A9> üũ <20><><EFBFBD><EFBFBD> <20>ʿ信 <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
if (buffSize > 4)
{
WCHAR notice[MAX_PATH] = { 0, };
KLogEx(DEBUG_TRACE_INFO, "btkrnl blocked(%X)(%d)", controlCode, buffSize);
if (policyLog)
{
RtlStringCbPrintfW(processName, sizeof(processName), L"%S", szProcessName);
RtlStringCbPrintfW(notice, sizeof(notice), L"btkrnl blocked(%X)(%d)", controlCode, buffSize);
SetLog(NULL, NULL, LOG_POLICY, BDC_BLUETOOTH, state, 0, processName, notice);
}
irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; // <20>Ǵ<EFBFBD> STATUS_ACCESS_DENIED
irp->IoStatus.Information = 0;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_INVALID_DEVICE_REQUEST;
}
}
$BtkrnlCleanup:
return dispath(deviceObject, irp);
}
/**
@brief <09><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ġ <20><>ŷ <20>Լ<EFBFBD> (RfComm / Microsoft Stack)
*/
PFILE_OBJECT gFileObject = NULL;
NTSTATUS RfcommInternalDeviceIoControl(PDRIVER_DISPATCH dispath, PDEVICE_OBJECT deviceObject, PIRP irp)
{
PIO_STACK_LOCATION irpstack = IoGetCurrentIrpStackLocation(irp);
NTSTATUS status = STATUS_SUCCESS;
PCHAR pBuffer = NULL;
PFILE_OBJECT pFileObject = irpstack->FileObject;
ULONG controlCode = irpstack->Parameters.DeviceIoControl.IoControlCode;
ULONG blueToothState = 0;
ULONG blueToothFileState = 0;
WCHAR processName[50] = { 0, };
ULONG processId = 0;
ULONG blueToothlog = 0;
ULONG blueToothFilelog = 0;
char szProcessName[20] = { 0, };
WCHAR notice[MAX_PATH] = { 0, };
if (!g_bs1Flt.IsAttached)
return dispath(deviceObject, irp);
if (!enable_bluetoothhook)
return dispath(deviceObject, irp);
processId = HandleToULong(PsGetCurrentProcessId());
UGetProcessName(szProcessName);
blueToothState = GetPolicyState(BDC_BLUETOOTH);
blueToothlog = IsPolicyLog(BDC_BLUETOOTH);
if (blueToothState == DISABLE)
{
KLogEx(DEBUG_TRACE_INFO, " blocked(%X)", controlCode);
if (blueToothlog)
{
RtlStringCbPrintfW(processName, sizeof(processName), L"%S", szProcessName);
RtlStringCbPrintfW(notice, sizeof(notice), L"controlCode(%X)", controlCode);
SetLog(NULL, NULL, LOG_POLICY, BDC_BLUETOOTH, blueToothState, 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 (!irp->MdlAddress || !irp->MdlAddress->ByteCount ||!irpstack->FileObject)
return dispath(deviceObject, irp);
pBuffer = MmGetSystemAddressForMdl(irp->MdlAddress);
if (!pBuffer)
return dispath(deviceObject, irp);
__try
{
blueToothFileState = GetPolicyState(BDC_BLUETOOTH_FILE);
blueToothFilelog = IsPolicyLog(BDC_BLUETOOTH_FILE);
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 (blueToothFilelog || blueToothlog)
{
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(%X), (%S)", controlCode, notice);
SetLog(NULL, NULL, LOG_POLICY, BDC_BLUETOOTH, blueToothFileState, 0, processName, notice);
}
gFileObject = pFileObject;
if (blueToothFileState == DISABLE)
{
KLogEx(DEBUG_TRACE_INFO, "Blocked OBEX Connect");
irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
irp->IoStatus.Information = 0;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_INVALID_DEVICE_REQUEST;
}
}
break;
case OBEX_OPCODE_DISCONNECT: // Disconnect
{
KLogEx(DEBUG_TRACE_INFO, "OBEX_OPCODE_DISCONNECT(%p)", pFileObject);
gFileObject = NULL;
if (blueToothFilelog || blueToothlog)
{
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_BLUETOOTH, blueToothFileState, 0, processName, notice);
}
}
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);
if (gFileObject != pFileObject)
{
break;
}
ULONG currentOffset = 3;
WCHAR szFileName[260] = { 0 };
ULONG packetLen = irp->MdlAddress->ByteCount;
PUCHAR pData = (PUCHAR)pBuffer;
if (blueToothFilelog || blueToothlog)
{
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_BLUETOOTH, blueToothFileState, 0, processName, notice);
}
if (blueToothFileState == DISABLE || blueToothFileState == READONLY)
{
KLogEx(DEBUG_TRACE_INFO, "Blocked File Transfer: %ws", szFileName);
irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
irp->IoStatus.Information = 0;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_INVALID_DEVICE_REQUEST;
}
}
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 = dispath(deviceObject, irp);
return status;
}
/**
@brief <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> USB <20><>ġ <20><>ŷ <20>Լ<EFBFBD> (BTWUSB)
*/
NTSTATUS BtwusbDeviceIoControl(PDRIVER_DISPATCH dispath, PDEVICE_OBJECT deviceObject, PIRP irp)
{
PIO_STACK_LOCATION irpstack = IoGetCurrentIrpStackLocation(irp);
ULONG controlCode = irpstack->Parameters.DeviceIoControl.IoControlCode;
NTSTATUS ntStatus = STATUS_SUCCESS;
ULONG blueToothState = 0;
WCHAR processName[50] = { 0, };
ULONG processId = 0;
ULONG blueToothlog = 0;
char szProcessName[20] = { 0, };
WCHAR notice[MAX_PATH] = { 0, };
if (!g_bs1Flt.IsAttached)
return dispath(deviceObject, irp);
if (!enable_bluetoothhook)
return dispath(deviceObject, irp);
processId = HandleToULong(PsGetCurrentProcessId());
UGetProcessName(szProcessName);
blueToothState = GetPolicyState(BDC_BLUETOOTH);
blueToothlog = IsPolicyLog(BDC_BLUETOOTH);
if (blueToothState == DISABLE)
{
KLogEx(DEBUG_TRACE_INFO, " btwusb blocked(%X)", controlCode);
if (blueToothlog)
{
RtlStringCbPrintfW(processName, sizeof(processName), L"%S", szProcessName);
RtlStringCbPrintfW(notice, sizeof(notice), L"btwusb blocked(%X)", controlCode);
SetLog(NULL, NULL, LOG_POLICY, BDC_BLUETOOTH, blueToothState, 0, processName, notice);
}
irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
irp->IoStatus.Information = 0;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_INVALID_DEVICE_REQUEST;
}
ntStatus = dispath(deviceObject, irp);
if (blueToothlog == TRUE)
{
}
return ntStatus;
}
/**
@brief <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> USB <20><>ġ <20><>ŷ <20>Լ<EFBFBD> (BTHUSB)
*/
NTSTATUS BthusbDeviceIoControl(PDRIVER_DISPATCH dispath, PDEVICE_OBJECT deviceObject, PIRP irp)
{
PIO_STACK_LOCATION irpstack = IoGetCurrentIrpStackLocation(irp);
ULONG controlCode = irpstack->Parameters.DeviceIoControl.IoControlCode;
NTSTATUS ntStatus = STATUS_SUCCESS;
ULONG blueToothState = 0;
WCHAR processName[50] = { 0, };
ULONG processId = 0;
ULONG blueToothlog = 0;
char szProcessName[20] = { 0, };
WCHAR notice[MAX_PATH] = { 0, };
if (!g_bs1Flt.IsAttached)
return dispath(deviceObject, irp);
if (!enable_bluetoothhook)
return dispath(deviceObject, irp);
processId = HandleToULong(PsGetCurrentProcessId());
UGetProcessName(szProcessName);
blueToothState = GetPolicyState(BDC_BLUETOOTH);
blueToothlog = IsPolicyLog(BDC_BLUETOOTH);
if (blueToothState == DISABLE)
{
KLogEx(DEBUG_TRACE_INFO, " bthusb blocked(%X)", controlCode);
if (blueToothlog)
{
RtlStringCbPrintfW(processName, sizeof(processName), L"%S", szProcessName);
RtlStringCbPrintfW(notice, sizeof(notice), L"bthusb blocked(%X)", controlCode);
SetLog(NULL, NULL, LOG_POLICY, BDC_BLUETOOTH, blueToothState, 0, processName, notice);
}
irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
irp->IoStatus.Information = 0;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_INVALID_DEVICE_REQUEST;
}
ntStatus = dispath(deviceObject, irp);
if (blueToothlog == TRUE)
{
}
return ntStatus;
}
NTSTATUS BlueToothIrpHookInit()
{
WCHAR* name = NULL;
ULONG i, mi;
PDRIVER_OBJECT obj = NULL;
PHOOK_CONTEXT hook = NULL;
for (i = 0; i < bluetooth_maximum; i++)
{
hook = &g_BlueToothHookContexts[i];
if (hook->IsHooked)
continue;
name = s_bthname[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_bluetoothhook = TRUE;
}
KLogEx(DEBUG_TRACE_INFO, "complete\n");
return STATUS_SUCCESS;
}
NTSTATUS BlueToothIrpHookCleanup()
{
ULONG i, mi;
LARGE_INTEGER WaitTime;
PHOOK_CONTEXT hook = NULL;
PDRIVER_DISPATCH pCurrentHandler = NULL;
enable_bluetoothhook = FALSE;
KLogEx(DEBUG_TRACE_INFO, "Started...\n");
for (i = 0; i < bluetooth_maximum; i++)
{
hook = &g_BlueToothHookContexts[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, "(%d), Waiting for active IRPs... Count: %d\n", i, hook->IrpEnterCount);
KeDelayExecutionThread(KernelMode, FALSE, &WaitTime);
}
hook->IsHooked = FALSE;
hook->DriverObject = NULL;
//RtlZeroMemory(hook->HookHandlers, sizeof(hook->HookHandlers));
}
WaitTime.QuadPart = -500 * 1000 * 10;
KeDelayExecutionThread(KernelMode, FALSE, &WaitTime);
KLogEx(DEBUG_TRACE_INFO, "Complete.\n");
return STATUS_SUCCESS;
}