Merge branch 'add-transaction-logging'

This commit is contained in:
Odd Stranne
2021-02-19 11:52:10 +01:00
8 changed files with 175 additions and 61 deletions

View File

@@ -2,13 +2,15 @@
enum ST_EVENT_ID
{
ST_EVENT_START_SPLITTING_PROCESS = 0, // ST_SPLITTING_EVENT
ST_EVENT_STOP_SPLITTING_PROCESS, // ST_SPLITTING_EVENT
ST_EVENT_ID_START_SPLITTING_PROCESS = 0, // ST_SPLITTING_EVENT
ST_EVENT_ID_STOP_SPLITTING_PROCESS, // ST_SPLITTING_EVENT
ST_EVENT_ERROR_FLAG = 0x80000000,
ST_EVENT_ID_ERROR_FLAG = 0x80000000,
ST_EVENT_ERROR_START_SPLITTING_PROCESS, // ST_SPLITTING_ERROR_EVENT
ST_EVENT_ERROR_STOP_SPLITTING_PROCESS // ST_SPLITTING_ERROR_EVENT
ST_EVENT_ID_ERROR_START_SPLITTING_PROCESS, // ST_SPLITTING_ERROR_EVENT
ST_EVENT_ID_ERROR_STOP_SPLITTING_PROCESS, // ST_SPLITTING_ERROR_EVENT
ST_EVENT_ID_ERROR_MESSAGE // ST_ERROR_MESSAGE_EVENT
};
typedef struct tag_ST_EVENT_HEADER
@@ -54,3 +56,14 @@ typedef struct tag_ST_SPLITTING_ERROR_EVENT
WCHAR ImageName[ANYSIZE_ARRAY];
}
ST_SPLITTING_ERROR_EVENT;
typedef struct tag_ST_ERROR_MESSAGE_EVENT
{
NTSTATUS Status;
// Byte length for non-null terminated wide char string.
USHORT ErrorMessageLength;
WCHAR ErrorMessage[ANYSIZE_ARRAY];
}
ST_ERROR_MESSAGE_EVENT;

View File

