HyperDbg Debugger
Loading...
Searching...
No Matches
HyperDbgHyperLogImports.h File Reference

Headers relating exported functions from hyperlog project. More...

Go to the source code of this file.

Macros

#define IMPORT_EXPORT_HYPERLOG   __declspec(dllimport)
 

Functions

IMPORT_EXPORT_HYPERLOG BOOLEAN LogInitialize (MESSAGE_TRACING_CALLBACKS *MsgTracingCallbacks)
 Initialize the buffer relating to log message tracing.
 
IMPORT_EXPORT_HYPERLOG VOID LogUnInitialize ()
 Uninitialize the buffer relating to log message tracing.
 
IMPORT_EXPORT_HYPERLOG UINT32 LogMarkAllAsRead (BOOLEAN IsVmxRoot)
 Mark all buffers as read.
 
IMPORT_EXPORT_HYPERLOG BOOLEAN LogCallbackPrepareAndSendMessageToQueue (UINT32 OperationCode, BOOLEAN IsImmediateMessage, BOOLEAN ShowCurrentSystemTime, BOOLEAN Priority, const char *Fmt,...)
 routines callback for preparing and sending message to queue
 
IMPORT_EXPORT_HYPERLOG BOOLEAN LogCallbackPrepareAndSendMessageToQueueWrapper (UINT32 OperationCode, BOOLEAN IsImmediateMessage, BOOLEAN ShowCurrentSystemTime, BOOLEAN Priority, const char *Fmt, va_list ArgList)
 Prepare a printf-style message mapping and send string messages and tracing for logging and monitoring.
 
IMPORT_EXPORT_HYPERLOG BOOLEAN LogCallbackSendBuffer (_In_ UINT32 OperationCode, _In_reads_bytes_(BufferLength) PVOID Buffer, _In_ UINT32 BufferLength, _In_ BOOLEAN Priority)
 routines callback for sending buffer
 
IMPORT_EXPORT_HYPERLOG BOOLEAN LogCallbackCheckIfBufferIsFull (BOOLEAN Priority)
 routines callback for checking if buffer is full
 
IMPORT_EXPORT_HYPERLOG BOOLEAN LogCallbackSendMessageToQueue (UINT32 OperationCode, BOOLEAN IsImmediateMessage, CHAR *LogMessage, UINT32 BufferLen, BOOLEAN Priority)
 routines callback for sending message to queue
 
IMPORT_EXPORT_HYPERLOG BOOLEAN LogRegisterEventBasedNotification (PVOID TargetIrp)
 Create an event-based usermode notifying mechanism.
 
IMPORT_EXPORT_HYPERLOG BOOLEAN LogRegisterIrpBasedNotification (PVOID TargetIrp, LONG *Status)
 Register a new IRP Pending thread which listens for new buffers.
 

Detailed Description

Headers relating exported functions from hyperlog project.

Author
Sina Karvandi (sina@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)
Version
0.1
Date
2023-01-15

Macro Definition Documentation

◆ IMPORT_EXPORT_HYPERLOG

#define IMPORT_EXPORT_HYPERLOG   __declspec(dllimport)

Function Documentation

◆ LogCallbackCheckIfBufferIsFull()

IMPORT_EXPORT_HYPERLOG BOOLEAN LogCallbackCheckIfBufferIsFull ( BOOLEAN Priority)

routines callback for checking if buffer is full

Parameters
Priority
Returns
BOOLEAN

routines callback for checking if buffer is full

Parameters
PriorityWhether the buffer has priority
Returns
BOOLEAN Returns true if the buffer is full, otherwise, return false
101{
103 {
104 //
105 // Ignore sending message to queue
106 //
107 return FALSE;
108 }
109
111}
#define FALSE
Definition BasicTypes.h:54
VMM_CALLBACKS g_Callbacks
List of callbacks.
Definition GlobalVariables.h:32
LOG_CALLBACK_CHECK_IF_BUFFER_IS_FULL LogCallbackCheckIfBufferIsFull
Definition VMM.h:188

◆ LogCallbackPrepareAndSendMessageToQueue()

