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