@@ -31,7 +31,7 @@ BuildSplittingEvent
auto header = (ST_EVENT_HEADER*)buffer;
auto evt = (ST_SPLITTING_EVENT*)(((UCHAR*)buffer) + FIELD_OFFSET(ST_EVENT_HEADER, EventData));
header->EventId = (Start ? ST_EVENT_START_SPLITTING_PROCESS : ST_EVENT_STOP_SPLITTING_PROCESS);
header->EventId = (Start ? ST_EVENT_ID_START_SPLITTING_PROCESS : ST_EVENT_ID_STOP_SPLITTING_PROCESS);
header->EventSize = eventSize;
evt->ProcessId = ProcessId;
@@ -70,7 +70,7 @@ BuildSplittingErrorEvent
auto header = (ST_EVENT_HEADER*)buffer;
auto evt = (ST_SPLITTING_ERROR_EVENT*)(((UCHAR*)buffer) + FIELD_OFFSET(ST_EVENT_HEADER, EventData));
header->EventId = (Start ? ST_EVENT_ERROR_START_SPLITTING_PROCESS : ST_EVENT_ERROR_STOP_SPLITTING_PROCESS);
header->EventId = (Start ? ST_EVENT_ID_ERROR_START_SPLITTING_PROCESS : ST_EVENT_ID_ERROR_STOP_SPLITTING_PROCESS);
header->EventSize = eventSize;
evt->ProcessId = ProcessId;
@@ -192,6 +192,38 @@ BuildStopSplittingErrorEvent
return WrapEvent(buffer, bufferSize);
}
RAW_EVENT*
BuildErrorMessageEvent
(
NTSTATUS Status,
const UNICODE_STRING *ErrorMessage
)
{
auto headerSize = FIELD_OFFSET(ST_EVENT_HEADER, EventData);
auto eventSize = FIELD_OFFSET(ST_ERROR_MESSAGE_EVENT, ErrorMessage) + ErrorMessage->Length;
auto allocationSize = headerSize + eventSize;
auto buffer = ExAllocatePoolWithTag(NonPagedPool, allocationSize, ST_POOL_TAG);
if (buffer == NULL)
{
return NULL;
}
auto header = (ST_EVENT_HEADER*)buffer;
auto evt = (ST_ERROR_MESSAGE_EVENT*)(((UCHAR*)buffer) + FIELD_OFFSET(ST_EVENT_HEADER, EventData));
header->EventId = ST_EVENT_ID_ERROR_MESSAGE;
header->EventSize = eventSize;
evt->Status = Status;
evt->ErrorMessageLength = ErrorMessage->Length;
RtlCopyMemory(evt->ErrorMessage, ErrorMessage->Buffer, ErrorMessage->Length);
return WrapEvent(buffer, allocationSize);
}
void
ReleaseEvent
(

View File

@@ -38,6 +38,13 @@ BuildStopSplittingErrorEvent
LOWER_UNICODE_STRING *ImageName
);
RAW_EVENT*
BuildErrorMessageEvent
(
NTSTATUS Status,
const UNICODE_STRING *ErrorMessage
);
void
ReleaseEvent
(

View File

@@ -5,6 +5,7 @@
#include "firewall.h"
#include "../ipaddr.h"
#include "../procbroker/procbroker.h"
#include "../eventing/eventing.h"
namespace firewall
{
@@ -92,6 +93,8 @@ struct CONTEXT
procbroker::CONTEXT *ProcessEventBroker;
eventing::CONTEXT *Eventing;
TRANSACTION_MGMT Transaction;
//

View File

@@ -7,6 +7,7 @@
#include "constants.h"
#include "asyncbind.h"
#include "../util.h"
#include "../eventing/builder.h"
#include "firewall.h"
namespace firewall
@@ -244,6 +245,72 @@ ResetClientCallbacks
Context->Callbacks.Context = NULL;
}
NTSTATUS
WfpTransactionBegin
(
CONTEXT *Context
)
{
auto status = FwpmTransactionBegin0(Context->WfpSession, 0);
if (!NT_SUCCESS(status))
{
DbgPrint("Could not create WFP transaction: 0x%X", status);
DECLARE_CONST_UNICODE_STRING(errorMessage, L"Could not create WFP transaction");
auto evt = eventing::BuildErrorMessageEvent(status, &errorMessage);
eventing::Emit(Context->Eventing, &evt);
}
return status;
}
NTSTATUS
WfpTransactionCommit
(
CONTEXT *Context
)
{
auto status = FwpmTransactionCommit0(Context->WfpSession);
if (!NT_SUCCESS(status))
{
DbgPrint("Could not commit WFP transaction: 0x%X", status);
DECLARE_CONST_UNICODE_STRING(errorMessage, L"Could not commit WFP transaction");
auto evt = eventing::BuildErrorMessageEvent(status, &errorMessage);
eventing::Emit(Context->Eventing, &evt);
}
return status;
}
NTSTATUS
WfpTransactionAbort
(
CONTEXT *Context
)
{
auto status = FwpmTransactionAbort0(Context->WfpSession);
if (!NT_SUCCESS(status))
{
DbgPrint("Could not abort WFP transaction: 0x%X", status);
DECLARE_CONST_UNICODE_STRING(errorMessage, L"Could not abort WFP transaction");
auto evt = eventing::BuildErrorMessageEvent(status, &errorMessage);
eventing::Emit(Context->Eventing, &evt);
}
return status;
}
} // anonymous namespace
//
@@ -262,7 +329,8 @@ Initialize
CONTEXT **Context,
PDEVICE_OBJECT DeviceObject,
const CALLBACKS *Callbacks,
procbroker::CONTEXT *ProcessEventBroker
procbroker::CONTEXT *ProcessEventBroker,
eventing::CONTEXT *Eventing
)
{
auto context = (CONTEXT*)ExAllocatePoolWithTag(NonPagedPool, sizeof(CONTEXT), ST_POOL_TAG);
@@ -279,6 +347,7 @@ Initialize
context->IpAddresses.Ipv6Action = IPV6_ACTION::NONE;
context->Callbacks = *Callbacks;
context->ProcessEventBroker = ProcessEventBroker;
context->Eventing = Eventing;
auto status = WdfWaitLockCreate(WDF_NO_OBJECT_ATTRIBUTES, &context->IpAddresses.Lock);
@@ -498,7 +567,7 @@ EnableSplitting
// Update WFP inside a transaction.
//
auto status = FwpmTransactionBegin0(Context->WfpSession, 0);
auto status = WfpTransactionBegin(Context);
if (!NT_SUCCESS(status))
{
@@ -542,12 +611,10 @@ EnableSplitting
// Commit filters.
//
status = FwpmTransactionCommit0(Context->WfpSession);
status = WfpTransactionCommit(Context);
if (!NT_SUCCESS(status))
{
DbgPrint("Failed to commit transaction\n");
goto Abort;
}
@@ -557,14 +624,7 @@ EnableSplitting
Abort:
//
// Do not overwrite error code in status variable.
//
if (!NT_SUCCESS(FwpmTransactionAbort0(Context->WfpSession)))
{
DbgPrint("Failed to abort transaction\n");
}
WfpTransactionAbort(Context);
return status;
}
@@ -637,14 +697,7 @@ DisableSplitting
Abort:
//
// Do not overwrite error code in status variable.
//
if (!NT_SUCCESS(TransactionAbort(Context)))
{
DbgPrint("Failed to abort transaction\n");
}
TransactionAbort(Context);
return status;
}
@@ -681,7 +734,7 @@ RegisterUpdatedIpAddresses
// or are registered conditionally depending on which IP addresses are present.
//
auto status = FwpmTransactionBegin0(Context->WfpSession, 0);
auto status = WfpTransactionBegin(Context);
if (!NT_SUCCESS(status))
{
@@ -769,14 +822,12 @@ RegisterUpdatedIpAddresses
// Finalize.
//
status = FwpmTransactionCommit0(Context->WfpSession);
status = WfpTransactionCommit(Context);
if (!NT_SUCCESS(status))
{
blocking::TransactionAbort(Context->BlockingContext);
DbgPrint("Failed to commit transaction\n");
goto Abort;
}
@@ -793,14 +844,7 @@ RegisterUpdatedIpAddresses
Abort:
//
// Do not overwrite error code in status variable.
//
if (!NT_SUCCESS(FwpmTransactionAbort0(Context->WfpSession)))
{
DbgPrint("Failed to abort transaction\n");
}
WfpTransactionAbort(Context);
return status;
}
@@ -820,12 +864,10 @@ TransactionBegin
WdfWaitLockAcquire(Context->Transaction.Lock, NULL);
auto status = FwpmTransactionBegin0(Context->WfpSession, 0);
auto status = WfpTransactionBegin(Context);
if (!NT_SUCCESS(status))
{
DbgPrint("Could not create WFP transaction: 0x%X", status);
goto Abort;
}
@@ -845,12 +887,7 @@ TransactionBegin
Abort_cancel_wfp:
auto s2 = FwpmTransactionAbort0(Context->WfpSession);
if (!NT_SUCCESS(s2))
{
DbgPrint("Could not abort WFP transaction: 0x%X", s2);
}
WfpTransactionAbort(Context);
Abort:
@@ -880,12 +917,10 @@ TransactionCommit
return STATUS_UNSUCCESSFUL;
}
auto status = FwpmTransactionCommit0(Context->WfpSession);
auto status = WfpTransactionCommit(Context);
if (!NT_SUCCESS(status))
{
DbgPrint("Could not commit WFP transaction: 0x%X", status);
return status;
}
@@ -920,12 +955,10 @@ TransactionAbort
return STATUS_UNSUCCESSFUL;
}
auto status = FwpmTransactionAbort0(Context->WfpSession);
auto status = WfpTransactionAbort(Context);
if (!NT_SUCCESS(status))
{
DbgPrint("Could not abort WFP transaction: 0x%X", status);
return status;
}