IMPORT_EXPORT_HYPERLOG BOOLEAN LogCallbackPrepareAndSendMessageToQueue ( UINT32 OperationCode,
BOOLEAN IsImmediateMessage,
BOOLEAN ShowCurrentSystemTime,
BOOLEAN Priority,
const char * Fmt,
... )

routines callback for preparing and sending message to queue

Parameters
OperationCode
IsImmediateMessage
ShowCurrentSystemTime
Priority
Fmt
...
Returns
BOOLEAN

routines callback for preparing and sending message to queue

Parameters
OperationCodeOptional operation code
IsImmediateMessageShould be sent immediately
ShowCurrentSystemTimeShow system-time
PriorityWhether the message has priority
FmtMessage format-string
...
Returns
BOOLEAN if it was successful then return TRUE, otherwise returns FALSE
34{
35 BOOLEAN Result;
36 va_list ArgList;
37
39 {
40 //
41 // Ignore sending message to queue
42 //
43 return FALSE;
44 }
45
46 va_start(ArgList, Fmt);
47
49 IsImmediateMessage,
50 ShowCurrentSystemTime,
51 Priority,
52 Fmt,
53 ArgList);
54 va_end(ArgList);
55
56 return Result;
57}
UCHAR BOOLEAN
Definition BasicTypes.h:39
LOG_CALLBACK_PREPARE_AND_SEND_MESSAGE_TO_QUEUE LogCallbackPrepareAndSendMessageToQueueWrapper
Definition VMM.h:185

◆ LogCallbackPrepareAndSendMessageToQueueWrapper()

IMPORT_EXPORT_HYPERLOG BOOLEAN LogCallbackPrepareAndSendMessageToQueueWrapper ( UINT32 OperationCode,
BOOLEAN IsImmediateMessage,
BOOLEAN ShowCurrentSystemTime,
BOOLEAN Priority,
const char * Fmt,
va_list ArgList )

Prepare a printf-style message mapping and send string messages and tracing for logging and monitoring.

