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

Headers of pool manager. More...

Go to the source code of this file.

Classes

struct  _POOL_TABLE
 Table of holding pools detail structure. More...
struct  _REQUEST_NEW_ALLOCATION
 Manage the requests for new allocations. More...

Macros

#define MaximumRequestsQueueDepth   300
 Maximum Pool Requests (while not allocated).
#define NumberOfPreAllocatedBuffers   10

Typedefs

typedef struct _POOL_TABLE POOL_TABLE
 Table of holding pools detail structure.
typedef struct _POOL_TABLEPPOOL_TABLE
typedef struct _REQUEST_NEW_ALLOCATION REQUEST_NEW_ALLOCATION
 Manage the requests for new allocations.
typedef struct _REQUEST_NEW_ALLOCATIONPREQUEST_NEW_ALLOCATION

Functions

BOOLEAN PoolManagerInitialize ()
 Initializes the pool manager.
VOID PoolManagerUninitialize ()
 Uninitialize the pool manager (free the buffers, etc.).
VOID PoolManagerShowPreAllocatedPools ()
 Shows list of pre-allocated pools available (used for debugging purposes).
BOOLEAN PoolManagerCheckAndPerformAllocationAndDeallocation ()
 This function performs allocations from VMX non-root based on g_RequestNewAllocation.
BOOLEAN PoolManagerRequestAllocation (SIZE_T Size, UINT32 Count, POOL_ALLOCATION_INTENTION Intention)
 Request to allocate new buffers.
UINT64 PoolManagerRequestPool (POOL_ALLOCATION_INTENTION Intention, BOOLEAN RequestNewPool, UINT32 Size)
 This function should be called from vmx-root in order to get a pool from the list.
BOOLEAN PoolManagerFreePool (UINT64 AddressToFree)
 This function set a pool flag to be freed, and it will be freed on the next IOCTL when it's safe to remove.

Variables

REQUEST_NEW_ALLOCATIONg_RequestNewAllocation
 If sb wants allocation from vmx root, adds it's request to this structure.
volatile LONG LockForRequestAllocation
 Request allocation Spinlock.
volatile LONG LockForReadingPool
 Spinlock for reading pool.
BOOLEAN g_PoolManagerInitialized
 Pool manager memory allocator initialized.
BOOLEAN g_IsNewRequestForAllocationReceived
 We set it when there is a new allocation.
BOOLEAN g_IsNewRequestForDeAllocation
 We set it when there is a new allocation.
LIST_ENTRY g_ListOfAllocatedPoolsHead
 Create a list from all pools.

Detailed Description

Headers of pool manager.

Author
Sina Karvandi (sina@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)
Version
0.1
Date
2020-04-11

Macro Definition Documentation

◆ MaximumRequestsQueueDepth

#define MaximumRequestsQueueDepth   300

Maximum Pool Requests (while not allocated).

◆ NumberOfPreAllocatedBuffers

#define NumberOfPreAllocatedBuffers   10

Typedef Documentation

◆ POOL_TABLE

typedef struct _POOL_TABLE POOL_TABLE

Table of holding pools detail structure.

◆ PPOOL_TABLE

typedef struct _POOL_TABLE * PPOOL_TABLE

◆ PREQUEST_NEW_ALLOCATION

◆ REQUEST_NEW_ALLOCATION

Manage the requests for new allocations.

Function Documentation

◆ PoolManagerCheckAndPerformAllocationAndDeallocation()

BOOLEAN PoolManagerCheckAndPerformAllocationAndDeallocation ( )

This function performs allocations from VMX non-root based on g_RequestNewAllocation.

