Skip to content

Releases: HalfTimeOfLife/KDAMonitor

v0.10 - Thread Callback

Choose a tag to compare

@HalfTimeOfLife HalfTimeOfLife released this 24 Aug 21:40

Fifth sensor: thread creation and termination events are now captured via PsSetCreateThreadNotifyRoutine, queued, and written to disk as structured JSONL, alongside process, image load, network, and registry events.

Added

  • thread_callback.c/.h: KdaMonThreadCallbackRegister/KdaMonThreadCallbackUnregister, registers a thread creation callback via PsSetCreateThreadNotifyRoutine, capturing process ID, thread ID, creation/termination state, creator process ID, and process image path
  • Process image path resolution via PsLookupProcessByProcessId and SeLocateProcessImageName
  • event_types.h: KDAMON_THREAD_EVENT_DATA (PID, process path, TID, creation flag, creator PID)
  • log_writer.c: KdaMonLogWriterWriteThreadEvent, dispatched via switch in KdaMonLogWriterWriteEvent, serializing thread events to structured JSONL
  • Registered/unregistered in DriverEntry/DriverUnload, after the registry callback, with symmetric teardown order
  • KDAMON_THREAD_PATH_MAX added to kdamon_config.h for the fixed-size process path buffer

Changed

  • event_types.h: thread process path now uses KDAMON_THREAD_PATH_MAX from kdamon_config.h instead of a hard-coded size

Notes

  • Validated on a Windows test VM with a dedicated PowerShell test script covering local thread creation/termination and remote thread injection; logs confirm correct pid/creator_pid correlation, including pid != creator_pid for injected threads, with clean driver/service teardown and no BSOD

v0.9 - Registry Callback

Choose a tag to compare

@HalfTimeOfLife HalfTimeOfLife released this 17 Aug 19:54

Fourth sensor: registry activity (create/set/delete value, key creation) is now captured via CmRegisterCallbackEx, queued, and written to disk as structured JSONL, alongside process, image load, and network events.

Added

  • registry_callback.c/registry_callback.h: KdaMonRegistryCallbackRegister/KdaMonRegistryCallbackUnregister, registers a single registry callback at altitude 360000, dispatching on REG_NOTIFY_CLASS to RegNtPreSetValueKey, RegNtPreDeleteValueKey, and RegNtPostCreateKeyEx
  • Key path resolution via CmCallbackGetKeyObjectIDEx (avoids the deadlock risk documented for ObQueryNameString in registry callbacks), process path resolution via SeLocateProcessImageName
  • event_types.h: KDAMON_REGISTRY_EVENT_DATA (PID, process path, action, key path, value name, value type, raw value data with size, status), KDAMON_REGISTRY_ACTION enum (SET_VALUE/DELETE_VALUE/CREATE_KEY)
  • log_writer.c: KdaMonLogWriterWriteRegistryEvent, dispatched via switch in KdaMonLogWriterWriteEvent, with type-aware value_data formatting (string for REG_SZ/REG_EXPAND_SZ, decimal for REG_DWORD/REG_QWORD, hex for REG_BINARY and unhandled types)
  • NTSTATUS captured on create_key operations, surfaced as hex in logs
  • Registered/unregistered in DriverEntry/DriverUnload, right after the image load callback, consistent with all event producers being torn down before the queue and log writer
  • Reuses event_queue.c (v0.3) and the log writer pipeline (v0.4) unchanged

Changed

  • KDAMON_NETWORK_EVENT_DATA.ProcessId and KDAMON_REGISTRY_EVENT_DATA.ProcessId changed from ULONG to HANDLE, matching the process sensor and correct Windows PID typing

Notes

  • Validated on Windows test VM: reg add/reg delete covering all three actions and all major value types (REG_SZ, REG_EXPAND_SZ, REG_DWORD, REG_QWORD, REG_BINARY); clean load/unload with no BSOD or orphaned kernel callback
  • set_value/delete_value have no captured status (Pre-only notifications); REG_MULTI_SZ logged as hex rather than parsed into individual strings

v0.8 - Network Callout

Choose a tag to compare

@HalfTimeOfLife HalfTimeOfLife released this 08 Aug 22:44

Third sensor: outbound and inbound IPv4 network connections are now captured via WFP callouts, queued, and written to disk as structured JSONL, alongside process and image load events.

Added

  • wfp_callout.c/wfp_callout.h: KdaMonWfpCalloutRegister/KdaMonWfpCalloutUnregister, registers two callouts (KDAMonitor Callout Outbound/Inbound) on FWPM_LAYER_ALE_AUTH_CONNECT_V4 and FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4, each with an associated filter
  • guids.c: centralized DEFINE_GUID declarations (session + callout GUIDs), replacing the inline DEFINE_GUID/INITGUID previously in wfp_session.c
  • event_types.h: KDAMON_NETWORK_EVENT_DATA (PID, process path, protocol, local/remote IP and port, direction)
  • log_writer.c: KdaMonLogWriterWriteNetworkEvent, dispatched via switch in KdaMonLogWriterWriteEvent
  • Registered/unregistered in DriverEntry/DriverUnload, right after the event queue, consistent with all event producers being torn down before the queue and log writer
  • Reuses event_queue.c (v0.3) and the log writer pipeline (v0.4) unchanged

Changed

  • wfp_session.c: g_EngineHandle no longer static, exposed via wfp_session.h so wfp_callout.c can reuse the same WFP session handle
  • wfp_session.c: subLayer.weight changed from 0 to 0xFFFF (highest sublayer priority)