Parameters
OperationCodeOptional operation code
IsImmediateMessageShould be sent immediately
ShowCurrentSystemTimeShow system-time
PriorityWhether the message has priority
FmtMessage format-string
...
Returns
BOOLEAN if it was successful then return TRUE, otherwise returns FALSE
982{
983 int SprintfResult;
984 size_t WrittenSize;
985 BOOLEAN IsVmxRootMode;
986 BOOLEAN Result = FALSE; // by default, we assume error happens
987 char * LogMessage = NULL;
988 char * TempMessage = NULL;
989 char TimeBuffer[20] = {0};
990 ULONG CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
991
992 //
993 // Set Vmx State
994 //
995 IsVmxRootMode = LogCheckVmxOperation();
996
997 //
998 // Set the buffer here, we avoid use stack (local variables) because stack might growth
999 // and be problematic
1000 //
1001 if (IsVmxRootMode)
1002 {
1003 LogMessage = &VmxLogMessage[CurrentCore * PacketChunkSize];
1004 TempMessage = &VmxTempMessage[CurrentCore * PacketChunkSize];
1005 }
1006 else
1007 {
1008 //
1009 // To avoid buffer collision and buffer re-writing in VMX non-root, allocate pool
1010 //
1012
1013 if (LogMessage == NULL)
1014 {
1015 //
1016 // Insufficient space
1017 //
1018 return FALSE;
1019 }
1021
1022 if (TempMessage == NULL)
1023 {
1024 //
1025 // Insufficient space
1026 //
1027 PlatformMemFreePool(LogMessage);
1028 return FALSE;
1029 }
1030 }
1031
1032 if (ShowCurrentSystemTime)
1033 {
1034 //
1035 // It's actually not necessary to use -1 but because user-mode code might assume a null-terminated buffer so
1036 // it's better to use - 1
1037 //
1038
1039 //
1040 // We won't use this because we can't use in any IRQL
1041 // Status = RtlStringCchVPrintfA(TempMessage, PacketChunkSize - 1, Fmt, ArgList);
1042 //
1043 SprintfResult = vsprintf_s(TempMessage, PacketChunkSize - 1, Fmt, ArgList);
1044
1045 //
1046 // Check if the buffer passed the limit
1047 //
1048 if (SprintfResult == -1)
1049 {
1050 //
1051 // Probably the buffer is large that we can't store it
1052 //
1053 goto FreeBufferAndReturn;
1054 }
1055
1056 //
1057 // Fill the above with timer
1058 //
1059 TIME_FIELDS TimeFields;
1060 LARGE_INTEGER SystemTime, LocalTime;
1061 KeQuerySystemTime(&SystemTime);
1062 ExSystemTimeToLocalTime(&SystemTime, &LocalTime);
1063 RtlTimeToTimeFields(&LocalTime, &TimeFields);
1064
1065 //
1066 // We won't use this because we can't use in any IRQL
1067 // Status = RtlStringCchPrintfA(TimeBuffer, RTL_NUMBER_OF(TimeBuffer),
1068 // "%02hd:%02hd:%02hd.%03hd", TimeFields.Hour,
1069 // TimeFields.Minute, TimeFields.Second,
1070 // TimeFields.Milliseconds);
1071 //
1072 //
1073 // Append time with previous message
1074 //
1075 // Status = RtlStringCchPrintfA(LogMessage, PacketChunkSize - 1, "(%s)\t %s", TimeBuffer, TempMessage);
1076 //
1077
1078 //
1079 // this function probably run without error, so there is no need to check the return value
1080 //
1081 sprintf_s(TimeBuffer, RTL_NUMBER_OF(TimeBuffer), "%02hd:%02hd:%02hd.%03hd", TimeFields.Hour, TimeFields.Minute, TimeFields.Second, TimeFields.Milliseconds);
1082
1083 //
1084 // Append time with previous message
1085 //
1086 SprintfResult = sprintf_s(LogMessage, PacketChunkSize - 1, "(%s - core : %d - vmx-root? %s)\t %s", TimeBuffer, CurrentCore, IsVmxRootMode ? "yes" : "no", TempMessage);
1087
1088 //
1089 // Check if the buffer passed the limit
1090 //
1091 if (SprintfResult == -1)
1092 {
1093 //
1094 // Probably the buffer is large that we can't store it
1095 //
1096 goto FreeBufferAndReturn;
1097 }
1098 }
1099 else
1100 {
1101 //
1102 // It's actually not necessary to use -1 but because user-mode code might assume a null-terminated buffer so
1103 // it's better to use - 1
1104 //
1105
1106 //
1107 // We won't use this because we can't use in any IRQL
1108 // Status = RtlStringCchVPrintfA(LogMessage, PacketChunkSize - 1, Fmt, ArgList);
1109 //
1110 SprintfResult = vsprintf_s(LogMessage, PacketChunkSize - 1, Fmt, ArgList);
1111
1112 //
1113 // Check if the buffer passed the limit
1114 //
1115 if (SprintfResult == -1)
1116 {
1117 //
1118 // Probably the buffer is large that we can't store it
1119 //
1120 goto FreeBufferAndReturn;
1121 }
1122 }
1123
1124 //
1125 // Use std function because they can be run in any IRQL
1126 // RtlStringCchLengthA(LogMessage, PacketChunkSize - 1, &WrittenSize);
1127 //
1128 WrittenSize = strnlen_s(LogMessage, PacketChunkSize - 1);
1129
1130 if (LogMessage[0] == '\0')
1131 {
1132 //
1133 // nothing to write
1134 //
1135 goto FreeBufferAndReturn;
1136 }
1137
1138 //
1139 // Send the prepared buffer (with no priority)
1140 //
1141 Result = LogCallbackSendMessageToQueue(OperationCode, IsImmediateMessage, LogMessage, (UINT32)WrittenSize, Priority);
1142
1143FreeBufferAndReturn:
1144
1145 if (!IsVmxRootMode)
1146 {
1147 PlatformMemFreePool(LogMessage);
1148 PlatformMemFreePool(TempMessage);
1149 }
1150
1151 return Result;
1152}
unsigned int UINT32
Definition BasicTypes.h:48
unsigned long ULONG
Definition BasicTypes.h:37
#define PacketChunkSize
Size of each packet.
Definition Constants.h:179
BOOLEAN LogCallbackSendMessageToQueue(UINT32 OperationCode, BOOLEAN IsImmediateMessage, CHAR *LogMessage, UINT32 BufferLen, BOOLEAN Priority)
Send string messages and tracing for logging and monitoring.
Definition Logging.c:1203
BOOLEAN LogCheckVmxOperation()
Checks whether the message tracing operates on vmx-root mode or not.
Definition Logging.c:19
char * VmxTempMessage
VMX temporary buffer for logging messages.
Definition Logging.h:29
char * VmxLogMessage
VMX buffer for logging messages.
Definition Logging.h:23
PVOID PlatformMemAllocateNonPagedPool(SIZE_T NumberOfBytes)
Allocate a non-paged buffer.
Definition Mem.c:41
VOID PlatformMemFreePool(PVOID BufferAddress)
Free (dellocate) a non-paged buffer.
Definition Mem.c:86
NULL()
Definition test-case-generator.py:530