Returns
BOOLEAN If the pool manager allocates buffer or there was no buffer to allocate then it returns true, if there was any error then it returns false
321{
322 BOOLEAN Result = TRUE;
323
324 //
325 // Make sure we're on vmx non-root and also we have new allocation
326 // and also pool manager is initialized, otherwise we shouldn't allocate or deallocate
327 //
329 {
330 //
331 // allocation's can't be done from vmx root
332 // or pool manager is not initialized yet
333 //
334 return FALSE;
335 }
336
337 //
338 // Make sure paging works properly
339 //
340 PAGED_CODE();
341
343
344 //
345 // Check for new allocation
346 //
348 {
349 for (SIZE_T i = 0; i < MaximumRequestsQueueDepth; i++)
350 {
352
353 if (CurrentItem->Size != 0)
354 {
355 Result = PoolManagerAllocateAndAddToPoolTable(CurrentItem->Size,
356 CurrentItem->Count,
357 CurrentItem->Intention);
358
359 //
360 // Free the data for future use
361 //
362 CurrentItem->Count = 0;
363 CurrentItem->Intention = 0;
364 CurrentItem->Size = 0;
365 }
366 }
367 }
368
369 //
370 // Check for deallocation
371 //
373 {
374 PLIST_ENTRY Link = g_ListOfAllocatedPoolsHead.Flink;
375
376 while (Link != &g_ListOfAllocatedPoolsHead)
377 {
378 PLIST_ENTRY Next = Link->Flink;
379
380 //
381 // Get the head of the record
382 //
383 PPOOL_TABLE PoolTable = (PPOOL_TABLE)CONTAINING_RECORD(Link, POOL_TABLE, PoolsList);
384
385 //
386 // Check whether this pool should be freed or not and
387 // also check whether it's already freed or not
388 //
389 if (PoolTable->ShouldBeFreed && !PoolTable->AlreadyFreed)
390 {
391 //
392 // Set the flag to indicate that we freed
393 //
394 PoolTable->AlreadyFreed = TRUE;
395
396 //
397 // This item should be freed
398 //
399 PlatformMemFreePool((PVOID)PoolTable->Address);
400
401 //
402 // Now we should remove the entry from the g_ListOfAllocatedPoolsHead
403 //
404 RemoveEntryList(Link);
405
406 //
407 // Free the structure pool
408 //
409 PlatformMemFreePool(PoolTable);
410 }
411
412 Link = Next;
413 }
414 }
415
416 //
417 // All allocation and deallocation are performed
418 //
421
423
424 return Result;
425}
PVOID PlatformMemFreePool(PVOID BufferAddress)
Frees a memory pool.
Definition PlatformMem.c:269
BOOLEAN PoolManagerAllocateAndAddToPoolTable(SIZE_T Size, UINT32 Count, POOL_ALLOCATION_INTENTION Intention)
Allocate the new pools and add them to pool table.
Definition PoolManager.c:271
struct _POOL_TABLE POOL_TABLE
Table of holding pools detail structure.
volatile LONG LockForReadingPool
Spinlock for reading pool.
Definition PoolManager.h:77
struct _REQUEST_NEW_ALLOCATION REQUEST_NEW_ALLOCATION
Manage the requests for new allocations.
struct _POOL_TABLE * PPOOL_TABLE
#define MaximumRequestsQueueDepth
Maximum Pool Requests (while not allocated).
Definition PoolManager.h:22
BOOLEAN g_IsNewRequestForAllocationReceived
We set it when there is a new allocation.
Definition PoolManager.h:89
REQUEST_NEW_ALLOCATION * g_RequestNewAllocation
If sb wants allocation from vmx root, adds it's request to this structure.
Definition PoolManager.h:65
BOOLEAN g_IsNewRequestForDeAllocation
We set it when there is a new allocation.
Definition PoolManager.h:95
LIST_ENTRY g_ListOfAllocatedPoolsHead
Create a list from all pools.
Definition PoolManager.h:101
BOOLEAN g_PoolManagerInitialized
Pool manager memory allocator initialized.
Definition PoolManager.h:83
VOID SpinlockLock(volatile LONG *Lock)
Tries to get the lock and won't return until successfully get the lock.
Definition Spinlock.c:53
VOID SpinlockUnlock(volatile LONG *Lock)
Release the lock.
Definition Spinlock.c:162
UCHAR BOOLEAN
Definition BasicTypes.h:35
void * PVOID
Definition BasicTypes.h:56
#define TRUE
Definition BasicTypes.h:114
#define FALSE
Definition BasicTypes.h:113
IMPORT_EXPORT_VMM BOOLEAN VmFuncVmxGetCurrentExecutionMode()
Get the current VMX operation state.
Definition Export.c:802
#define CONTAINING_RECORD(address, type, field)
Definition nt-list.h:36
UINT64 Address
Definition PoolManager.h:35
BOOLEAN ShouldBeFreed
Definition PoolManager.h:40
BOOLEAN AlreadyFreed
Definition PoolManager.h:41
UINT32 Count
Definition PoolManager.h:52
SIZE_T Size
Definition PoolManager.h:51
POOL_ALLOCATION_INTENTION Intention
Definition PoolManager.h:53

◆ PoolManagerFreePool()

BOOLEAN PoolManagerFreePool ( UINT64 AddressToFree)

This function set a pool flag to be freed, and it will be freed on the next IOCTL when it's safe to remove.

