Skip to content

Commit

Permalink
restored old behavior for data capture
Browse files Browse the repository at this point in the history
  • Loading branch information
hugsy committed Mar 23, 2024
1 parent 792252f commit 4cb40b4
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 150 deletions.
192 changes: 96 additions & 96 deletions Driver/Headers/Context.hpp
Original file line number Diff line number Diff line change
@@ -1,96 +1,96 @@
#pragma once

// clang-format off
#include "Common.hpp"
#include "DriverUtils.hpp"
#include "Log.hpp"

#include "CapturedIrpManager.hpp"
#include "HookedDriverManager.hpp"
// clang-format on


#define CFB_MAX_HEXDUMP_BYTE 128

namespace Driver = CFB::Driver;
namespace Utils = CFB::Driver::Utils;

struct GlobalContext
{
///
/// @brief Any critical read/write operation to the global context structure must acquire this lock.
///
Utils::KQueuedSpinLock ContextLock;

///
/// @brief A pointer to the device object
///
PDRIVER_OBJECT DriverObject;

///
/// @brief A pointer to the device object
///
PDEVICE_OBJECT DeviceObject;

///
/// @brief A pointer to the EPROCESS of the broker. Not more than one handle to the
/// device is allowed.
///
PEPROCESS Owner;

///
/// @brief Incremental session ID number.
///
ULONG SessionId;

///
/// @brief Manages the hooked drivers
///
Driver::HookedDriverManager DriverManager;

///
/// @brief Where all the intercepted IRPs are stored
///
Driver::CapturedIrpManager IrpManager;


GlobalContext() : DriverObject {nullptr}, DeviceObject {nullptr}, Owner {nullptr}, ContextLock {}, SessionId(-1)
{
dbg("Creating GlobalContext");
}


~GlobalContext()
{
dbg("Destroying GlobalContext");
DriverObject = nullptr;
DeviceObject = nullptr;
Owner = nullptr;
}

static void*
operator new(usize sz)
{
void* Memory = ::ExAllocatePoolWithTag(NonPagedPoolNx, sz, CFB_DEVICE_TAG);
if ( Memory )
{
dbg("Allocated GlobalContext at %p", Memory);
::RtlSecureZeroMemory(Memory, sz);
}
return Memory;
}

static void
operator delete(void* m)
{
dbg("Deallocating GlobalContext");
::ExFreePoolWithTag(m, CFB_DEVICE_TAG);
m = nullptr;
return;
}
};

///
/// @brief Reference to the global driver context.
///
extern struct GlobalContext* Globals;
#pragma once

// clang-format off
#include "Common.hpp"
#include "DriverUtils.hpp"
#include "Log.hpp"

#include "CapturedIrpManager.hpp"
#include "HookedDriverManager.hpp"
// clang-format on


#define CFB_MAX_HEXDUMP_BYTE 64

namespace Driver = CFB::Driver;
namespace Utils = CFB::Driver::Utils;

struct GlobalContext
{
///
/// @brief Any critical read/write operation to the global context structure must acquire this lock.
///
Utils::KQueuedSpinLock ContextLock;

///
/// @brief A pointer to the device object
///
PDRIVER_OBJECT DriverObject;

///
/// @brief A pointer to the device object
///
PDEVICE_OBJECT DeviceObject;

///
/// @brief A pointer to the EPROCESS of the broker. Not more than one handle to the
/// device is allowed.
///
PEPROCESS Owner;

///
/// @brief Incremental session ID number.
///
ULONG SessionId;

///
/// @brief Manages the hooked drivers
///
Driver::HookedDriverManager DriverManager;

///
/// @brief Where all the intercepted IRPs are stored
///
Driver::CapturedIrpManager IrpManager;


GlobalContext() : DriverObject {nullptr}, DeviceObject {nullptr}, Owner {nullptr}, ContextLock {}, SessionId(-1)
{
dbg("Creating GlobalContext");
}


~GlobalContext()
{
dbg("Destroying GlobalContext");
DriverObject = nullptr;
DeviceObject = nullptr;
Owner = nullptr;
}

static void*
operator new(usize sz)
{
void* Memory = ::ExAllocatePoolWithTag(NonPagedPoolNx, sz, CFB_DEVICE_TAG);
if ( Memory )
{
dbg("Allocated GlobalContext at %p", Memory);
::RtlSecureZeroMemory(Memory, sz);
}
return Memory;
}

static void
operator delete(void* m)
{
dbg("Deallocating GlobalContext");
::ExFreePoolWithTag(m, CFB_DEVICE_TAG);
m = nullptr;
return;
}
};

///
/// @brief Reference to the global driver context.
///
extern struct GlobalContext* Globals;
97 changes: 47 additions & 50 deletions Driver/Source/CapturedIrp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ CapturedIrp::CapturePreCallData(_In_ PIRP Irp)
return STATUS_UNSUCCESSFUL;
}

NTSTATUS Status = STATUS_UNSUCCESSFUL;
const ULONG Flags = m_DeviceObject->Flags;
const PIO_STACK_LOCATION Stack = ::IoGetCurrentIrpStackLocation(Irp);

Expand All @@ -164,8 +165,9 @@ CapturedIrp::CapturePreCallData(_In_ PIRP Irp)

dbg("CapturePreCallData(%p)", Irp);

m_MajorFunction = Stack->MajorFunction;
m_MinorFunction = Stack->MinorFunction;
m_MajorFunction = Stack->MajorFunction;
m_MinorFunction = Stack->MinorFunction;
const ULONG Method = METHOD_FROM_CTL_CODE(m_IoctlCode);