◆ LogCallbackSendBuffer()

IMPORT_EXPORT_HYPERLOG BOOLEAN LogCallbackSendBuffer ( _In_ UINT32 OperationCode,
_In_reads_bytes_(BufferLength) PVOID Buffer,
_In_ UINT32 BufferLength,
_In_ BOOLEAN Priority )

routines callback for sending buffer

Parameters
OperationCode
Buffer
BufferLength
Priority
Returns
BOOLEAN
128{
130 {
131 //
132 // Ignore sending buffer
133 //
134 return FALSE;
135 }
136
137 return g_Callbacks.LogCallbackSendBuffer(OperationCode,
138 Buffer,
139 BufferLength,
140 Priority);
141}
LOG_CALLBACK_SEND_BUFFER LogCallbackSendBuffer
Definition VMM.h:187

◆ LogCallbackSendMessageToQueue()

IMPORT_EXPORT_HYPERLOG BOOLEAN LogCallbackSendMessageToQueue ( UINT32 OperationCode,
BOOLEAN IsImmediateMessage,
CHAR * LogMessage,
UINT32 BufferLen,
BOOLEAN Priority )

routines callback for sending message to queue

Parameters
OperationCode
IsImmediateMessage
LogMessage
BufferLen
Priority
Returns
BOOLEAN

routines callback for sending message to queue

Parameters
OperationCodeOptional operation code
IsImmediateMessageShould be sent immediately
LogMessageLink of message buffer
BufferLenLength of buffer
PriorityWhether the buffer has priority
Returns
BOOLEAN if it was successful then return TRUE, otherwise returns FALSE
76{
78 {
79 //
80 // Ignore sending message to queue
81 //
82 return FALSE;
83 }
84
85 return g_Callbacks.LogCallbackSendMessageToQueue(OperationCode,
86 IsImmediateMessage,
87 LogMessage,
88 BufferLen,
89 Priority);
90}
LOG_CALLBACK_SEND_MESSAGE_TO_QUEUE LogCallbackSendMessageToQueue
Definition VMM.h:186

◆ LogInitialize()

IMPORT_EXPORT_HYPERLOG BOOLEAN LogInitialize ( MESSAGE_TRACING_CALLBACKS * MsgTracingCallbacks)

Initialize the buffer relating to log message tracing.