View File

@@ -4,6 +4,7 @@
#include "../ipaddr.h"
#include "../defs/types.h"
#include "../procbroker/procbroker.h"
#include "../eventing/eventing.h"
namespace firewall
{
@@ -53,7 +54,8 @@ Initialize
CONTEXT **Context,
PDEVICE_OBJECT DeviceObject,
const CALLBACKS *Callbacks,
procbroker::CONTEXT *ProcessEventBroker
procbroker::CONTEXT *ProcessEventBroker,
eventing::CONTEXT *Eventing
);
NTSTATUS

View File

@@ -898,7 +898,8 @@ Initialize
&context->Firewall,
WdfDeviceWdmGetDeviceObject(Device),
&callbacks,
context->ProcessEventBroker
context->ProcessEventBroker,
context->Eventing
);
if (!NT_SUCCESS(status))

View File

@@ -5,6 +5,8 @@
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <iomanip>
#include <windows.h>
#include <conio.h>
#include <ip2string.h>
@@ -600,6 +602,19 @@ void DisplaySplittingErrorEvent(const ST_SPLITTING_ERROR_EVENT *evt, size_t /*ev
std::wcout << L"Imagename: " << imageName << std::endl;
}
void DisplayErrorMessageEvent(const ST_ERROR_MESSAGE_EVENT *evt, size_t /*eventSize*/)
{
std::wstringstream ss;
ss << L"Status: 0x" << std::setw(8) << std::setfill(L'0') << std::hex << evt->Status;
std::wcout << ss.str() << std::endl;
std::wstring message(&evt->ErrorMessage[0], &evt->ErrorMessage[0] + (evt->ErrorMessageLength / sizeof(wchar_t)));
std::wcout << L"Error message: " << message << std::endl;
}
void ParseDisplayEvent(const uint8_t *evt, size_t eventSize)
{
if (!g_DisplayEvents)
@@ -615,7 +630,7 @@ void ParseDisplayEvent(const uint8_t *evt, size_t eventSize)
switch (header->EventId)
{
case ST_EVENT_START_SPLITTING_PROCESS:
case ST_EVENT_ID_START_SPLITTING_PROCESS:
{
std::wcout << L"Type: ST_EVENT_START_SPLITTING_PROCESS" << std::endl;
@@ -623,7 +638,7 @@ void ParseDisplayEvent(const uint8_t *evt, size_t eventSize)
break;
}
case ST_EVENT_STOP_SPLITTING_PROCESS:
case ST_EVENT_ID_STOP_SPLITTING_PROCESS:
{
std::wcout << L"Type: ST_EVENT_STOP_SPLITTING_PROCESS" << std::endl;
@@ -631,7 +646,7 @@ void ParseDisplayEvent(const uint8_t *evt, size_t eventSize)
break;
}
case ST_EVENT_ERROR_START_SPLITTING_PROCESS:
case ST_EVENT_ID_ERROR_START_SPLITTING_PROCESS:
{
std::wcout << L"Type: ST_EVENT_ERROR_START_SPLITTING_PROCESS" << std::endl;
@@ -639,7 +654,7 @@ void ParseDisplayEvent(const uint8_t *evt, size_t eventSize)
break;
}
case ST_EVENT_ERROR_STOP_SPLITTING_PROCESS:
case ST_EVENT_ID_ERROR_STOP_SPLITTING_PROCESS:
{
std::wcout << L"Type: ST_EVENT_ERROR_STOP_SPLITTING_PROCESS" << std::endl;
@@ -647,6 +662,14 @@ void ParseDisplayEvent(const uint8_t *evt, size_t eventSize)
break;
}
case ST_EVENT_ID_ERROR_MESSAGE:
{
std::wcout << L"Type: ST_EVENT_ID_ERROR_MESSAGE" << std::endl;
DisplayErrorMessageEvent((ST_ERROR_MESSAGE_EVENT*)&header->EventData[0], header->EventSize);
break;
}
default:
{
std::wcout << L"Unsupported event" << std::endl;