//
// Determine & allocate the input/output buffer sizes from the IRP for "normal" IOCTLs
Expand Down Expand Up @@ -198,74 +200,69 @@ CapturedIrp::CapturePreCallData(_In_ PIRP Irp)
//
// Now, copy the input/output buffer content to the CapturedIrp object
//
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PVOID Buffer = m_InputBuffer.get();
ULONG BufferLength = m_InputBuffer.size();

switch ( m_MajorFunction )
{
case IRP_MJ_DEVICE_CONTROL:
case IRP_MJ_INTERNAL_DEVICE_CONTROL:
// __try // TODO fix unwinding
{
//
// Handle NEITHER method for IOCTLs
//
if ( METHOD_FROM_CTL_CODE(m_IoctlCode) == METHOD_NEITHER )
Status = STATUS_SUCCESS;
do
{
if ( Stack->Parameters.DeviceIoControl.Type3InputBuffer < (PVOID)(1 << 16) )
if ( (Stack->MajorFunction == IRP_MJ_DEVICE_CONTROL ||
Stack->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) &&
Method == METHOD_NEITHER )
{
return STATUS_INVALID_PARAMETER;
if ( Stack->Parameters.DeviceIoControl.Type3InputBuffer >= (PVOID)(1 << 16) )
RtlCopyMemory(Buffer, Stack->Parameters.DeviceIoControl.Type3InputBuffer, BufferLength);
else
Status = STATUS_INVALID_PARAMETER;
break;
}

::memcpy(m_InputBuffer.get(), Stack->Parameters.DeviceIoControl.Type3InputBuffer, m_InputBuffer.size());
Status = STATUS_SUCCESS;
}
break;
}
default:
{
//
// Otherwise, use copy method from flags
//
if ( Flags & DO_BUFFERED_IO )
{
if ( !Irp->AssociatedIrp.SystemBuffer )
if ( Method == METHOD_BUFFERED )
{
return STATUS_INVALID_PARAMETER_1;
if ( Irp->AssociatedIrp.SystemBuffer )
RtlCopyMemory(Buffer, Irp->AssociatedIrp.SystemBuffer, BufferLength);
else
Status = STATUS_INVALID_PARAMETER_1;
break;
}

::memcpy(m_InputBuffer.get(), Irp->AssociatedIrp.SystemBuffer, m_InputBuffer.size());
Status = STATUS_SUCCESS;
}
else if ( Flags & DO_DIRECT_IO )
{
if ( !Irp->MdlAddress )
if ( Method == METHOD_IN_DIRECT || Method == METHOD_OUT_DIRECT )
{
return STATUS_INVALID_PARAMETER_2;
if ( !Irp->MdlAddress )
{
Status = STATUS_INVALID_PARAMETER_2;
break;
}

PVOID pDataAddr = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
if ( !pDataAddr )
{
Status = STATUS_INVALID_PARAMETER_3;
break;
}

RtlCopyMemory(Buffer, pDataAddr, BufferLength);
}

PVOID pDataAddr = ::MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
if ( !pDataAddr )
{
return STATUS_INVALID_PARAMETER_3;
}

::memcpy(m_InputBuffer.get(), pDataAddr, m_InputBuffer.size());
Status = STATUS_SUCCESS;
}
break;
}
} while ( 0 );
}
// __except (EXCEPTION_EXECUTE_HANDLER)
// {
// Status = GetExceptionCode();
// }

if ( !NT_SUCCESS(Status) )
{
err("CapturePreCallData() returned %#08x", Status);
}
#ifdef _DEBUG
// #ifdef _DEBUG
else
{
dbg("Captured input data (%lu bytes):", m_InputBuffer.size());
CFB::Utils::Hexdump(m_InputBuffer.get(), MIN(m_InputBuffer.size(), CFB_MAX_HEXDUMP_BYTE));
}
#endif // _DEBUG
// #endif // _DEBUG

return STATUS_SUCCESS;
}
Expand Down Expand Up @@ -336,10 +333,10 @@ CapturedIrp::CapturePostCallData(_In_ PIRP Irp, _In_ NTSTATUS ReturnedIoctlStatu
//
::memcpy(m_OutputBuffer.get() + Offset, UserBuffer, Count);

#ifdef _DEBUG
// #ifdef _DEBUG
dbg("Capturing output data:");
CFB::Utils::Hexdump(m_OutputBuffer.get(), MIN(m_OutputBuffer.size(), CFB_MAX_HEXDUMP_BYTE));
#endif // _DEBUG
// #endif // _DEBUG

return STATUS_SUCCESS;
}
Expand Down
8 changes: 4 additions & 4 deletions Driver/Source/Entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,9 +361,9 @@ _Function_class_(DRIVER_DISPATCH) DriverReadRoutine(_In_ PDEVICE_OBJECT DeviceOb
i + 1,
DumpableIrpNumber,
CurrentIrp->InputDataSize());
#ifdef _DEBUG
// #ifdef _DEBUG
CFB::Utils::Hexdump(Buffer, MIN(CurrentIrp->InputDataSize(), CFB_MAX_HEXDUMP_BYTE));
#endif // _DEBUG
// #endif // _DEBUG
}

//
Expand All @@ -385,9 +385,9 @@ _Function_class_(DRIVER_DISPATCH) DriverReadRoutine(_In_ PDEVICE_OBJECT DeviceOb
i + 1,
DumpableIrpNumber,
CurrentIrp->OutputDataSize());
#ifdef _DEBUG
// #ifdef _DEBUG
CFB::Utils::Hexdump(Buffer, MIN(CurrentIrp->OutputDataSize(), CFB_MAX_HEXDUMP_BYTE));
#endif // _DEBUG
// #endif // _DEBUG
}

dbg("IRP %d/%d returned to client", i + 1, DumpableIrpNumber);
Expand Down

0 comments on commit 4cb40b4

Please sign in to comment.