Skip to content

Commit

Permalink
pcre2 wrapper improvement
Browse files Browse the repository at this point in the history
  • Loading branch information
jxy-s committed Sep 19, 2024
1 parent 219a834 commit 63da380
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 74 deletions.
20 changes: 12 additions & 8 deletions include/pcre2_vfdynf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
);

Expand Down
74 changes: 44 additions & 30 deletions pcre2/pcre2_vfdynf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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;
}
63 changes: 34 additions & 29 deletions vfdynf/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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];
Expand All @@ -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 },
Expand Down Expand Up @@ -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,
Expand All @@ -242,15 +242,15 @@ BOOLEAN AVrfpInitExclusionsRegexInternal(
{
NTSTATUS status;
UNICODE_STRING pattern;
PCRE2_CONTEXT pcre2;
PCRE2_HANDLE regex;

RtlInitUnicodeString(&pattern, &Pattern[offset]);
if (!pattern.Length)
{
break;
}

status = Pcre2Compile(&pcre2, &pattern);
status = Pcre2Compile(&regex, &pattern);
if (!NT_SUCCESS(status))
{
DbgPrintEx(DPFLTR_VERIFIER_ID,
Expand All @@ -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);
}
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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());
}
}
15 changes: 8 additions & 7 deletions vfdynf/stop.c
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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
{
Expand All @@ -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.
Expand Down Expand Up @@ -75,7 +75,7 @@ BOOLEAN AVrfStopProcessAttach(
return TRUE;
}

status = Pcre2Compile(&StopRegex, &pattern);
status = Pcre2Compile(&AVrfpStopRegex, &pattern);
if (!NT_SUCCESS(status))
{
DbgPrintEx(DPFLTR_VERIFIER_ID,
Expand All @@ -93,8 +93,9 @@ VOID AVrfStopProcessDetach(
VOID
)
{
if (StopRegex.Code)
if (AVrfpStopRegex)
{
Pcre2Close(&StopRegex);
Pcre2Close(AVrfpStopRegex);
AVrfpStopRegex = NULL;
}
}

0 comments on commit 63da380

Please sign in to comment.