Parameters
MsgTracingCallbacksspecify the callbacks
Returns
BOOLEAN
99{
100 ULONG ProcessorsCount;
101
102 ProcessorsCount = KeQueryActiveProcessorCount(0);
103
104 //
105 // Initialize buffers for trace message and data messages
106 //(we have two buffers one for vmx root and one for vmx non-root)
107 //
109
111 {
112 return FALSE; // STATUS_INSUFFICIENT_RESOURCES
113 }
114
115 //
116 // Allocate VmxTempMessage and VmxLogMessage
117 //
120
121 if (!VmxTempMessage)
122 {
125 return FALSE; // STATUS_INSUFFICIENT_RESOURCES
126 }
127
130
131 if (!VmxLogMessage)
132 {
135
138
139 return FALSE; // STATUS_INSUFFICIENT_RESOURCES
140 }
141
142 //
143 // Initialize the lock for Vmx-root mode (HIGH_IRQL Spinlock)
144 //
146
147 //
148 // Allocate buffer for messages and initialize the core buffer information
149 //
150 for (int i = 0; i < 2; i++)
151 {
152 //
153 // initialize the lock
154 // Actually, only the 0th buffer use this spinlock but let initialize it
155 // for both but the second buffer spinlock is useless
156 // as we use our custom spinlock
157 //
158 KeInitializeSpinLock(&MessageBufferInformation[i].BufferLock);
159 KeInitializeSpinLock(&MessageBufferInformation[i].BufferLockForNonImmMessage);
160
161 //
162 // allocate the buffer for regular buffers
163 //
166
167 if (!MessageBufferInformation[i].BufferStartAddress ||
168 !MessageBufferInformation[i].BufferForMultipleNonImmediateMessage)
169 {
170 return FALSE; // STATUS_INSUFFICIENT_RESOURCES
171 }
172
173 //
174 // allocate the buffer for priority buffers
175 //
177
178 if (!MessageBufferInformation[i].BufferStartAddressPriority)
179 {
180 return FALSE; // STATUS_INSUFFICIENT_RESOURCES
181 }
182
183 //
184 // Zeroing the buffer
185 //
186 RtlZeroMemory((void *)MessageBufferInformation[i].BufferStartAddress, LogBufferSize);
187 RtlZeroMemory((void *)MessageBufferInformation[i].BufferForMultipleNonImmediateMessage, PacketChunkSize);
188 RtlZeroMemory((void *)MessageBufferInformation[i].BufferStartAddressPriority, LogBufferSizePriority);
189
190 //
191 // Set the end address
192 //
195 }
196
197 //
198 // Copy the callbacks into the global callback holder
199 //
200 RtlCopyBytes(&g_MsgTracingCallbacks, MsgTracingCallbacks, sizeof(MESSAGE_TRACING_CALLBACKS));
201
202 return TRUE;
203}
#define TRUE
Definition BasicTypes.h:55
unsigned __int64 UINT64
Definition BasicTypes.h:21
#define LogBufferSize
Final storage size of message tracing.
Definition Constants.h:200
#define LogBufferSizePriority
Final storage size of message tracing.
Definition Constants.h:207
volatile LONG VmxRootLoggingLock
Vmx-root lock for logging.
Definition Logging.h:110
LOG_BUFFER_INFORMATION * MessageBufferInformation
Global Variable for buffer on all cores.
Definition Logging.h:104
MESSAGE_TRACING_CALLBACKS g_MsgTracingCallbacks
Global variable that holds callbacks.
Definition Logging.h:181
PVOID PlatformMemAllocateZeroedNonPagedPool(SIZE_T NumberOfBytes)
Allocate a non-paged buffer (zeroed)
Definition Mem.c:69
Core-specific buffers.
Definition Logging.h:69
UINT64 BufferEndAddressPriority
Definition Logging.h:89
UINT64 BufferStartAddress
Definition Logging.h:79
UINT64 BufferStartAddressPriority
Definition Logging.h:88
UINT64 BufferEndAddress
Definition Logging.h:80
UINT64 BufferForMultipleNonImmediateMessage
Definition Logging.h:73
Prototype of each function needed by message tracer.
Definition HyperLog.h:49

◆ LogMarkAllAsRead()

IMPORT_EXPORT_HYPERLOG UINT32 LogMarkAllAsRead ( BOOLEAN IsVmxRoot)

Mark all buffers as read.

Priority buffers won't be set as read

