mirror of
https://github.com/donnaskiez/ac.git
synced 2024-11-21 22:24:08 +01:00
reference counts
This commit is contained in:
parent
2ebeb8a055
commit
a4fe653d44
4 changed files with 79 additions and 13 deletions
|
@ -49,6 +49,28 @@ EnumHandleCallback(
|
|||
#pragma alloc_text(PAGE, ExUnlockHandleTableEntry)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Its important on unload we dereference any objects to ensure the kernels reference
|
||||
* count remains correct.
|
||||
*/
|
||||
VOID
|
||||
CleanupProcessListFreeCallback(
|
||||
_In_ PPROCESS_LIST_ENTRY ProcessListEntry
|
||||
)
|
||||
{
|
||||
ObDereferenceObject(ProcessListEntry->parent);
|
||||
ObDereferenceObject(ProcessListEntry->process);
|
||||
}
|
||||
|
||||
VOID
|
||||
CleanupThreadListFreeCallback(
|
||||
_In_ PTHREAD_LIST_ENTRY ThreadListEntry
|
||||
)
|
||||
{
|
||||
ObDereferenceObject(ThreadListEntry->thread);
|
||||
ObDereferenceObject(ThreadListEntry->owning_process);
|
||||
}
|
||||
|
||||
VOID
|
||||
CleanupProcessListOnDriverUnload()
|
||||
{
|
||||
|
@ -57,7 +79,7 @@ CleanupProcessListOnDriverUnload()
|
|||
|
||||
for (;;)
|
||||
{
|
||||
if (!ListFreeFirstEntry(&process_list->start, &process_list->lock))
|
||||
if (!ListFreeFirstEntry(&process_list->start, &process_list->lock, CleanupProcessListFreeCallback))
|
||||
{
|
||||
ExFreePoolWithTag(process_list, POOL_TAG_THREAD_LIST);
|
||||
return;
|
||||
|
@ -73,7 +95,7 @@ CleanupThreadListOnDriverUnload()
|
|||
|
||||
for (;;)
|
||||
{
|
||||
if (!ListFreeFirstEntry(&thread_list->start, &thread_list->lock))
|
||||
if (!ListFreeFirstEntry(&thread_list->start, &thread_list->lock, CleanupThreadListFreeCallback))
|
||||
{
|
||||
ExFreePoolWithTag(thread_list, POOL_TAG_THREAD_LIST);
|
||||
return;
|
||||
|
@ -81,10 +103,6 @@ CleanupThreadListOnDriverUnload()
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Important to remember the callback function will run at irql = DISPATCH_LEVEL since
|
||||
* we hold the spinlock during enumeration.
|
||||
*/
|
||||
_IRQL_requires_max_(APC_LEVEL)
|
||||
_Acquires_lock_(_Lock_kind_mutex_)
|
||||
_Releases_lock_(_Lock_kind_mutex_)
|
||||
|
@ -256,6 +274,9 @@ ProcessCreateNotifyRoutine(
|
|||
if (!entry)
|
||||
return;
|
||||
|
||||
ObReferenceObject(parent);
|
||||
ObReferenceObject(process);
|
||||
|
||||
entry->parent = parent;
|
||||
entry->process = process;
|
||||
|
||||
|
@ -268,6 +289,9 @@ ProcessCreateNotifyRoutine(
|
|||
if (!entry)
|
||||
return;
|
||||
|
||||
ObDereferenceObject(entry->parent);
|
||||
ObDereferenceObject(entry->process);
|
||||
|
||||
ListRemoveEntry(&process_list->start, entry, &process_list->lock);
|
||||
}
|
||||
}
|
||||
|
@ -300,6 +324,9 @@ ThreadCreateNotifyRoutine(
|
|||
if (!entry)
|
||||
return;
|
||||
|
||||
ObReferenceObject(thread);
|
||||
ObReferenceObject(process);
|
||||
|
||||
entry->thread = thread;
|
||||
entry->owning_process = process;
|
||||
entry->apc = NULL;
|
||||
|
@ -314,6 +341,9 @@ ThreadCreateNotifyRoutine(
|
|||
if (!entry)
|
||||
return;
|
||||
|
||||
ObDereferenceObject(entry->thread);
|
||||
ObDereferenceObject(entry->owning_process);
|
||||
|
||||
ListRemoveEntry(&thread_list->start, entry, &thread_list->lock);
|
||||
}
|
||||
}
|
||||
|
@ -658,7 +688,7 @@ EnumerateProcessHandles(
|
|||
_In_opt_ PVOID Context
|
||||
)
|
||||
{
|
||||
/* Handles are paged out so we need to be at an IRQL that allows paging */
|
||||
/* Handles are stored in paged memory */
|
||||
PAGED_CODE();
|
||||
|
||||
UNREFERENCED_PARAMETER(Context);
|
||||
|
|
|
@ -350,8 +350,8 @@ MapDiskImageIntoVirtualAddressSpace(
|
|||
|
||||
NTSTATUS status;
|
||||
HANDLE file_handle;
|
||||
OBJECT_ATTRIBUTES object_attributes;
|
||||
PIO_STATUS_BLOCK pio_block;
|
||||
OBJECT_ATTRIBUTES object_attributes = { 0 };
|
||||
PIO_STATUS_BLOCK pio_block = NULL;
|
||||
UNICODE_STRING path;
|
||||
|
||||
*Section = NULL;
|
||||
|
@ -977,8 +977,8 @@ ParseSMBIOSTable(
|
|||
ULONG firmware_table_buffer_size = NULL;
|
||||
ULONG bytes_returned;
|
||||
PRAW_SMBIOS_DATA smbios_data;
|
||||
PSMBIOS_TABLE_HEADER smbios_table_header;
|
||||
PRAW_SMBIOS_TABLE_01 smbios_baseboard_information;
|
||||
PSMBIOS_TABLE_HEADER smbios_table_header = NULL;
|
||||
PRAW_SMBIOS_TABLE_01 smbios_baseboard_information = NULL;
|
||||
|
||||
status = ExGetSystemFirmwareTable(
|
||||
SMBIOS_TABLE,
|
||||
|
|
|
@ -304,6 +304,26 @@ end:
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple thread safe linked list implementation. All structures should begin
|
||||
* with a SINGLE_LIST_ENTRY structure provided by the windows API. for example:
|
||||
*
|
||||
* typedef struct _LIST_ENTRY_STRUCTURE
|
||||
* {
|
||||
* SINGLE_LIST_ENTRY list;
|
||||
* PVOID address;
|
||||
* UINT32 data;
|
||||
* ...
|
||||
* };
|
||||
*
|
||||
* This common structure layout allows us to pass in a callback routine when freeing
|
||||
* allowing immense flexibility to ensure we can free and/or deference any objects
|
||||
* that are referenced in said object.
|
||||
*
|
||||
* I've opted to use a mutex rather then a spinlock since there are many times we
|
||||
* enumerate the list for extended periods aswell as queue up many insertions at
|
||||
* once.
|
||||
*/
|
||||
VOID
|
||||
ListInit(
|
||||
_Inout_ PSINGLE_LIST_ENTRY Head,
|
||||
|
@ -333,12 +353,19 @@ ListInsert(
|
|||
KeReleaseGuardedMutex(Lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Assuming the SINGLE_LIST_ENTRY is the first item in the structure, we
|
||||
* can pass a callback routine to be called before the free occurs. This
|
||||
* allows us to dereference/free structure specific items whilst still allowing
|
||||
* the list to remain flexible.
|
||||
*/
|
||||
_Acquires_lock_(_Lock_kind_mutex_)
|
||||
_Releases_lock_(_Lock_kind_mutex_)
|
||||
BOOLEAN
|
||||
ListFreeFirstEntry(
|
||||
_Inout_ PSINGLE_LIST_ENTRY Head,
|
||||
_In_ PKGUARDED_MUTEX Lock
|
||||
_In_ PKGUARDED_MUTEX Lock,
|
||||
_In_opt_ PVOID CallbackRoutine
|
||||
)
|
||||
{
|
||||
BOOLEAN result = FALSE;
|
||||
|
@ -347,6 +374,10 @@ ListFreeFirstEntry(
|
|||
if (Head->Next)
|
||||
{
|
||||
PSINGLE_LIST_ENTRY entry = Head->Next;
|
||||
|
||||
VOID(*callback_function_ptr)(PVOID) = CallbackRoutine;
|
||||
(*callback_function_ptr)(entry);
|
||||
|
||||
Head->Next = Head->Next->Next;
|
||||
ExFreePoolWithTag(entry, POOL_TAG_THREAD_LIST);
|
||||
result = TRUE;
|
||||
|
@ -356,6 +387,10 @@ ListFreeFirstEntry(
|
|||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we are removing a specific entry, its assumed we have freed and/or dereferenced
|
||||
* any fields in the structure.
|
||||
*/
|
||||
_Acquires_lock_(_Lock_kind_mutex_)
|
||||
_Releases_lock_(_Lock_kind_mutex_)
|
||||
VOID
|
||||
|
|
|
@ -100,7 +100,8 @@ _Releases_lock_(_Lock_kind_mutex_)
|
|||
BOOLEAN
|
||||
ListFreeFirstEntry(
|
||||
_Inout_ PSINGLE_LIST_ENTRY Head,
|
||||
_In_ PKGUARDED_MUTEX Lock
|
||||
_In_ PKGUARDED_MUTEX Lock,
|
||||
_In_opt_ PVOID CallbackRoutine
|
||||
);
|
||||
|
||||
_Acquires_lock_(_Lock_kind_mutex_)
|
||||
|
|
Loading…
Reference in a new issue