From be7ab87dca37f066d2e843e841d98d7731d3a22a Mon Sep 17 00:00:00 2001 From: Sergey Isakov Date: Tue, 8 Oct 2019 23:57:18 +0300 Subject: [PATCH] implemented patch with mask for kext, kernel and booter --- .../CloverV2/EFI/CLOVER/config-sample.plist | 6 + rEFIt_UEFI/Platform/Settings.c | 117 ++++++++++++------ rEFIt_UEFI/Platform/kernel_patcher.c | 50 +++----- rEFIt_UEFI/Platform/kernel_patcher.h | 1 + rEFIt_UEFI/Platform/kext_patcher.c | 72 +++++++++-- rEFIt_UEFI/refit/lib.h | 10 +- 6 files changed, 178 insertions(+), 78 deletions(-) diff --git a/CloverPackage/CloverV2/EFI/CLOVER/config-sample.plist b/CloverPackage/CloverV2/EFI/CLOVER/config-sample.plist index 5052da0df..3b87ac450 100644 --- a/CloverPackage/CloverV2/EFI/CLOVER/config-sample.plist +++ b/CloverPackage/CloverV2/EFI/CLOVER/config-sample.plist @@ -420,10 +420,14 @@ Find igKEwHRC + MaskFind + //////// MatchOS 10.14 Replace igKEwOtC + MaskReplace + AAAAAP8A Comment @@ -460,6 +464,8 @@ VoodooHDA Replace VGVsZXBob25lcwA= + MaskReplace + /////wAAAAAAAAA= Find diff --git a/rEFIt_UEFI/Platform/Settings.c b/rEFIt_UEFI/Platform/Settings.c index 2bb89a1ad..f73eefb86 100644 --- a/rEFIt_UEFI/Platform/Settings.c +++ b/rEFIt_UEFI/Platform/Settings.c @@ -836,6 +836,16 @@ CopyKernelAndKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Dst, Dst->KernelPatches[Dst->NrKernels].Count = Src->KernelPatches[i].Count; Dst->KernelPatches[Dst->NrKernels].MatchOS = AllocateCopyPool (AsciiStrSize(Src->KernelPatches[i].MatchOS), Src->KernelPatches[i].MatchOS); Dst->KernelPatches[Dst->NrKernels].MatchBuild = AllocateCopyPool (AsciiStrSize(Src->KernelPatches[i].MatchBuild), Src->KernelPatches[i].MatchBuild); + if (Src->KernelPatches[i].MaskFind != NULL) { + Dst->KernelPatches[Dst->NrKernels].MaskFind = AllocateCopyPool (Src->KernelPatches[i].DataLen, Src->KernelPatches[i].MaskFind); + } else { + Dst->KernelPatches[Dst->NrKernels].MaskFind = NULL; + } + if (Src->KernelPatches[i].MaskReplace != NULL) { + Dst->KernelPatches[Dst->NrKernels].MaskReplace = AllocateCopyPool (Src->KernelPatches[i].DataLen, Src->KernelPatches[i].MaskReplace); + } else { + Dst->KernelPatches[Dst->NrKernels].MaskReplace = NULL; + } ++(Dst->NrKernels); } } @@ -1069,22 +1079,17 @@ FillinKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Patches, if (Patches->KextPatches) { Patches->NrKexts = 0; FreePool (Patches->KextPatches); + Patches->KextPatches = NULL; } if (Count > 0) { TagPtr Prop2 = NULL, Dict = NULL; KEXT_PATCH *newPatches = AllocateZeroPool (Count * sizeof(KEXT_PATCH)); - // Patches->NrKexts = 0; - /* if (Patches->KextPatches != NULL) { - CopyMem (newPatches, Patches->KextPatches, (Patches->NrKexts * sizeof(KEXT_PATCH))); - FreePool (Patches->KextPatches); - } */ - Patches->KextPatches = newPatches; DBG ("KextsToPatch: %d requested\n", Count); for (i = 0; i < Count; i++) { CHAR8 *KextPatchesName, *KextPatchesLabel; - UINTN FindLen = 0, ReplaceLen = 0; + UINTN FindLen = 0, ReplaceLen = 0, MaskLen = 0; UINT8 *TmpData, *TmpPatch; EFI_STATUS Status = GetElement (Prop, i, &Prop2); if (EFI_ERROR (Status)) { @@ -1095,7 +1100,6 @@ FillinKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Patches, if (Prop2 == NULL) { break; } - DBG (" - [%02d]:", i); Dict = GetProperty (Prop2, "Name"); @@ -1119,14 +1123,11 @@ FillinKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Patches, } else { AsciiStrCatS(KextPatchesLabel, 255, " (NoLabel)"); } - - DBG (" %a", KextPatchesLabel); Patches->KextPatches[Patches->NrKexts].MenuItem.BValue = TRUE; Dict = GetProperty (Prop2, "Disabled"); if ((Dict != NULL) && IsPropertyTrue (Dict)) { - Patches->KextPatches[Patches->NrKexts].MenuItem.BValue = FALSE; } @@ -1140,15 +1141,35 @@ FillinKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Patches, Patches->KextPatches[Patches->NrKexts].Data = AllocateCopyPool (FindLen, TmpData); Patches->KextPatches[Patches->NrKexts].DataLen = FindLen; + FreePool(TmpData); + TmpData = GetDataSetting (Prop2, "MaskFind", &MaskLen); + MaskLen = (MaskLen > FindLen)? FindLen : MaskLen; + + if (TmpData == NULL || MaskLen == 0) { + Patches->KextPatches[Patches->NrKexts].MaskFind = NULL; + } else { + Patches->KextPatches[Patches->NrKexts].MaskFind = AllocateZeroPool (FindLen); + CopyMem(Patches->KextPatches[Patches->NrKexts].MaskFind, TmpData, MaskLen); + } + FreePool(TmpData); Patches->KextPatches[Patches->NrKexts].Patch = AllocateCopyPool (FindLen, TmpPatch); + FreePool(TmpPatch); + MaskLen = 0; + TmpData = GetDataSetting (Prop2, "MaskReplace", &MaskLen); + MaskLen = (MaskLen > FindLen)? FindLen : MaskLen; + + if (TmpData == NULL || MaskLen == 0) { + Patches->KextPatches[Patches->NrKexts].MaskReplace = NULL; + } else { + Patches->KextPatches[Patches->NrKexts].MaskReplace = AllocateZeroPool (FindLen); + CopyMem(Patches->KextPatches[Patches->NrKexts].MaskReplace, TmpData, MaskLen); + } + FreePool(TmpData); Patches->KextPatches[Patches->NrKexts].MatchOS = NULL; Patches->KextPatches[Patches->NrKexts].MatchBuild = NULL; Patches->KextPatches[Patches->NrKexts].Name = AllocateCopyPool (AsciiStrSize(KextPatchesName), KextPatchesName); - Patches->KextPatches[Patches->NrKexts].Label = AllocateCopyPool (AsciiStrSize(KextPatchesLabel), KextPatchesLabel); - - FreePool(TmpData); - FreePool(TmpPatch); FreePool(KextPatchesName); + Patches->KextPatches[Patches->NrKexts].Label = AllocateCopyPool (AsciiStrSize(KextPatchesLabel), KextPatchesLabel); FreePool(KextPatchesLabel); // check enable/disabled patch (OS based) by Micky1979 @@ -1203,7 +1224,7 @@ FillinKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Patches, DBG ("KernelToPatch: %d requested\n", Count); for (i = 0; i < Count; i++) { CHAR8 *KernelPatchesLabel; - UINTN FindLen = 0, ReplaceLen = 0; + UINTN FindLen = 0, ReplaceLen = 0, MaskLen = 0; UINT8 *TmpData, *TmpPatch; EFI_STATUS Status = GetElement (Prop, i, &Prop2); if (EFI_ERROR (Status)) { @@ -1214,7 +1235,6 @@ FillinKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Patches, if (Prop2 == NULL) { break; } - DBG (" - [%02d]:", i); Dict = GetProperty (Prop2, "Comment"); @@ -1223,15 +1243,9 @@ FillinKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Patches, } else { KernelPatchesLabel = AllocateCopyPool (8, "NoLabel"); } - DBG (" %a", KernelPatchesLabel); - //Patches->KernelPatches[Patches->NrKernels].MenuItem.BValue = TRUE; Dict = GetProperty (Prop2, "Disabled"); - /* if ((Dict != NULL) && IsPropertyTrue (Dict)) { - DBG(" :: patch disabled\n"); - Patches->KernelPatches[Patches->NrKernels].MenuItem.BValue = FALSE; - } */ Patches->KernelPatches[Patches->NrKernels].MenuItem.BValue = !IsPropertyTrue (Dict); TmpData = GetDataSetting (Prop2, "Find", &FindLen); @@ -1244,7 +1258,27 @@ FillinKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Patches, Patches->KernelPatches[Patches->NrKernels].Data = AllocateCopyPool (FindLen, TmpData); Patches->KernelPatches[Patches->NrKernels].DataLen = FindLen; + FreePool(TmpData); + TmpData = GetDataSetting (Prop2, "MaskFind", &MaskLen); + MaskLen = (MaskLen > FindLen)? FindLen : MaskLen; + if (TmpData == NULL || MaskLen == 0) { + Patches->KernelPatches[Patches->NrKexts].MaskFind = NULL; + } else { + Patches->KernelPatches[Patches->NrKexts].MaskFind = AllocateZeroPool (FindLen); + CopyMem(Patches->KernelPatches[Patches->NrKexts].MaskFind, TmpData, MaskLen); + } + FreePool(TmpData); Patches->KernelPatches[Patches->NrKernels].Patch = AllocateCopyPool (FindLen, TmpPatch); + FreePool(TmpPatch); + TmpData = GetDataSetting (Prop2, "MaskReplace", &MaskLen); + MaskLen = (MaskLen > FindLen)? FindLen : MaskLen; + if (TmpData == NULL || MaskLen == 0) { + Patches->KernelPatches[Patches->NrKexts].MaskReplace = NULL; + } else { + Patches->KernelPatches[Patches->NrKexts].MaskReplace = AllocateZeroPool (FindLen); + CopyMem(Patches->KernelPatches[Patches->NrKexts].MaskReplace, TmpData, MaskLen); + } + FreePool(TmpData); Patches->KernelPatches[Patches->NrKernels].Count = 0; Patches->KernelPatches[Patches->NrKernels].MatchOS = NULL; Patches->KernelPatches[Patches->NrKernels].MatchBuild = NULL; @@ -1254,9 +1288,6 @@ FillinKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Patches, if (Dict != NULL) { Patches->KernelPatches[Patches->NrKernels].Count = GetPropertyInteger (Dict, 0); } - - FreePool(TmpData); - FreePool(TmpPatch); FreePool(KernelPatchesLabel); // check enable/disabled patch (OS based) by Micky1979 @@ -1271,7 +1302,6 @@ FillinKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Patches, Patches->KernelPatches[Patches->NrKernels].MatchBuild = AllocateCopyPool (AsciiStrSize (Dict->string), Dict->string); DBG(" :: MatchBuild: %a", Patches->KernelPatches[Patches->NrKernels].MatchBuild); } - DBG (" :: data len: %d\n", Patches->KernelPatches[Patches->NrKernels].DataLen); Patches->NrKernels++; } @@ -1283,6 +1313,7 @@ FillinKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Patches, INTN i, Count = GetTagCount (Prop); //delete old and create new if (Patches->BootPatches) { + //TODO - free all subtree Patches->NrBoots = 0; FreePool (Patches->BootPatches); } @@ -1294,18 +1325,16 @@ FillinKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Patches, DBG ("BootPatches: %d requested\n", Count); for (i = 0; i < Count; i++) { CHAR8 *BootPatchesLabel; - UINTN FindLen = 0, ReplaceLen = 0; + UINTN FindLen = 0, ReplaceLen = 0, MaskLen = 0; UINT8 *TmpData, *TmpPatch; EFI_STATUS Status = GetElement (Prop, i, &Prop2); if (EFI_ERROR (Status)) { DBG (" - [%02d]: error %r getting next element\n", i, Status); continue; } - if (Prop2 == NULL) { break; } - DBG (" - [%02d]:", i); Dict = GetProperty (Prop2, "Comment"); @@ -1323,7 +1352,6 @@ FillinKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Patches, TmpData = GetDataSetting (Prop2, "Find", &FindLen); TmpPatch = GetDataSetting (Prop2, "Replace", &ReplaceLen); - if (!FindLen || !ReplaceLen || (FindLen != ReplaceLen)) { DBG (" :: invalid Find/Replace data - skipping!\n"); continue; @@ -1331,7 +1359,27 @@ FillinKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Patches, Patches->BootPatches[Patches->NrBoots].Data = AllocateCopyPool (FindLen, TmpData); Patches->BootPatches[Patches->NrBoots].DataLen = FindLen; + FreePool(TmpData); + TmpData = GetDataSetting (Prop2, "MaskFind", &MaskLen); + MaskLen = (MaskLen > FindLen)? FindLen : MaskLen; + if (TmpData == NULL || MaskLen == 0) { + Patches->BootPatches[Patches->NrKexts].MaskFind = NULL; + } else { + Patches->BootPatches[Patches->NrKexts].MaskFind = AllocateZeroPool (FindLen); + CopyMem(Patches->BootPatches[Patches->NrKexts].MaskFind, TmpData, MaskLen); + } + FreePool(TmpData); Patches->BootPatches[Patches->NrBoots].Patch = AllocateCopyPool (FindLen, TmpPatch); + FreePool(TmpPatch); + TmpData = GetDataSetting (Prop2, "MaskReplace", &MaskLen); + MaskLen = (MaskLen > FindLen)? FindLen : MaskLen; + if (TmpData == NULL || MaskLen == 0) { + Patches->BootPatches[Patches->NrKexts].MaskReplace = NULL; + } else { + Patches->BootPatches[Patches->NrKexts].MaskReplace = AllocateZeroPool (FindLen); + CopyMem(Patches->BootPatches[Patches->NrKexts].MaskReplace, TmpData, MaskLen); + } + FreePool(TmpData); Patches->BootPatches[Patches->NrBoots].Count = 0; Patches->BootPatches[Patches->NrBoots].MatchOS = NULL; Patches->BootPatches[Patches->NrBoots].MatchBuild = NULL; @@ -1341,9 +1389,6 @@ FillinKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Patches, if (Dict != NULL) { Patches->BootPatches[Patches->NrBoots].Count = GetPropertyInteger (Dict, 0); } - - FreePool(TmpData); - FreePool(TmpPatch); FreePool(BootPatchesLabel); Dict = GetProperty (Prop2, "MatchOS"); @@ -6192,8 +6237,8 @@ GetUserSettings( Status = GetElement (Prop, i, &Dict); if (!EFI_ERROR(Status)) { Prop2 = GetProperty (Dict, "Comment"); - if (Prop2 && Prop2->string) { - DBG(" %a\n", Prop2->string); + if (Prop2 && Prop2->string) { + DBG(" %a\n", Prop2->string); } Prop2 = GetProperty(Dict, "Disabled"); if (IsPropertyFalse(Prop2)) { diff --git a/rEFIt_UEFI/Platform/kernel_patcher.c b/rEFIt_UEFI/Platform/kernel_patcher.c index e90acd9f6..7861b4427 100644 --- a/rEFIt_UEFI/Platform/kernel_patcher.c +++ b/rEFIt_UEFI/Platform/kernel_patcher.c @@ -1732,28 +1732,16 @@ KernelUserPatch(IN UINT8 *UKernelData, LOADER_ENTRY *Entry) continue; } -#if 0 //!defined(FKERNELPATCH) - Num = SearchAndCount( - UKernelData, - KERNEL_MAX_SIZE, - Entry->KernelAndKextPatches->KernelPatches[i].Data, - Entry->KernelAndKextPatches->KernelPatches[i].DataLen - ); - - if (!Num) { - DBG_RT(Entry, "==> pattern(s) not found.\n"); - continue; - } -#endif //FKERNELPATCH - - Num = SearchAndReplace( - UKernelData, - KERNEL_MAX_SIZE, - Entry->KernelAndKextPatches->KernelPatches[i].Data, - Entry->KernelAndKextPatches->KernelPatches[i].DataLen, - Entry->KernelAndKextPatches->KernelPatches[i].Patch, - Entry->KernelAndKextPatches->KernelPatches[i].Count - ); + Num = SearchAndReplaceMask( + UKernelData, + KERNEL_MAX_SIZE, + Entry->KernelAndKextPatches->KernelPatches[i].Data, + Entry->KernelAndKextPatches->KernelPatches[i].MaskFind, + Entry->KernelAndKextPatches->KernelPatches[i].DataLen, + Entry->KernelAndKextPatches->KernelPatches[i].Patch, + Entry->KernelAndKextPatches->KernelPatches[i].MaskReplace, + Entry->KernelAndKextPatches->KernelPatches[i].Count + ); if (Num) { y++; @@ -1779,14 +1767,16 @@ BooterPatch(IN UINT8 *BooterData, IN UINT64 BooterSize, LOADER_ENTRY *Entry) continue; } - Num = SearchAndReplace( - BooterData, - BooterSize, - Entry->KernelAndKextPatches->BootPatches[i].Data, - Entry->KernelAndKextPatches->BootPatches[i].DataLen, - Entry->KernelAndKextPatches->BootPatches[i].Patch, - Entry->KernelAndKextPatches->BootPatches[i].Count - ); + Num = SearchAndReplaceMask( + BooterData, + BooterSize, + Entry->KernelAndKextPatches->BootPatches[i].Data, + Entry->KernelAndKextPatches->BootPatches[i].MaskFind, + Entry->KernelAndKextPatches->BootPatches[i].DataLen, + Entry->KernelAndKextPatches->BootPatches[i].Patch, + Entry->KernelAndKextPatches->BootPatches[i].MaskReplace, + Entry->KernelAndKextPatches->BootPatches[i].Count + ); if (Num) { y++; diff --git a/rEFIt_UEFI/Platform/kernel_patcher.h b/rEFIt_UEFI/Platform/kernel_patcher.h index 00658fb61..47fa0594a 100644 --- a/rEFIt_UEFI/Platform/kernel_patcher.h +++ b/rEFIt_UEFI/Platform/kernel_patcher.h @@ -149,5 +149,6 @@ UINTN SearchAndCount(UINT8 *Source, UINT64 SourceSize, UINT8 *Search, UINTN Sear // UINTN SearchAndReplace(UINT8 *Source, UINT64 SourceSize, UINT8 *Search, UINTN SearchSize, UINT8 *Replace, INTN MaxReplaces); +UINTN SearchAndReplaceMask(UINT8 *Source, UINT64 SourceSize, UINT8 *Search, UINT8 *MaskSearch, UINTN SearchSize, UINT8 *Replace, UINT8 *MaskReplace, INTN MaxReplaces); #endif /* !__LIBSAIO_KERNEL_PATCHER_H */ diff --git a/rEFIt_UEFI/Platform/kext_patcher.c b/rEFIt_UEFI/Platform/kext_patcher.c index 0bc11a6e4..3eb816359 100644 --- a/rEFIt_UEFI/Platform/kext_patcher.c +++ b/rEFIt_UEFI/Platform/kext_patcher.c @@ -69,6 +69,62 @@ UINTN SearchAndReplace(UINT8 *Source, UINT64 SourceSize, UINT8 *Search, UINTN Se return NumReplaces; } +BOOLEAN CompareMemMask(UINT8 *Source, UINT8 *Search, UINT8 *Mask, UINTN SearchSize) +{ + UINT8 M; + UINTN Ind; + if (!Mask) { + return !CompareMem(Source, Search, SearchSize); + } + for (Ind = 0; Ind < SearchSize; Ind++) { + M = *Mask++; + if ((*Source++ & M) != (*Search++ & M)) { + return FALSE; + } + } + return TRUE; +} + +VOID CopyMemMask(UINT8 *Dest, UINT8 *Replace, UINT8 *Mask, UINTN SearchSize) +{ + UINT8 M, D; + UINTN Ind; + if (!Mask) { + CopyMem(Dest, Replace, SearchSize); + return; + } + for (Ind = 0; Ind < SearchSize; Ind++) { + M = *Mask++; + D = *Dest; + *Dest++ = (((D ^ *Replace++) & M) ^ D) ^ M; + } +} + +UINTN SearchAndReplaceMask(UINT8 *Source, UINT64 SourceSize, UINT8 *Search, UINT8 *MaskSearch, UINTN SearchSize, + UINT8 *Replace, UINT8 *MaskReplace, INTN MaxReplaces) +{ + UINTN NumReplaces = 0; + BOOLEAN NoReplacesRestriction = MaxReplaces <= 0; + UINT8 *End = Source + SourceSize; + if (!Source || !Search || !Replace || !SearchSize) { + return 0; + } + while ((Source < End) && (NoReplacesRestriction || (MaxReplaces > 0))) { + if (CompareMemMask(Source, Search, MaskSearch, SearchSize)) { + CopyMemMask(Source, Replace, MaskReplace, SearchSize); + NumReplaces++; + MaxReplaces--; + Source += SearchSize; + } else { + Source++; + } + + } + + return NumReplaces; +} + + UINTN SearchAndReplaceTxt(UINT8 *Source, UINT64 SourceSize, UINT8 *Search, UINTN SearchSize, UINT8 *Replace, INTN MaxReplaces) { UINTN NumReplaces = 0; @@ -449,7 +505,7 @@ VOID AppleRTCPatch(UINT8 *Driver, UINT32 DriverSize, CHAR8 *InfoPlist, UINT32 In if (NumLion_X64 + NumLion_i386 + NumML + NumMavMoj3 + NumMoj4 > 1) { // more then one pattern found - we do not know what to do with it - // and we'll skipp it + // and we'll skip it Print(L"AppleRTCPatch: ERROR: multiple patterns found (LionX64: %d, Lioni386: %d, ML: %d, MavMoj3: %d, Moj4: %d) - skipping patching!\n", NumLion_X64, NumLion_i386, NumML, NumMavMoj3, NumMoj4); gBS->Stall(5000000); @@ -916,12 +972,14 @@ VOID AnyKextPatch(UINT8 *Driver, UINT32 DriverSize, CHAR8 *InfoPlist, UINT32 Inf if (!Entry->KernelAndKextPatches->KextPatches[N].IsPlistPatch) { // kext binary patch DBG_RT(Entry, "Binary patch\n"); - Num = SearchAndReplace(Driver, - DriverSize, - Entry->KernelAndKextPatches->KextPatches[N].Data, - Entry->KernelAndKextPatches->KextPatches[N].DataLen, - Entry->KernelAndKextPatches->KextPatches[N].Patch, - -1); + Num = SearchAndReplaceMask(Driver, + DriverSize, + Entry->KernelAndKextPatches->KextPatches[N].Data, + Entry->KernelAndKextPatches->KextPatches[N].MaskFind, + Entry->KernelAndKextPatches->KextPatches[N].DataLen, + Entry->KernelAndKextPatches->KextPatches[N].Patch, + Entry->KernelAndKextPatches->KextPatches[N].MaskReplace, + -1); } else { // Info plist patch DBG_RT(Entry, "Info.plist data : '"); diff --git a/rEFIt_UEFI/refit/lib.h b/rEFIt_UEFI/refit/lib.h index bf090c125..bf875b50b 100644 --- a/rEFIt_UEFI/refit/lib.h +++ b/rEFIt_UEFI/refit/lib.h @@ -541,12 +541,11 @@ struct KEXT_PATCH #endif UINT8 *Data; UINT8 *Patch; + UINT8 *MaskFind; + UINT8 *MaskReplace; CHAR8 *MatchOS; CHAR8 *MatchBuild; -// KEXT_PATCH *Next; -// UINT64 Index; - INPUT_ITEM MenuItem; //zzzz -// BOOLEAN Disabled; + INPUT_ITEM MenuItem; }; typedef struct { @@ -554,11 +553,12 @@ typedef struct { INTN DataLen; UINT8 *Data; UINT8 *Patch; + UINT8 *MaskFind; + UINT8 *MaskReplace; INTN Count; CHAR8 *MatchOS; CHAR8 *MatchBuild; INPUT_ITEM MenuItem; -// BOOLEAN Disabled; } KERNEL_PATCH; typedef struct KERNEL_AND_KEXT_PATCHES