Parameters
AddressToFreeThe pool address that was previously obtained from the pool manager
Returns
BOOLEAN If the address was already in the list of allocated pools by pool manager then it returns TRUE; otherwise, FALSE
155{
156 PLIST_ENTRY ListTemp = 0;
157 BOOLEAN Result = FALSE;
158 ListTemp = &g_ListOfAllocatedPoolsHead;
159
161
162 while (&g_ListOfAllocatedPoolsHead != ListTemp->Flink)
163 {
164 ListTemp = ListTemp->Flink;
165
166 //
167 // Get the head of the record
168 //
169 PPOOL_TABLE PoolTable = (PPOOL_TABLE)CONTAINING_RECORD(ListTemp, POOL_TABLE, PoolsList);
170
171 if (PoolTable->Address == AddressToFree)
172 {
173 //
174 // We found an entry that matched the detailed from
175 // previously allocated pools
176 //
177 PoolTable->ShouldBeFreed = TRUE;
178 Result = TRUE;
179
181 break;
182 }
183 }
184
186 return Result;
187}

◆ PoolManagerInitialize()

BOOLEAN PoolManagerInitialize ( )

Initializes the pool manager.

Returns
BOOLEAN
54{
55 //
56 // Allocate global requesting variable
57 //
58 SIZE_T BufferSize = MaximumRequestsQueueDepth * sizeof(REQUEST_NEW_ALLOCATION);
59 if (!PlmgrAllocateRequestNewAllocation(BufferSize))
60 {
61 LogError("Err, insufficient memory");
62 return FALSE;
63 }
64
65 //
66 // Initialize list head
67 //
68 InitializeListHead(&g_ListOfAllocatedPoolsHead);
69
70 //
71 // Nothing to deallocate or allocate at the beginning
72 //
75
76 //
77 // Memory allocator is initialized
78 //
80
81 //
82 // Initialized successfully
83 //
84 return TRUE;
85}
BOOLEAN PlmgrAllocateRequestNewAllocation(SIZE_T NumberOfBytes)
Allocate global requesting variable.
Definition PoolManager.c:21
#define LogError(format,...)
Log in the case of error.
Definition HyperDbgHyperLogIntrinsics.h:113

◆ PoolManagerRequestAllocation()

BOOLEAN PoolManagerRequestAllocation ( SIZE_T Size,
UINT32 Count,
POOL_ALLOCATION_INTENTION Intention )

Request to allocate new buffers.

Parameters
SizeRequest new buffer to allocate
CountCount of chunks
IntentionThe intention of chunks (buffer tag)
Returns
BOOLEAN If the request is save it returns true otherwise it returns false
437{
438 BOOLEAN FoundAPlace = FALSE;
439
440 //
441 // ******** We check to find a free place to store ********
442 //
443
445
446 for (SIZE_T i = 0; i < MaximumRequestsQueueDepth; i++)
447 {
449
450 if (CurrentItem->Size == 0)
451 {
452 CurrentItem->Count = Count;
453 CurrentItem->Intention = Intention;
454 CurrentItem->Size = Size;
455
456 FoundAPlace = TRUE;
457
458 break;
459 }
460 }
461
462 if (!FoundAPlace)
463 {
465 return FALSE;
466 }
467
468 //
469 // Signals to show that we have new allocations
470 //
472
474 return TRUE;
475}
volatile LONG LockForRequestAllocation
Request allocation Spinlock.
Definition PoolManager.h:71

◆ PoolManagerRequestPool()

UINT64 PoolManagerRequestPool ( POOL_ALLOCATION_INTENTION Intention,
BOOLEAN RequestNewPool,
UINT32 Size )

This function should be called from vmx-root in order to get a pool from the list.

If RequestNewPool is TRUE then Size is used, otherwise Size is useless Note : Most of the times this function called from vmx root but not all the time

