mirror of
https://github.com/tnodir/fort
synced 2024-11-15 01:55:44 +00:00
Driver: Add log buffer.
This commit is contained in:
parent
da9c0a10d9
commit
92762a5389
@ -1,8 +1,18 @@
|
||||
/* Windows IP Filter Log Buffer */
|
||||
|
||||
#define WIPF_BUFFER_SIZE 4 * 1024
|
||||
#define WIPF_BUFFER_SIZE_MAX 32 * 1024
|
||||
|
||||
#include "../wipflog.c"
|
||||
|
||||
typedef struct wipf_buffer {
|
||||
UINT32 top, size;
|
||||
PVOID data;
|
||||
|
||||
PIRP irp; /* pending */
|
||||
PVOID out;
|
||||
ULONG out_len;
|
||||
|
||||
KSPIN_LOCK lock;
|
||||
} WIPF_BUFFER, *PWIPF_BUFFER;
|
||||
|
||||
@ -21,9 +31,121 @@ wipf_buffer_close (PWIPF_BUFFER buf)
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL
|
||||
static NTSTATUS
|
||||
wipf_buffer_write (PWIPF_BUFFER buf, UINT32 remote_ip, UINT64 pid,
|
||||
UINT32 path_len, const PVOID path)
|
||||
UINT32 path_len, const PVOID path,
|
||||
PIRP *irp, NTSTATUS *irp_status, ULONG_PTR *info)
|
||||
{
|
||||
return TRUE;
|
||||
const UINT32 len = sizeof(UINT32) + sizeof(UINT64)
|
||||
+ sizeof(UINT32) + path_len;
|
||||
UINT32 size;
|
||||
KIRQL irq;
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
|
||||
KeAcquireSpinLock(&buf->lock, &irq);
|
||||
|
||||
/* Try to directly write to pending client */
|
||||
if (buf->irp) {
|
||||
*irp = buf->irp;
|
||||
buf->irp = NULL;
|
||||
|
||||
*info = len;
|
||||
|
||||
if (buf->out_len < len) {
|
||||
*irp_status = STATUS_BUFFER_TOO_SMALL;
|
||||
/* fallback to buffer */
|
||||
} else {
|
||||
wipf_log_write(buf->out, remote_ip, pid, path_len, path);
|
||||
|
||||
*irp_status = STATUS_SUCCESS;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
size = buf->size;
|
||||
|
||||
if (len > WIPF_BUFFER_SIZE) {
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
goto end; /* drop too long path */
|
||||
}
|
||||
if (len > size - buf->top) {
|
||||
size *= 2;
|
||||
}
|
||||
if (size > WIPF_BUFFER_SIZE_MAX) {
|
||||
status = STATUS_BUFFER_TOO_SMALL;
|
||||
goto end; /* drop on overflow of buffer */
|
||||
}
|
||||
|
||||
/* resize the buffer */
|
||||
if (size != buf->size) {
|
||||
PVOID data = ExAllocatePoolWithTag(NonPagedPool, size, WIPF_POOL_TAG);
|
||||
if (data == NULL) {
|
||||
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto end; /* drop on OOM */
|
||||
}
|
||||
|
||||
RtlCopyMemory(data, buf->data, buf->top);
|
||||
wipf_buffer_close(buf);
|
||||
|
||||
buf->data = data;
|
||||
buf->size = size;
|
||||
}
|
||||
|
||||
buf->top += len;
|
||||
|
||||
wipf_log_write(buf->data, remote_ip, pid, path_len, path);
|
||||
|
||||
end:
|
||||
KeReleaseSpinLock(&buf->lock, irq);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
wipf_buffer_xmove (PWIPF_BUFFER buf, PIRP irp, PVOID out, ULONG out_len,
|
||||
ULONG_PTR *info)
|
||||
{
|
||||
KIRQL irq;
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
|
||||
KeAcquireSpinLock(&buf->lock, &irq);
|
||||
|
||||
*info = buf->top;
|
||||
|
||||
if (!buf->top) {
|
||||
if (buf->irp) {
|
||||
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
} else {
|
||||
buf->irp = irp;
|
||||
buf->out = out;
|
||||
buf->out_len = out_len;
|
||||
status = STATUS_PENDING;
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (out_len < buf->top) {
|
||||
status = STATUS_BUFFER_TOO_SMALL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
RtlCopyMemory(out, buf->data, buf->top);
|
||||
buf->top = 0;
|
||||
|
||||
end:
|
||||
KeReleaseSpinLock(&buf->lock, irq);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
wipf_buffer_cancel_pending (PWIPF_BUFFER buf, PIRP irp)
|
||||
{
|
||||
KIRQL irq;
|
||||
|
||||
KeAcquireSpinLock(&buf->lock, &irq);
|
||||
if (irp == buf->irp) {
|
||||
buf->irp = NULL;
|
||||
}
|
||||
KeReleaseSpinLock(&buf->lock, irq);
|
||||
}
|
||||
|
@ -108,9 +108,8 @@ wipf_callout_classify_v4 (const FWPS_INCOMING_VALUES0 *inFixedValues,
|
||||
{
|
||||
PWIPF_CONF_REF conf_ref;
|
||||
UINT32 local_ip, remote_ip;
|
||||
UINT64 pid;
|
||||
UINT32 path_len;
|
||||
PVOID path = NULL;
|
||||
PVOID path;
|
||||
BOOL blocked, notify;
|
||||
|
||||
UNUSED(packet);
|
||||
@ -123,12 +122,10 @@ wipf_callout_classify_v4 (const FWPS_INCOMING_VALUES0 *inFixedValues,
|
||||
|
||||
local_ip = inFixedValues->incomingValue[localIpField].value.uint32;
|
||||
remote_ip = inFixedValues->incomingValue[remoteIpField].value.uint32;
|
||||
path_len = inMetaValues->processPath->size;
|
||||
path = inMetaValues->processPath->data;
|
||||
|
||||
if (local_ip != remote_ip) {
|
||||
pid = inMetaValues->processId;
|
||||
path_len = inMetaValues->processPath->size;
|
||||
path = inMetaValues->processPath->data;
|
||||
|
||||
blocked = wipf_conf_ipblocked(&conf_ref->conf, remote_ip,
|
||||
path_len, path, ¬ify);
|
||||
} else {
|
||||
@ -144,8 +141,19 @@ wipf_callout_classify_v4 (const FWPS_INCOMING_VALUES0 *inFixedValues,
|
||||
} else {
|
||||
classifyOut->actionType = FWP_ACTION_CONTINUE;
|
||||
|
||||
if (notify)
|
||||
wipf_buffer_write(&g_device->buffer, remote_ip, pid, path_len, path);
|
||||
if (notify) {
|
||||
PIRP irp = NULL;
|
||||
NTSTATUS irp_status;
|
||||
ULONG_PTR info;
|
||||
|
||||
wipf_buffer_write(&g_device->buffer, remote_ip,
|
||||
inMetaValues->processId, path_len, path,
|
||||
&irp, &irp_status, &info);
|
||||
|
||||
if (irp) {
|
||||
wipf_request_complete_info(irp, irp_status, info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
@ -228,10 +236,23 @@ wipf_driver_complete (PDEVICE_OBJECT device, PIRP irp)
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
wipf_driver_cancel_pending (PDEVICE_OBJECT device, PIRP irp)
|
||||
{
|
||||
UNUSED(device);
|
||||
|
||||
wipf_buffer_cancel_pending(&g_device->buffer, irp);
|
||||
|
||||
IoReleaseCancelSpinLock(irp->CancelIrql); /* before IoCompleteRequest()! */
|
||||
|
||||
wipf_request_complete(irp, STATUS_CANCELLED);
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
wipf_driver_control (PDEVICE_OBJECT device, PIRP irp)
|
||||
{
|
||||
PIO_STACK_LOCATION irp_stack;
|
||||
ULONG_PTR info = 0;
|
||||
NTSTATUS status = STATUS_INVALID_PARAMETER;
|
||||
|
||||
UNUSED(device);
|
||||
@ -255,23 +276,27 @@ wipf_driver_control (PDEVICE_OBJECT device, PIRP irp)
|
||||
}
|
||||
break;
|
||||
}
|
||||
#if 0
|
||||
case WIPF_IOCTL_GETLOG: {
|
||||
PVOID data = irp->AssociatedIrp.SystemBuffer;
|
||||
const ULONG len = irp_stack->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
PVOID out = irp->AssociatedIrp.SystemBuffer;
|
||||
const ULONG out_len = irp_stack->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
|
||||
status = wipf_buffer_read_result(&g_device->buffer, irp);
|
||||
status = wipf_buffer_xmove(&g_device->buffer, irp, out, out_len, &info);
|
||||
|
||||
if (status == STATUS_PENDING) {
|
||||
KIRQL cirq;
|
||||
|
||||
IoMarkIrpPending(irp);
|
||||
|
||||
IoAcquireCancelSpinLock(&cirq);
|
||||
IoSetCancelRoutine(irp, wipf_driver_cancel_pending);
|
||||
IoReleaseCancelSpinLock(cirq);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "wipf: Control: Error: %d\n", status);
|
||||
}
|
||||
|
||||
wipf_request_complete(irp, status);
|
||||
wipf_request_complete_info(irp, status, info);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -6,11 +6,14 @@
|
||||
|
||||
#define WIPF_POOL_TAG 'WIPF'
|
||||
|
||||
#define wipf_request_complete(irp, status) \
|
||||
#define wipf_request_complete_info(irp, status, info) \
|
||||
do { \
|
||||
(irp)->IoStatus.Status = (status); \
|
||||
(irp)->IoStatus.Information = 0; \
|
||||
(irp)->IoStatus.Information = (info); \
|
||||
IoCompleteRequest((irp), IO_NO_INCREMENT); \
|
||||
} while(0)
|
||||
|
||||
#define wipf_request_complete(irp, status) \
|
||||
wipf_request_complete_info((irp), (status), 0)
|
||||
|
||||
#endif WIPFDRV_H
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
typedef struct wipf_conf {
|
||||
UINT32 len;
|
||||
UCHAR data[1];
|
||||
UCHAR data[4];
|
||||
} WIPF_CONF, *PWIPF_CONF;
|
||||
|
||||
#endif WIPFCONF_H
|
||||
|
@ -7,6 +7,7 @@ static BOOL
|
||||
wipf_conf_ipblocked (const PWIPF_CONF conf, UINT32 remote_ip,
|
||||
UINT32 path_len, const PVOID path, PBOOL notify)
|
||||
{
|
||||
return TRUE;
|
||||
*notify = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
29
src/wipflog.c
Normal file
29
src/wipflog.c
Normal file
@ -0,0 +1,29 @@
|
||||
/* Windows IP Filter Log */
|
||||
|
||||
static void
|
||||
wipf_log_write (char *p, UINT32 remote_ip, UINT64 pid,
|
||||
UINT32 path_len, const char *path)
|
||||
{
|
||||
*((UINT32 *) p)++ = remote_ip;
|
||||
*((UINT64 *) p)++ = pid;
|
||||
*((UINT32 *) p)++ = path_len;
|
||||
|
||||
if (path_len) {
|
||||
RtlCopyMemory(p, path, path_len);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wipf_log_read (const char **p, UINT32 *remote_ip, UINT64 *pid,
|
||||
UINT32 *path_len, const char **path)
|
||||
{
|
||||
*remote_ip = *((UINT32 *) *p)++;
|
||||
*pid = *((UINT64 *) *p)++;
|
||||
*path_len = *((UINT32 *) *p)++;
|
||||
|
||||
if (*path_len) {
|
||||
*path = *p;
|
||||
*p += *path_len;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user