From 63da3809f11b12f1d5045ca47ca86e265600b1ca Mon Sep 17 00:00:00 2001 From: Johnny Shaw Date: Thu, 19 Sep 2024 09:55:22 -0600 Subject: [PATCH] pcre2 wrapper improvement --- include/pcre2_vfdynf.h | 20 +++++++----- pcre2/pcre2_vfdynf.c | 74 +++++++++++++++++++++++++----------------- vfdynf/fault.c | 63 ++++++++++++++++++----------------- vfdynf/stop.c | 15 +++++---- 4 files changed, 98 insertions(+), 74 deletions(-) diff --git a/include/pcre2_vfdynf.h b/include/pcre2_vfdynf.h index 4f3eb67..bbb0d2e 100644 --- a/include/pcre2_vfdynf.h +++ b/include/pcre2_vfdynf.h @@ -18,24 +18,28 @@ extern "C" { #endif -typedef struct _PCRE2_CONTEXT -{ - PVOID Code; - PVOID MatchData; -} PCRE2_CONTEXT, *PPCRE2_CONTEXT; +typedef PVOID PCRE2_HANDLE; +typedef PCRE2_HANDLE* PPCRE2_HANDLE; VOID Pcre2Close( - _In_ PPCRE2_CONTEXT Pcre2Handle + _In_ PCRE2_HANDLE Pcre2Handle ); _Must_inspect_result_ NTSTATUS Pcre2Compile( - _Out_ PPCRE2_CONTEXT Pcre2Handle, + _Out_ PPCRE2_HANDLE Pcre2Handle, _In_ PUNICODE_STRING Pattern ); +_Must_inspect_result_ +NTSTATUS Pcre2MatchEx( + _In_ PCRE2_HANDLE Pcre2Handle, + _In_ PUNICODE_STRING String, + _Out_ PBOOLEAN Match + ); + BOOLEAN Pcre2Match( - _In_ PPCRE2_CONTEXT Pcre2Handle, + _In_ PCRE2_HANDLE Pcre2Handle, _In_ PUNICODE_STRING String ); diff --git a/pcre2/pcre2_vfdynf.c b/pcre2/pcre2_vfdynf.c index 80390af..2b6be7b 100644 --- a/pcre2/pcre2_vfdynf.c +++ b/pcre2/pcre2_vfdynf.c @@ -92,35 +92,23 @@ NTSTATUS Pcre2ErrorToNtStatus( } VOID Pcre2Close( - _In_ PPCRE2_CONTEXT Pcre2 + _In_ PCRE2_HANDLE Pcre2Handle ) { - if (Pcre2->MatchData) - { - pcre2_match_data_free((pcre2_match_data*)Pcre2->MatchData); - Pcre2->MatchData = NULL; - } - - if (Pcre2->Code) - { - pcre2_code_free((pcre2_code*)Pcre2->Code); - Pcre2->Code = NULL; - } + pcre2_code_free((pcre2_code*)Pcre2Handle); } _Must_inspect_result_ NTSTATUS Pcre2Compile( - _Out_ PPCRE2_CONTEXT Pcre2, + _Out_ PPCRE2_HANDLE Pcre2Handle, _In_ PUNICODE_STRING Pattern ) { pcre2_code* code; - pcre2_match_data* matchData; int errorCode; size_t errorOffset; - Pcre2->Code = NULL; - Pcre2->MatchData = NULL; + *Pcre2Handle = NULL; code = pcre2_compile((PCRE2_SPTR16)Pattern->Buffer, Pattern->Length / sizeof(WCHAR), @@ -133,33 +121,59 @@ NTSTATUS Pcre2Compile( return Pcre2ErrorToNtStatus(errorCode); } + *Pcre2Handle = (PCRE2_HANDLE)code; + + return STATUS_SUCCESS; +} + +_Must_inspect_result_ +NTSTATUS Pcre2MatchEx( + _In_ PCRE2_HANDLE Pcre2Handle, + _In_ PUNICODE_STRING String, + _Out_ PBOOLEAN Match + ) +{ + pcre2_code* code; + pcre2_match_data* matchData; + int offset; + + *Match = FALSE; + + code = (pcre2_code*)Pcre2Handle; + matchData = pcre2_match_data_create_from_pattern(code, NULL); if (!matchData) { - pcre2_code_free(code); return STATUS_INSUFFICIENT_RESOURCES; } - Pcre2->Code = code; - Pcre2->MatchData = matchData; + offset = pcre2_match(code, + (PCRE2_SPTR16)String->Buffer, + String->Length / sizeof(WCHAR), + 0, + 0, + matchData, + NULL); + + pcre2_match_data_free(matchData); + + *Match = (offset >= 0); return STATUS_SUCCESS; } + BOOLEAN Pcre2Match( - _In_ PPCRE2_CONTEXT Pcre2, - _In_ PUNICODE_STRING Pattern + _In_ PCRE2_HANDLE Pcre2Handle, + _In_ PUNICODE_STRING String ) { - int offset; + BOOLEAN match; - offset = pcre2_match((pcre2_code*)Pcre2->Code, - (PCRE2_SPTR16)Pattern->Buffer, - Pattern->Length / sizeof(WCHAR), - 0, - 0, - (pcre2_match_data*)Pcre2->MatchData, - NULL); + if (NT_SUCCESS(Pcre2MatchEx(Pcre2Handle, String, &match))) + { + return match; + } - return (offset >= 0); + return FALSE; } diff --git a/vfdynf/fault.c b/vfdynf/fault.c index 19818fd..fa26c11 100644 --- a/vfdynf/fault.c +++ b/vfdynf/fault.c @@ -7,14 +7,14 @@ typedef struct _VFDYNF_FAULT_ENUM_MODULES_CONTEXT { PVOID CallerAddress; - PPCRE2_CONTEXT TypeInclude; + PCRE2_HANDLE Regex; BOOLEAN Result; } VFDYNF_FAULT_ENUM_MODULES_CONTEXT, *PVFDYNF_FAULT_ENUM_MODULES_CONTEXT; typedef struct _VFDYNF_EXCLUSION_REGEX { ULONG Count; - PPCRE2_CONTEXT Regex; + PPCRE2_HANDLE Regex; } VFDYNF_EXCLUSION_REGEX, *PVFDYNF_EXCLUSION_REGEX; typedef struct _VFDYNF_FAULT_COUNT @@ -32,10 +32,10 @@ typedef struct _VFDYNF_FAULT_CONTEXT ULONG64 LastClear; AVRF_STACK_TABLE StackTable; BOOLEAN RegexInitialized; - PCRE2_CONTEXT Include; + PCRE2_HANDLE IncludeRegex; VFDYNF_EXCLUSION_REGEX Exclusions; VFDYNF_FAULT_COUNT TypeCount[VFDYNF_FAULT_TYPE_COUNT]; - PCRE2_CONTEXT TypeInclude[VFDYNF_FAULT_TYPE_COUNT]; + PCRE2_HANDLE TypeIncludeRegex[VFDYNF_FAULT_TYPE_COUNT]; VFDYNF_EXCLUSION_REGEX TypeExclusions[VFDYNF_FAULT_TYPE_COUNT]; BYTE SymInfoBuffer[sizeof(SYMBOL_INFOW) + ((MAX_SYM_NAME + 1) * sizeof(WCHAR))]; WCHAR SymbolBuffer[MAX_SYM_NAME + 1 + MAX_PATH]; @@ -53,10 +53,10 @@ static VFDYNF_FAULT_CONTEXT AVrfpFaultContext = .LastClear = 0, .StackTable = { 0 }, .RegexInitialized = FALSE, - .Include = { 0 }, + .IncludeRegex = { 0 }, .Exclusions = { 0 }, .TypeCount = { 0 }, - .TypeInclude = { 0 }, + .TypeIncludeRegex = { 0 }, .TypeExclusions = { 0 }, .SymInfoBuffer = { 0 }, .SymbolBuffer = { 0 }, @@ -226,7 +226,7 @@ BOOLEAN AVrfpInitExclusionsRegexInternal( Exclusion->Count = count; Exclusion->Regex = RtlAllocateHeap(RtlProcessHeap(), 0, - count * sizeof(PCRE2_CONTEXT)); + count * sizeof(PCRE2_HANDLE)); if (!Exclusion->Regex) { DbgPrintEx(DPFLTR_VERIFIER_ID, @@ -242,7 +242,7 @@ BOOLEAN AVrfpInitExclusionsRegexInternal( { NTSTATUS status; UNICODE_STRING pattern; - PCRE2_CONTEXT pcre2; + PCRE2_HANDLE regex; RtlInitUnicodeString(&pattern, &Pattern[offset]); if (!pattern.Length) @@ -250,7 +250,7 @@ BOOLEAN AVrfpInitExclusionsRegexInternal( break; } - status = Pcre2Compile(&pcre2, &pattern); + status = Pcre2Compile(®ex, &pattern); if (!NT_SUCCESS(status)) { DbgPrintEx(DPFLTR_VERIFIER_ID, @@ -263,7 +263,7 @@ BOOLEAN AVrfpInitExclusionsRegexInternal( AVRF_ASSERT(count < Exclusion->Count); - Exclusion->Regex[count++] = pcre2; + Exclusion->Regex[count++] = regex; offset += ((pattern.Length / sizeof(WCHAR)) + 1); } @@ -311,7 +311,7 @@ BOOLEAN AVrfpInitIncludeRegex( if (pattern.Length) { - status = Pcre2Compile(&AVrfpFaultContext.Include, &pattern); + status = Pcre2Compile(&AVrfpFaultContext.IncludeRegex, &pattern); if (!NT_SUCCESS(status)) { DbgPrintEx(DPFLTR_VERIFIER_ID, @@ -332,7 +332,7 @@ BOOLEAN AVrfpInitIncludeRegex( continue; } - status = Pcre2Compile(&AVrfpFaultContext.TypeInclude[i], &pattern); + status = Pcre2Compile(&AVrfpFaultContext.TypeIncludeRegex[i], &pattern); if (!NT_SUCCESS(status)) { DbgPrintEx(DPFLTR_VERIFIER_ID, @@ -392,7 +392,7 @@ BOOLEAN AVrfpIsStackOverriddenByRegex( for (ULONG i = 0; i < AVrfpFaultContext.Exclusions.Count; i++) { - if (Pcre2Match(&AVrfpFaultContext.Exclusions.Regex[i], StackSymbols)) + if (Pcre2Match(AVrfpFaultContext.Exclusions.Regex[i], StackSymbols)) { return TRUE; } @@ -401,7 +401,7 @@ BOOLEAN AVrfpIsStackOverriddenByRegex( typeExclusions = &AVrfpFaultContext.TypeExclusions[AVrfpFaultTypeIndex(FaultType)]; for (ULONG i = 0; i < typeExclusions->Count; i++) { - if (Pcre2Match(&typeExclusions->Regex[i], StackSymbols)) + if (Pcre2Match(typeExclusions->Regex[i], StackSymbols)) { return TRUE; } @@ -423,18 +423,18 @@ BOOLEAN NTAPI AVrfpFaultModuleEnumCallback( if ((context->CallerAddress >= Module->BaseAddress) && (context->CallerAddress < Module->EndAddress)) { - if (AVrfpFaultContext.Include.Code) + if (AVrfpFaultContext.IncludeRegex) { - if (Pcre2Match(AVrfpFaultContext.Include.Code, &Module->BaseName)) + if (Pcre2Match(AVrfpFaultContext.IncludeRegex, &Module->BaseName)) { context->Result = TRUE; return TRUE; } } - if (context->TypeInclude) + if (context->Regex) { - if (Pcre2Match(context->TypeInclude, &Module->BaseName)) + if (Pcre2Match(context->Regex, &Module->BaseName)) { context->Result = TRUE; return TRUE; @@ -474,9 +474,9 @@ BOOLEAN AVrfIsCallerIncluded( AVRF_ASSERT(AVrfpFaultContext.RegexInitialized); - context.TypeInclude = &AVrfpFaultContext.TypeInclude[AVrfpFaultTypeIndex(FaultType)]; + context.Regex = AVrfpFaultContext.TypeIncludeRegex[AVrfpFaultTypeIndex(FaultType)]; - if (!AVrfpFaultContext.Include.Code && !context.TypeInclude->Code) + if (!AVrfpFaultContext.IncludeRegex && !context.Regex) { return TRUE; } @@ -1072,7 +1072,10 @@ VOID AVrfFaultProcessDetach( { for (ULONG i = 0; i < AVrfpFaultContext.Exclusions.Count; i++) { - Pcre2Close(&AVrfpFaultContext.Exclusions.Regex[i]); + if (AVrfpFaultContext.Exclusions.Regex[i]) + { + Pcre2Close(AVrfpFaultContext.Exclusions.Regex[i]); + } } RtlFreeHeap(RtlProcessHeap(), 0, AVrfpFaultContext.Exclusions.Regex); @@ -1091,7 +1094,10 @@ VOID AVrfFaultProcessDetach( { for (ULONG j = 0; j < entry->Count; j++) { - Pcre2Close(&entry->Regex[j]); + if (entry->Regex[j]) + { + Pcre2Close(&entry->Regex[j]); + } } RtlFreeHeap(RtlProcessHeap(), 0, entry->Regex); @@ -1100,17 +1106,16 @@ VOID AVrfFaultProcessDetach( } } - Pcre2Close(&AVrfpFaultContext.Include); + Pcre2Close(AVrfpFaultContext.IncludeRegex); for (ULONG i = 0; i < VFDYNF_FAULT_TYPE_COUNT; i++) { - Pcre2Close(&AVrfpFaultContext.TypeInclude[i]); + if (AVrfpFaultContext.TypeIncludeRegex[i]) + { + Pcre2Close(AVrfpFaultContext.TypeIncludeRegex[i]); + AVrfpFaultContext.TypeIncludeRegex[i] = NULL; + } } AVrfFreeStackTable(&AVrfpFaultContext.StackTable); - - if (AVrfpFaultContext.SymInitialized) - { - Delay_SymCleanup(NtCurrentProcess()); - } } diff --git a/vfdynf/stop.c b/vfdynf/stop.c index 7323820..3709611 100644 --- a/vfdynf/stop.c +++ b/vfdynf/stop.c @@ -9,7 +9,7 @@ typedef struct _VFDYNF_VERIFIER_STOP_MODULE_ENUM_CONTEXT BOOLEAN Result; } VFDYNF_VERIFIER_STOP_MODULE_ENUM_CONTEXT, *PVFDYNF_VERIFIER_STOP_MODULE_ENUM_CONTEXT; -static PCRE2_CONTEXT StopRegex = { NULL, NULL }; +static PCRE2_HANDLE AVrfpStopRegex = NULL; _Function_class_(AVRF_MODULE_ENUM_CALLBACK) BOOLEAN NTAPI AVrfpVerifierStopModuleEnumCallback( @@ -24,9 +24,9 @@ BOOLEAN NTAPI AVrfpVerifierStopModuleEnumCallback( if ((context->CallerAddress >= Module->BaseAddress) && (context->CallerAddress < Module->EndAddress)) { - if (StopRegex.Code) + if (AVrfpStopRegex) { - context->Result = Pcre2Match(StopRegex.Code, &Module->BaseName); + context->Result = Pcre2Match(AVrfpStopRegex, &Module->BaseName); } else { @@ -36,7 +36,7 @@ BOOLEAN NTAPI AVrfpVerifierStopModuleEnumCallback( return TRUE; } - if (!StopRegex.Code) + if (!AVrfpStopRegex) { // // Only check the primary module if a regex wasn't provided. @@ -75,7 +75,7 @@ BOOLEAN AVrfStopProcessAttach( return TRUE; } - status = Pcre2Compile(&StopRegex, &pattern); + status = Pcre2Compile(&AVrfpStopRegex, &pattern); if (!NT_SUCCESS(status)) { DbgPrintEx(DPFLTR_VERIFIER_ID, @@ -93,8 +93,9 @@ VOID AVrfStopProcessDetach( VOID ) { - if (StopRegex.Code) + if (AVrfpStopRegex) { - Pcre2Close(&StopRegex); + Pcre2Close(AVrfpStopRegex); + AVrfpStopRegex = NULL; } }