Notes

  • Filters use FWP_ACTION_CALLOUT_INSPECTION rather than FWP_ACTION_CALLOUT_TERMINATING
  • Validated on Windows test VM: netsh wfp show state/show filters confirm provider, sublayer, both callouts, and both filters registered on load, absent on unload
  • IPv6 not yet covered (V4-only layers, LocalIp/RemoteIp stored as 32-bit ULONG) — planned as a post-v1.0 follow-up

v0.7 - WFP session setup

Choose a tag to compare

@HalfTimeOfLife HalfTimeOfLife released this 04 Aug 19:50

WFP session infrastructure: opens the WFP engine and registers the provider/sublayer that the network callout (v0.8) will attach to. No traffic filtering yet.

Added

  • wfp_session.c/.h: KdaMonWfpSessionInit/KdaMonWfpSessionCleanup, opens a WFP engine session, registers KDAMonitor Provider and KDAMonitor Sublayer with dedicated GUIDs
  • Registered early in DriverEntry (right after device creation, before the event queue), unregistered symmetrically last in DriverUnload (before device deletion), consistent with treating the WFP session as infrastructure rather than an event producer

v0.6 - Image Load Callback

Choose a tag to compare

@HalfTimeOfLife HalfTimeOfLife released this 02 Aug 22:11

Second sensor: every image (DLL/EXE) loaded into any process is captured, pushed into the existing queue, and written to the log through the standard pipeline.

Added

  • image_callback.c/.h: PsSetLoadImageNotifyRoutine callback, captures image base, size, properties, system/mapped/partial-map flags, signature level/type, and full image path
  • Registered/unregistered in DriverEntry/DriverUnload, after the process callback (unregistered first, symmetric teardown order)
  • event_types.h: KDAMON_IMAGE_LOAD_EVENT_DATA (PID, image base/size, properties, three BOOLEAN-as-ULONG flags, signature level/type, fixed-size image name)
  • log_writer.c: KdaMonLogWriterWriteImageEvent, dispatched via switch in KdaMonLogWriterWriteEvent

v0.5 - Process Callback

Choose a tag to compare

@HalfTimeOfLife HalfTimeOfLife released this 02 Aug 11:57

The first sensor is live: process create/exit events are now captured, queued, and written to disk as structured JSONL.

Added

  • process_callback.c/process_callback.h: PsSetCreateProcessNotifyRoutineEx callback, logs process create/exit
  • Registered/unregistered in DriverEntry/DriverUnload
  • event_types.h: KDAMON_PROCESS_EVENT_DATA (PID, PPID, create/exit flag, fixed-size image name)
  • log_writer.c: KdaMonLogWriterWriteProcessEvent, dispatched via switch in KdaMonLogWriterWriteEvent
  • log_writer.c: KdaMonJsonEscapeW helper for safe JSON string escaping of NT-style paths
  • Reuses event_queue.c (v0.3) and the log writer pipeline (v0.4) unchanged

Fixed

  • EventBuffer in log_writer.c undersized for worst-case process event payload (256 → 1000 bytes), causing silent event drops on long paths
  • ppid now serialized as JSON null instead of 0 for exit events, where no parent PID is provided by the kernel

Notes

  • Validated on Windows test VM: process create/exit lifecycle confirmed via DbgView and resulting .jsonl

v0.4 - Log Writer

Choose a tag to compare

@HalfTimeOfLife HalfTimeOfLife released this 30 Jul 12:45

The queue now empties itself automatically to a log file on disk.

Added

  • log_writer.c/log_writer.h: system thread draining the event queue
  • Writes JSONL log to disk (one file per session), independent of client presence
  • Auto-creates C:\KDAMonitor\ and C:\KDAMonitor\logs\ if missing
  • Reuses event_queue.c introduced in v0.3, adds a WakeEvent so the thread blocks instead of polling

Fixed

  • Bugcheck IRQL_NOT_LESS_OR_EQUAL (0xA) caused by zeroing the event queue struct after initializing its wake event
  • Undeclared STATUS_* identifiers due to incorrect ntstatus.h/ntddk.h include order
  • Unresolved externals (__stdio_common_vswprintf/vsprintf) from ntstrsafe.h's inline implementation

Notes

  • Validated end-to-end on Windows test VM: device creation, log file creation, event push/pop, JSONL write all confirmed working

v0.3 - Kernel Event Queue

Choose a tag to compare

@HalfTimeOfLife HalfTimeOfLife released this 30 Jul 12:44

Added a kernel-mode event queue used to buffer activity events before they're consumed (by the log writer in v0.4 onward).

Added

  • event_types.h: KDAMON_EVENT structure (type, timestamp, unique ID), KDAMON_EVENT_TYPE enum with TODO placeholders for future event types
  • event_queue.c/event_queue.h: ring buffer + spinlock, push/pop API, dropped events counter

Notes

  • Push/pop validated via a temporary in-driver test in DriverEntry (FIFO order, unique incrementing IDs, correct count after push/pop)

v0.2 - Device, IOCTL Echo & Test Client

Choose a tag to compare

@HalfTimeOfLife HalfTimeOfLife released this 26 Jul 22:32

Added a device object and IOCTL echo response, along with a small usermode test client.

Added

  • device.c: device object creation, symbolic link, DO_BUFFERED_IO flag
  • ioctl.c: IRP_MJ_CREATE/IRP_MJ_CLOSE and IRP_MJ_DEVICE_CONTROL dispatch routines
  • kdamon_shared.h: IOCTL_KDAMON_ECHO code and request/reply structures
  • client/: minimal usermode test client validating the echo round-trip

Notes

  • Validated on Windows test VM

v0.1 - Driver Skeleton

Choose a tag to compare

@HalfTimeOfLife HalfTimeOfLife released this 24 Jul 10:25

First release of KDAMonitor.

Added

  • DriverEntry / DriverUnload
  • Windows version detection via RtlGetVersion

Notes

  • Validated on Windows test VM