Parameters
IsVmxRootDetermine whether you want to read vmx root buffer or vmx non root buffer
Returns
UINT32 return count of messages that set to invalid
559{
560 UINT32 Index;
561 UINT32 ResultsOfBuffersSetToRead = 0;
562 KIRQL OldIRQL = NULL_ZERO;
563
564 //
565 // Check if we're in Vmx-root, if it is then we use our customized HIGH_IRQL Spinlock,
566 // if not we use the windows spinlock
567 //
568 if (IsVmxRoot)
569 {
570 //
571 // Set the index
572 //
573 Index = 1;
574
575 //
576 // Acquire the lock
577 //
579 }
580 else
581 {
582 //
583 // Set the index
584 //
585 Index = 0;
586
587 //
588 // Acquire the lock
589 //
590 KeAcquireSpinLock(&MessageBufferInformation[Index].BufferLock, &OldIRQL);
591 }
592
593 //
594 // We have iterate through the all indexes
595 //
596 for (size_t i = 0; i < MaximumPacketsCapacity; i++)
597 {
598 //
599 // Compute the current buffer to read
600 //
603 (PacketChunkSize + sizeof(BUFFER_HEADER))));
604
605 if (!Header->Valid)
606 {
607 //
608 // there is nothing to send
609 //
610
611 //
612 // Check if we're in Vmx-root, if it is then we use our customized HIGH_IRQL Spinlock,
613 // if not we use the windows spinlock
614 //
615 if (IsVmxRoot)
616 {
618 }
619 else
620 {
621 //
622 // Release the lock
623 //
624 KeReleaseSpinLock(&MessageBufferInformation[Index].BufferLock, OldIRQL);
625 }
626
627 return ResultsOfBuffersSetToRead;
628 }
629
630 //
631 // If we reached here, means that there is sth to send
632 //
633 ResultsOfBuffersSetToRead++;
634
635 //
636 // Second, save the buffer contents
637 //
639
640 //
641 // Finally, set the current index to invalid as we sent it
642 //
643 Header->Valid = FALSE;
644
645 //
646 // Last step is to clear the current buffer (we can't do it once when CurrentIndexToSend is zero because
647 // there might be multiple messages on the start of the queue that didn't read yet)
648 // we don't free the header
649 //
650 RtlZeroMemory(SendingBuffer, Header->BufferLength);
651
652 //
653 // Check to see whether we passed the index or not
654 //
655 if (MessageBufferInformation[Index].CurrentIndexToSend > MaximumPacketsCapacity - 2)
656 {
658 }
659 else
660 {
661 //
662 // Increment the next index to read
663 //
665 }
666 }
667
668 //
669 // Check if we're in Vmx-root, if it is then we use our customized HIGH_IRQL Spinlock,
670 // if not we use the windows spinlock
671 //
672 if (IsVmxRoot)
673 {
675 }
676 else
677 {
678 //
679 // Release the lock
680 //
681 KeReleaseSpinLock(&MessageBufferInformation[Index].BufferLock, OldIRQL);
682 }
683
684 return ResultsOfBuffersSetToRead;
685}
#define NULL_ZERO
Definition BasicTypes.h:51
#define MaximumPacketsCapacity
Default buffer count of packets for message tracing.
Definition Constants.h:163
struct _BUFFER_HEADER BUFFER_HEADER
Message buffer structure.
void SpinlockLock(volatile LONG *Lock)
Tries to get the lock and won't return until successfully get the lock.
Definition Spinlock.c:52
void SpinlockUnlock(volatile LONG *Lock)
Release the lock.
Definition Spinlock.c:158
Message buffer structure.
Definition Logging.h:58
UINT32 BufferLength
Definition Logging.h:60
BOOLEAN Valid
Definition Logging.h:61
UINT32 CurrentIndexToSend
Definition Logging.h:82

◆ LogRegisterEventBasedNotification()

IMPORT_EXPORT_HYPERLOG BOOLEAN LogRegisterEventBasedNotification ( PVOID TargetIrp)

Create an event-based usermode notifying mechanism.