Parameters
IntentionThe intention why we need this pool for (buffer tag)
RequestNewPoolCreate a request to allocate a new pool with the same size, next time that it's safe to allocate (this way we never ran out of pools for this "Intention")
SizeIf the RequestNewPool is true the we should specify a size for the new pool
Returns
UINT64 Returns a pool address or returns null if there was an error
231{
232 UINT64 Address = 0;
233
237 if (PoolTable->Intention == Intention && PoolTable->IsBusy == FALSE)
238 {
239 PoolTable->IsBusy = TRUE;
240 Address = PoolTable->Address;
241 break;
242 }
243 });
244
245 //
246 // Check if we need additional pools e.g another pool or the pool
247 // will be available for the next use blah blah
248 //
249 if (RequestNewPool)
250 {
251 PoolManagerRequestAllocation(Size, 1, Intention);
252 }
253
254 //
255 // return Address might be null indicating there is no valid pools
256 //
257 return Address;
258}
#define LIST_FOR_EACH_LINK(_head, _struct_type, _member, _var)
Definition MetaMacros.h:34
BOOLEAN PoolManagerRequestAllocation(SIZE_T Size, UINT32 Count, POOL_ALLOCATION_INTENTION Intention)
Request to allocate new buffers.
Definition PoolManager.c:436
#define ScopedSpinlock(LockObject, CodeToRun)
Definition Spinlock.h:39

◆ PoolManagerShowPreAllocatedPools()

VOID PoolManagerShowPreAllocatedPools ( )

Shows list of pre-allocated pools available (used for debugging purposes).

Returns
VOID
196{
197 PLIST_ENTRY ListTemp = 0;
198 ListTemp = &g_ListOfAllocatedPoolsHead;
199
200 while (&g_ListOfAllocatedPoolsHead != ListTemp->Flink)
201 {
202 ListTemp = ListTemp->Flink;
203
204 //
205 // Get the head of the record
206 //
207 PPOOL_TABLE PoolTable = (PPOOL_TABLE)CONTAINING_RECORD(ListTemp, POOL_TABLE, PoolsList);
208
209 LogInfo("Pool details, Pool intention: %x | Pool address: %llx | Pool state: %s | Should be freed: %s | Already freed: %s\n",
210 PoolTable->Intention,
211 PoolTable->Address,
212 PoolTable->IsBusy ? "used" : "free",
213 PoolTable->ShouldBeFreed ? "true" : "false",
214 PoolTable->AlreadyFreed ? "true" : "false");
215 }
216}
#define LogInfo(format,...)
Define log variables.
Definition HyperDbgHyperLogIntrinsics.h:71
BOOLEAN IsBusy
Definition PoolManager.h:39
POOL_ALLOCATION_INTENTION Intention
Definition PoolManager.h:37

◆ PoolManagerUninitialize()

VOID PoolManagerUninitialize ( )

Uninitialize the pool manager (free the buffers, etc.).

Returns
VOID
94{
95 PLIST_ENTRY Link;
96
97 //
98 // Pool manager is not initialized anymore
99 //
101
103
104 Link = g_ListOfAllocatedPoolsHead.Flink;
105
106 while (Link != &g_ListOfAllocatedPoolsHead)
107 {
108 PLIST_ENTRY Next = Link->Flink;
109
110 //
111 // Get the head of the record
112 //
113 PPOOL_TABLE PoolTable = (PPOOL_TABLE)CONTAINING_RECORD(Link, POOL_TABLE, PoolsList);
114
115 //
116 // Free the alloocated buffer (if not already changed)
117 //
118 if (!PoolTable->AlreadyFreed)
119 {
120 PlatformMemFreePool((PVOID)PoolTable->Address);
121 }
122
123 //
124 // Unlink the PoolTable
125 //
126 RemoveEntryList(Link);
127
128 //
129 // Free the record itself
130 //
131 PlatformMemFreePool(PoolTable);
132
133 Link = Next;
134 }
135
136 InitializeListHead(&g_ListOfAllocatedPoolsHead);
139
141
143}
VOID PlmgrFreeRequestNewAllocation(VOID)
Definition PoolManager.c:37

Variable Documentation

◆ g_IsNewRequestForAllocationReceived

BOOLEAN g_IsNewRequestForAllocationReceived

We set it when there is a new allocation.

◆ g_IsNewRequestForDeAllocation

BOOLEAN g_IsNewRequestForDeAllocation

We set it when there is a new allocation.

◆ g_ListOfAllocatedPoolsHead

LIST_ENTRY g_ListOfAllocatedPoolsHead

Create a list from all pools.

◆ g_PoolManagerInitialized

BOOLEAN g_PoolManagerInitialized

Pool manager memory allocator initialized.

◆ g_RequestNewAllocation

REQUEST_NEW_ALLOCATION* g_RequestNewAllocation

If sb wants allocation from vmx root, adds it's request to this structure.

◆ LockForReadingPool

volatile LONG LockForReadingPool

Spinlock for reading pool.

◆ LockForRequestAllocation

volatile LONG LockForRequestAllocation

Request allocation Spinlock.