Parameters
TargetIrp
Returns
BOOLEAN
1584{
1585 PNOTIFY_RECORD NotifyRecord;
1586 NTSTATUS Status;
1587 PIO_STACK_LOCATION IrpStack;
1588 PREGISTER_NOTIFY_BUFFER RegisterEvent;
1589 PIRP Irp = (PIRP)TargetIrp;
1590
1591 IrpStack = IoGetCurrentIrpStackLocation(Irp);
1592 RegisterEvent = (PREGISTER_NOTIFY_BUFFER)Irp->AssociatedIrp.SystemBuffer;
1593
1594 //
1595 // Allocate a record and save all the event context
1596 //
1598
1599 if (NULL == NotifyRecord)
1600 {
1601 DbgPrint("Err, unable to allocate memory for notify record\n");
1602 return FALSE;
1603 }
1604
1605 NotifyRecord->Type = EVENT_BASED;
1606
1607 KeInitializeDpc(&NotifyRecord->Dpc, // Dpc
1608 LogNotifyUsermodeCallback, // DeferredRoutine
1609 NotifyRecord // DeferredContext
1610 );
1611
1612 //
1613 // Get the object pointer from the handle
1614 // Note we must be in the context of the process that created the handle
1615 //
1616 Status = ObReferenceObjectByHandle(RegisterEvent->hEvent,
1617 SYNCHRONIZE | EVENT_MODIFY_STATE,
1618 *ExEventObjectType,
1619 Irp->RequestorMode,
1620 &NotifyRecord->Message.Event,
1621 NULL);
1622
1623 if (!NT_SUCCESS(Status))
1624 {
1625 DbgPrint("Err, unable to reference user mode event object, status = 0x%x\n", Status);
1626 PlatformMemFreePool(NotifyRecord);
1627 return FALSE;
1628 }
1629
1630 //
1631 // Insert dpc to the queue
1632 //
1633 KeInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
1634
1635 return TRUE;
1636}
struct _REGISTER_NOTIFY_BUFFER * PREGISTER_NOTIFY_BUFFER
@ EVENT_BASED
Definition DataTypes.h:256
VOID LogNotifyUsermodeCallback(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
Complete the IRP in IRP Pending state and fill the usermode buffers with pool data.
Definition Logging.c:1350
PVOID PlatformMemAllocateNonPagedPoolWithQuota(SIZE_T NumberOfBytes)
Allocate a non-paged buffer (use QUOTA)
Definition Mem.c:55
The usermode request.
Definition Logging.h:40
Used to register event for transferring buffer between user-to-kernel.
Definition DataTypes.h:279

◆ LogRegisterIrpBasedNotification()

IMPORT_EXPORT_HYPERLOG BOOLEAN LogRegisterIrpBasedNotification ( PVOID TargetIrp,
LONG * Status )

Register a new IRP Pending thread which listens for new buffers.

Parameters
TargetIrp
Status
Returns
BOOLEAN
1465{
1466 PNOTIFY_RECORD NotifyRecord;
1467 PIO_STACK_LOCATION IrpStack;
1468 PREGISTER_NOTIFY_BUFFER RegisterEvent;
1469 PIRP Irp = (PIRP)TargetIrp;
1470
1471 //
1472 // check if current core has another thread with pending IRP,
1473 // if no then put the current thread to pending
1474 // otherwise return and complete thread with STATUS_SUCCESS as
1475 // there is another thread waiting for message
1476 //
1477
1478 if (g_GlobalNotifyRecord == NULL)
1479 {
1480 IrpStack = IoGetCurrentIrpStackLocation(Irp);
1481 RegisterEvent = (PREGISTER_NOTIFY_BUFFER)Irp->AssociatedIrp.SystemBuffer;
1482
1483 //
1484 // Allocate a record and save all the event context
1485 //
1487
1488 if (NULL == NotifyRecord)
1489 {
1490 *Status = (LONG)STATUS_INSUFFICIENT_RESOURCES;
1491 return FALSE;
1492 }
1493
1494 NotifyRecord->Type = IRP_BASED;
1495 NotifyRecord->Message.PendingIrp = Irp;
1496
1497 KeInitializeDpc(&NotifyRecord->Dpc, // Dpc
1498 LogNotifyUsermodeCallback, // DeferredRoutine
1499 NotifyRecord // DeferredContext
1500 );
1501
1502 IoMarkIrpPending(Irp);
1503
1504 //
1505 // check for new message (for both Vmx-root mode or Vmx non root-mode)
1506 // First, we check for priority messages in both buffers then we check
1507 // for regular messages
1508 //
1510 {
1511 //
1512 // check vmx non-root (priority buffers)
1513 //
1514 NotifyRecord->CheckVmxRootMessagePool = FALSE;
1515
1516 //
1517 // Insert dpc to queue
1518 //
1519 KeInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
1520 }
1521 else if (LogCheckForNewMessage(TRUE, TRUE))
1522 {
1523 //
1524 // check vmx root (priority buffers)
1525 //
1526 NotifyRecord->CheckVmxRootMessagePool = TRUE;
1527 //
1528 // Insert dpc to queue
1529 //
1530 KeInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
1531 }
1533 {
1534 //
1535 // check vmx non-root
1536 //
1537 NotifyRecord->CheckVmxRootMessagePool = FALSE;
1538
1539 //
1540 // Insert dpc to queue
1541 //
1542 KeInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
1543 }
1544 else if (LogCheckForNewMessage(TRUE, FALSE))
1545 {
1546 //
1547 // check vmx root
1548 //
1549 NotifyRecord->CheckVmxRootMessagePool = TRUE;
1550 //
1551 // Insert dpc to queue
1552 //
1553 KeInsertQueueDpc(&NotifyRecord->Dpc, NotifyRecord, NULL);
1554 }
1555 else
1556 {
1557 //
1558 // Set the notify routine to the global structure
1559 //
1560 g_GlobalNotifyRecord = NotifyRecord;
1561 }
1562 //
1563 // We will return pending as we have marked the IRP pending
1564 //
1565
1566 *Status = (LONG)STATUS_PENDING;
1567 return TRUE;
1568 }
1569 else
1570 {
1571 *Status = (LONG)STATUS_SUCCESS;
1572 return TRUE;
1573 }
1574}
@ IRP_BASED
Definition DataTypes.h:255
BOOLEAN LogCheckForNewMessage(BOOLEAN IsVmxRoot, BOOLEAN Priority)
Check if new message is available or not.
Definition Logging.c:922
NOTIFY_RECORD * g_GlobalNotifyRecord
Save the state of the thread that waits for messages to deliver to user-mode.
Definition Logging.h:175
PIRP PendingIrp
Definition Logging.h:46
NOTIFY_TYPE Type
Definition Logging.h:41
union _NOTIFY_RECORD::@55 Message
BOOLEAN CheckVmxRootMessagePool
Definition Logging.h:50
KDPC Dpc
Definition Logging.h:49

◆ LogUnInitialize()

IMPORT_EXPORT_HYPERLOG VOID LogUnInitialize ( )

Uninitialize the buffer relating to log message tracing.

Returns
VOID
212{
213 //
214 // de-allocate buffer for messages and initialize the core buffer information (for vmx-root core)
215 //
216 for (int i = 0; i < 2; i++)
217 {
218 //
219 // Free each buffers
220 //
221 if (MessageBufferInformation[i].BufferStartAddress != NULL64_ZERO)
222 {
223 PlatformMemFreePool((PVOID)MessageBufferInformation[i].BufferStartAddress);
224 }
225
226 if (MessageBufferInformation[i].BufferStartAddressPriority != NULL64_ZERO)
227 {
228 PlatformMemFreePool((PVOID)MessageBufferInformation[i].BufferStartAddressPriority);
229 }
230
231 if (MessageBufferInformation[i].BufferForMultipleNonImmediateMessage != NULL64_ZERO)
232 {
233 PlatformMemFreePool((PVOID)MessageBufferInformation[i].BufferForMultipleNonImmediateMessage);
234 }
235 }
236
237 //
238 // de-allocate buffers for trace message and data messages
239 //
242}
#define NULL64_ZERO
Definition BasicTypes.h:52