a feature to double search pattern in kernel/kext/boot

Signed-off-by: SergeySlice <sergey.slice@gmail.com>
This commit is contained in:
SergeySlice 2020-04-25 19:18:18 +03:00
parent ddd42ed08b
commit 615b710944
8 changed files with 289 additions and 84 deletions

View File

@ -451,6 +451,28 @@
<key>Replace</key>
<data>igKEwOtE</data>
</dict>
<dict>
<key>Comment</key>
<string>Lapci panic patch example</string>
<key>MatchOS</key>
<string>All</string>
<key>Disabled</key>
<true/>
<key>StartPattern</key>
<data>ACnHeAAx241H+oM=</data>
<key>MaskStart</key>
<data>/////wA=</data>
<key>Find</key>
<data>6AAA//+DAAAAAAAA</data>
<key>MaskFind</key>
<data>/wAA////AAAAAP//</data>
<key>Replace</key>
<data>6AAA//8xwJCQkJCQ</data>
<key>MaskReplace</key>
<data>/wAA////////////</data>
<key>RangeFind</key>
<integer>200</integer>
</dict>
</array>
<key>#ForceKextsToLoad</key>
<array>

View File

@ -1,2 +1,4 @@
Powershell Dismount-DiskImage -ImagePath "C:\Users\Sergey\Desktop\QEMU\test1.vhdx"
"C:\Program Files\qemu\qemu-system-x86_64.exe" -L . -m 2048 -cpu Penryn -bios OVMF.fd -vga cirrus -device ahci,id=ahc -drive format=vhdx,id=hda,file=test1.vhdx -drive format=vhdx,id=hdb,file=freedos.vhdx -usb -device usb-mouse,bus=usb-bus.0,port=2 -device usb-kbd,bus=usb-bus.0,port=1
Powershell Mount-DiskImage -ImagePath "C:\Users\Sergey\Desktop\QEMU\test1.vhdx"

View File

@ -3,17 +3,28 @@
#cp -v /Users/sergey/src/edk2/Clover/CloverPackage/CloverV2/EFI/CLOVER/drivers64UEFI/VBoxHfs-64.efi /Volumes/TEFI/EFI/CLOVER/drivers64UEFI
#sudo umount /Volumes/QEFI
diskutil umount /dev/disk2s1
diskutil umount /dev/disk2s2
diskutil eject disk2
#qemu -L ~/Desktop/QEMU-Clover/QEMU -m 2048 -cpu core2duo -bios OVMF.fd -machine q35 -usb -device usb-mouse,bus=usb-bus.0,port=2 -device usb-kbd,bus=usb-bus.0,port=1 -device ahci,id=ahc -device ide-drive,bus=ahc.0,drive=hdc -drive id=hdc,file=/Users/sergey/Desktop/QEMU-Clover/QEMU-test2.img -device ide-drive,bus=ahc.1,drive=hdb -drive id=hdb,if=none,file=/Users/sergey/Desktop/QEMU-Clover/freedos.img -net nic,macaddr=00:12:32:43:55:16 -net user,name=lan -serial stdio
#qemu -L ~/Desktop/QEMU-Clover/QEMU -m 2048 -vga std -cpu core2duo -bios OVMF.fd -machine q35 -usb -device usb-mouse,bus=usb-bus.0,port=2 -device usb-kbd,bus=usb-bus.0,port=1 -hda /Users/sergey/Desktop/QEMU-Clover/QEMU-test2.img -hdc /Users/sergey/Desktop/QEMU-Clover/freedos.img -net nic,macaddr=00:12:32:43:55:16 -net user,name=lan
#-serial stdio
qemu -L . -m 2048 -cpu core2duo -bios bios.bin-1.13.0 -machine q35 -device ahci,id=ahc -drive format=raw,file=QEMU-test3.img -usb -device usb-mouse,bus=usb-bus.0,port=2 -device usb-kbd,bus=usb-bus.0,port=1
#qemu -L . -m 2048 -cpu core2duo -bios bios.bin-1.13.0 -machine q35 -device ahci,id=ahc -drive format=raw,file=QEMU-test3.img -usb -device usb-mouse,bus=usb-bus.0,port=2 -device usb-kbd,bus=usb-bus.0,port=1
#-serial stdio
#qemu -L ~/Desktop/QEMU-Clover/QEMU -m 2048 -vga std -cpu core2duo -bios bios.bin -machine q35 -usb -device usb-mouse,bus=usb-bus.0,port=2 -device usb-kbd,bus=usb-bus.0,port=1 -hda /Users/sergey/Desktop/QEMU-Clover/QEMU-test2.img -hdc /Users/sergey/Desktop/QEMU-Clover/freedos.img -net nic,macaddr=00:12:32:43:55:16 -net user,name=lan
#-serial stdio
#sudo mkdir /Volumes/QEFI
#sudo mount -t msdos /dev/disk1s1 /Volumes/QEFI
diskutil mount /dev/disk2s1
qemu-system-x86_64 -L ~/Desktop/QEMU-Clover/QEMU -m 2048 -cpu Penryn \
-bios OVMF.fd \
-vga cirrus \
-device ahci,id=ahc \
-drive format=raw,id=hda,file=/Users/sergey/Desktop/QEMU-Clover/QEMU-test2.img \
-drive format=raw,id=hdc,file=/Users/sergey/Desktop/QEMU-Clover/small.ffs \
-drive format=raw,id=hdb,file=/Users/sergey/Desktop/QEMU-Clover/freedos.img \
-usb -device usb-mouse,bus=usb-bus.0,port=2 -device usb-kbd,bus=usb-bus.0,port=1
hdiutil attach /Users/sergey/Desktop/QEMU-Clover/QEMU-test2.img
diskutil mount disk2s1

View File

@ -794,6 +794,15 @@ CopyKernelAndKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Dst,
Dst->KextPatches[Dst->NrKexts].Patch = (__typeof__(Dst->KextPatches[Dst->NrKexts].Patch))AllocateCopyPool (Src->KextPatches[i].DataLen, Src->KextPatches[i].Patch);
Dst->KextPatches[Dst->NrKexts].MatchOS = (__typeof__(Dst->KextPatches[Dst->NrKexts].MatchOS))AllocateCopyPool (AsciiStrSize(Src->KextPatches[i].MatchOS), Src->KextPatches[i].MatchOS);
Dst->KextPatches[Dst->NrKexts].MatchBuild = (__typeof__(Dst->KextPatches[Dst->NrKexts].MatchBuild))AllocateCopyPool (AsciiStrSize(Src->KextPatches[i].MatchBuild), Src->KextPatches[i].MatchBuild);
if (Src->KextPatches[i].StartPattern != NULL) {
Dst->KextPatches[Dst->NrKexts].StartPattern = (__typeof__(Dst->KextPatches[Dst->NrKexts].StartPattern))AllocateCopyPool (Src->KextPatches[i].StartPatternLen, Src->KextPatches[i].StartPattern);
Dst->KextPatches[Dst->NrKexts].StartMask = (__typeof__(Dst->KextPatches[Dst->NrKexts].StartMask))AllocateCopyPool (Src->KextPatches[i].StartPatternLen, Src->KextPatches[i].StartMask);
} else {
Dst->KextPatches[Dst->NrKexts].StartPattern = NULL;
Dst->KextPatches[Dst->NrKexts].StartMask = NULL;
}
Dst->KextPatches[Dst->NrKexts].StartPatternLen = Src->KextPatches[i].StartPatternLen;
Dst->KextPatches[Dst->NrKexts].SearchLen = Src->KextPatches[i].SearchLen;
++(Dst->NrKexts);
}
}
@ -824,13 +833,23 @@ CopyKernelAndKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Dst,
if (Src->KernelPatches[i].MaskFind != NULL) {
Dst->KernelPatches[Dst->NrKernels].MaskFind = (__typeof__(Dst->KernelPatches[Dst->NrKernels].MaskFind))AllocateCopyPool (Src->KernelPatches[i].DataLen, Src->KernelPatches[i].MaskFind);
} else {
Dst->KernelPatches[Dst->NrKernels].MaskFind = NULL;
Dst->KernelPatches[Dst->NrKernels].MaskFind = NULL;
}
if (Src->KernelPatches[i].MaskReplace != NULL) {
Dst->KernelPatches[Dst->NrKernels].MaskReplace = (__typeof__(Dst->KernelPatches[Dst->NrKernels].MaskReplace))AllocateCopyPool (Src->KernelPatches[i].DataLen, Src->KernelPatches[i].MaskReplace);
} else {
Dst->KernelPatches[Dst->NrKernels].MaskReplace = NULL;
Dst->KernelPatches[Dst->NrKernels].MaskReplace = NULL;
}
if (Src->KernelPatches[i].StartPattern != NULL) {
Dst->KernelPatches[Dst->NrKernels].StartPattern = (__typeof__(Dst->KernelPatches[Dst->NrKernels].StartPattern))AllocateCopyPool (Src->KernelPatches[i].StartPatternLen, Src->KernelPatches[i].StartPattern);
Dst->KernelPatches[Dst->NrKernels].StartMask = (__typeof__(Dst->KernelPatches[Dst->NrKernels].StartMask))AllocateCopyPool (Src->KernelPatches[i].StartPatternLen, Src->KernelPatches[i].StartMask);
} else {
Dst->KernelPatches[Dst->NrKernels].StartPattern = NULL;
Dst->KernelPatches[Dst->NrKernels].StartMask = NULL;
}
Dst->KernelPatches[Dst->NrKernels].StartPatternLen = Src->KernelPatches[Dst->NrKernels].StartPatternLen;
Dst->KernelPatches[Dst->NrKernels].SearchLen = Src->KernelPatches[Dst->NrKernels].SearchLen;
++(Dst->NrKernels);
}
}
@ -1078,6 +1097,13 @@ FillinKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Patches,
if (Patches->KextPatches[i].MatchBuild) {
FreePool(Patches->KextPatches[i].MatchBuild);
}
if (Patches->KextPatches[i].StartPattern) {
FreePool(Patches->KextPatches[i].StartPattern);
}
if (Patches->KextPatches[i].StartMask) {
FreePool(Patches->KextPatches[i].StartMask);
}
}
Patches->NrKexts = 0;
FreePool(Patches->KextPatches);
@ -1088,21 +1114,21 @@ FillinKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Patches,
KEXT_PATCH *newPatches = (__typeof__(newPatches))AllocateZeroPool (Count * sizeof(KEXT_PATCH));
Patches->KextPatches = newPatches;
DBG("KextsToPatch: %lld requested\n", Count);
DBG("KextsToPatch: %lld requested\n", Count);
for (i = 0; i < Count; i++) {
CHAR8 *KextPatchesName, *KextPatchesLabel;
UINTN FindLen = 0, ReplaceLen = 0, MaskLen = 0;
UINT8 *TmpData, *TmpPatch;
EFI_STATUS Status = GetElement (Prop, i, &Prop2);
if (EFI_ERROR(Status)) {
DBG(" - [%02lld]: Patches error %s getting next element\n", i, strerror(Status));
DBG(" - [%02lld]: Patches error %s getting next element\n", i, strerror(Status));
continue;
}
if (Prop2 == NULL) {
break;
}
DBG(" - [%02lld]:", i);
DBG(" - [%02lld]:", i);
Dict = GetProperty(Prop2, "Name");
if (Dict == NULL) {
@ -1132,6 +1158,29 @@ FillinKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Patches,
if ((Dict != NULL) && IsPropertyTrue (Dict)) {
Patches->KextPatches[Patches->NrKexts].MenuItem.BValue = FALSE;
}
Dict = GetProperty(Prop2, "RangeFind");
Patches->KextPatches[Patches->NrKexts].SearchLen = GetPropertyInteger(Dict, 0); //default 0 will be calculated later
TmpData = GetDataSetting (Prop2, "StartPattern", &FindLen);
if (TmpData != NULL) {
Patches->KextPatches[Patches->NrKexts].StartPatternLen = FindLen;
Patches->KextPatches[Patches->NrKexts].StartPattern = (__typeof__(Patches->KextPatches[Patches->NrKexts].StartPattern))AllocateCopyPool (FindLen, TmpData);
FreePool(TmpData);
}
TmpData = GetDataSetting (Prop2, "MaskStart", &ReplaceLen);
ReplaceLen = MIN(ReplaceLen, FindLen);
if (FindLen != 0) {
Patches->KextPatches[Patches->NrKexts].StartMask = (__typeof__(Patches->KextPatches[Patches->NrKexts].StartMask))AllocateZeroPool (FindLen);
SetMem(Patches->KextPatches[Patches->NrKexts].StartMask, FindLen, 0xFF);
if (TmpData != NULL) {
CopyMem(Patches->KextPatches[Patches->NrKexts].StartMask, TmpData, ReplaceLen);
}
}
if (TmpData != NULL) {
FreePool(TmpData);
}
TmpData = GetDataSetting (Prop2, "Find", &FindLen);
TmpPatch = GetDataSetting (Prop2, "Replace", &ReplaceLen);
@ -1144,6 +1193,7 @@ FillinKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Patches,
Patches->KextPatches[Patches->NrKexts].Data = (__typeof__(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;
@ -1279,6 +1329,30 @@ FillinKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Patches,
Dict = GetProperty(Prop2, "Disabled");
Patches->KernelPatches[Patches->NrKernels].MenuItem.BValue = !IsPropertyTrue (Dict);
Dict = GetProperty(Prop2, "RangeFind");
Patches->KernelPatches[Patches->NrKernels].SearchLen = GetPropertyInteger(Dict, 0); //default 0 will be calculated later
TmpData = GetDataSetting (Prop2, "StartPattern", &FindLen);
if (TmpData != NULL) {
Patches->KernelPatches[Patches->NrKernels].StartPatternLen = FindLen;
Patches->KernelPatches[Patches->NrKernels].StartPattern = (__typeof__(Patches->KernelPatches[Patches->NrKernels].StartPattern))AllocateCopyPool (FindLen, TmpData);
FreePool(TmpData);
}
TmpData = GetDataSetting (Prop2, "MaskStart", &ReplaceLen);
ReplaceLen = MIN(ReplaceLen, FindLen);
if (FindLen != 0) {
Patches->KernelPatches[Patches->NrKernels].StartMask = (__typeof__(Patches->KernelPatches[Patches->NrKernels].StartMask))AllocateZeroPool (FindLen);
SetMem(Patches->KernelPatches[Patches->NrKernels].StartMask, FindLen, 0xFF);
if (TmpData != NULL) {
CopyMem(Patches->KernelPatches[Patches->NrKernels].StartMask, TmpData, ReplaceLen);
}
}
if (TmpData != NULL) {
FreePool(TmpData);
}
TmpData = GetDataSetting (Prop2, "Find", &FindLen);
TmpPatch = GetDataSetting (Prop2, "Replace", &ReplaceLen);
@ -1409,6 +1483,30 @@ FillinKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Patches,
Dict = GetProperty(Prop2, "Disabled");
Patches->BootPatches[Patches->NrBoots].MenuItem.BValue = !IsPropertyTrue (Dict);
Patches->BootPatches[Patches->NrBoots].MenuItem.ItemType = BoolValue;
Dict = GetProperty(Prop2, "RangeFind");
Patches->BootPatches[Patches->NrBoots].SearchLen = GetPropertyInteger(Dict, 0); //default 0 will be calculated later
TmpData = GetDataSetting (Prop2, "StartPattern", &FindLen);
if (TmpData != NULL) {
Patches->BootPatches[Patches->NrBoots].StartPatternLen = FindLen;
Patches->BootPatches[Patches->NrBoots].StartPattern = (__typeof__(Patches->BootPatches[Patches->NrBoots].StartPattern))AllocateCopyPool (FindLen, TmpData);
FreePool(TmpData);
}
TmpData = GetDataSetting (Prop2, "MaskStart", &ReplaceLen);
ReplaceLen = MIN(ReplaceLen, FindLen);
if (FindLen != 0) {
Patches->BootPatches[Patches->NrBoots].StartMask = (__typeof__(Patches->BootPatches[Patches->NrBoots].StartMask))AllocateZeroPool (FindLen);
SetMem(Patches->BootPatches[Patches->NrBoots].StartMask, FindLen, 0xFF);
if (TmpData != NULL) {
CopyMem(Patches->BootPatches[Patches->NrBoots].StartMask, TmpData, ReplaceLen);
}
}
if (TmpData != NULL) {
FreePool(TmpData);
}
TmpData = GetDataSetting (Prop2, "Find", &FindLen);
TmpPatch = GetDataSetting (Prop2, "Replace", &ReplaceLen);

View File

@ -90,7 +90,7 @@ VOID KernelPatcher_64(VOID* kernelData, LOADER_ENTRY *Entry)
UINT32 cpuid_family_addr=0, cpuid_model_addr=0;
UINT64 os_version;
DBG_RT(Entry, "Looking for _cpuid_set_info _panic ...\n");
// DBG_RT(Entry, "Looking for _cpuid_set_info _panic ...\n");
// Determine location of _cpuid_set_info _panic call for reference
// basically looking for info_p->cpuid_model = bitfield32(reg[eax], 7, 4);
@ -104,7 +104,7 @@ VOID KernelPatcher_64(VOID* kernelData, LOADER_ENTRY *Entry)
}
if (!patchLocation) {
DBG_RT(Entry, "_cpuid_set_info Unsupported CPU _panic not found \n");
// DBG_RT(Entry, "_cpuid_set_info Unsupported CPU _panic not found \n");
return;
}
@ -113,7 +113,7 @@ VOID KernelPatcher_64(VOID* kernelData, LOADER_ENTRY *Entry)
// make sure only kernels for OSX 10.6.0 to 10.7.3 are being patched by this approach
if (os_version >= AsciiOSVersionToUint64("10.6") && os_version <= AsciiOSVersionToUint64("10.7.3")) {
DBG_RT(Entry, "will patch kernel for macOS 10.6.0 to 10.7.3\n");
// DBG_RT(Entry, "will patch kernel for macOS 10.6.0 to 10.7.3\n");
// remove tsc_init: unknown CPU family panic for kernels prior to 10.6.2 which still had Atom support
if (os_version < AsciiOSVersionToUint64("10.6.2")) {
@ -122,7 +122,7 @@ VOID KernelPatcher_64(VOID* kernelData, LOADER_ENTRY *Entry)
if (bytes[i] == 0x48 && bytes[i+1] == 0x8D && bytes[i+2] == 0x3D && bytes[i+3] == 0xF4 &&
bytes[i+4] == 0x63 && bytes[i+5] == 0x2A && bytes[i+6] == 0x00) {
patchLocation1 = i+9;
DBG_RT(Entry, "Found _tsc_init _panic address at 0x%08x\n",patchLocation1);
// DBG_RT(Entry, "Found _tsc_init _panic address at 0x%08x\n",patchLocation1);
break;
}
}
@ -143,7 +143,7 @@ VOID KernelPatcher_64(VOID* kernelData, LOADER_ENTRY *Entry)
C7051C2C5F0000000000 mov dword [ds:0xffffff80008a22c0], 0x0 (example from 10.7)
*/
switchaddr = patchLocation - 19;
DBG_RT(Entry, "switch statement patch location is 0x%08x\n", (switchaddr+6));
// DBG_RT(Entry, "switch statement patch location is 0x%08x\n", (switchaddr+6));
if (bytes[switchaddr + 0] == 0xC7 && bytes[switchaddr + 1] == 0x05 &&
bytes[switchaddr + 5] == 0x00 && bytes[switchaddr + 6] == 0x00 &&
@ -173,16 +173,16 @@ VOID KernelPatcher_64(VOID* kernelData, LOADER_ENTRY *Entry)
cpuid_model_addr = cpuid_family_addr - 0X153;
}
DBG_RT(Entry, "cpuid_family address: 0x%08x\n", cpuid_family_addr);
DBG_RT(Entry, "cpuid_model address: 0x%08x\n", cpuid_model_addr);
// DBG_RT(Entry, "cpuid_family address: 0x%08x\n", cpuid_family_addr);
// DBG_RT(Entry, "cpuid_model address: 0x%08x\n", cpuid_model_addr);
switchaddr += 6; // offset 6 bytes in mov operation to write a dword instead of zero
// calculate mask for patching, cpuid_family mask not needed as we offset on a valid mask
mask_model = cpuid_model_addr - (switchaddr+14);
DBG_RT(Entry, "model mask 0x%08x\n", mask_model);
// DBG_RT(Entry, "model mask 0x%08x\n", mask_model);
DBG_RT(Entry, "overriding cpuid_family and cpuid_model as CPUID_INTEL_PENRYN\n");
// DBG_RT(Entry, "overriding cpuid_family and cpuid_model as CPUID_INTEL_PENRYN\n");
bytes[switchaddr+0] = (CPUFAMILY_INTEL_PENRYN & 0x000000FF) >> 0;
bytes[switchaddr+1] = (CPUFAMILY_INTEL_PENRYN & 0x0000FF00) >> 8;
bytes[switchaddr+2] = (CPUFAMILY_INTEL_PENRYN & 0x00FF0000) >> 16;
@ -207,7 +207,7 @@ VOID KernelPatcher_64(VOID* kernelData, LOADER_ENTRY *Entry)
}
}
else {
DBG_RT(Entry, "Unable to determine cpuid_family address, patching aborted\n");
// DBG_RT(Entry, "Unable to determine cpuid_family address, patching aborted\n");
return;
}
}
@ -787,7 +787,7 @@ BOOLEAN KernelLapicPatch_64(VOID *kernelData, LOADER_ENTRY *Entry)
} else {
DBG_RT(Entry, "Patched Lapic panic master (10.10 - recent macOS)\n");
// E8 XX XX FF FF 83 XX XX XX XX 00 00
// E8 XX XX FF FF 31 C0 90 90 90 90 90
// E8 XX XX FF FF 31 C0 90 90 90 90 90 xor eax,eax; nop; nop;....
bytes[patchLocation2 + 5] = 0x31;
bytes[patchLocation2 + 6] = 0xC0;
for (i = 7; i < 12; i++) {
@ -1420,7 +1420,7 @@ VOID Patcher_SSE3_6(VOID* kernelData)
UINT32 i;
//UINT32 Length = sizeof(kernelData);
DBG("Start find SSE3 address\n");
// DBG("Start find SSE3 address\n");
i=0;
//for (i=0;i<Length;i++)
while(TRUE) {
@ -1429,7 +1429,7 @@ VOID Patcher_SSE3_6(VOID* kernelData)
bytes[i-1664-32] == 0x55
) {
patchLocation1 = i-1664-32;
DBG("Found SSE3 data address at 0x%08X\n",patchLocation1);
// DBG("Found SSE3 data address at 0x%08X\n",patchLocation1);
}
// hasSSE2+..... title
@ -1438,31 +1438,31 @@ VOID Patcher_SSE3_6(VOID* kernelData)
bytes[i+6] == 0xFF && bytes[i+7] == 0xFF && bytes[i+8] == 0x24 &&
bytes[i+9] == 0x01) {
patchLocation2 = i;
DBG("Found SSE3 Title address at 0x%08X\n",patchLocation2);
// DBG("Found SSE3 Title address at 0x%08X\n",patchLocation2);
break;
}
i++;
}
if (!patchLocation1 || !patchLocation2) {
DBG("Can't found SSE3 data addres or Title address at 0x%08X 0x%08X\n", patchLocation1, patchLocation2);
// DBG("Can't found SSE3 data addres or Title address at 0x%08X 0x%08X\n", patchLocation1, patchLocation2);
return;
}
DBG("Found SSE3 last data addres Start\n");
// DBG("Found SSE3 last data addres Start\n");
i = patchLocation1 + 1500;
//for (i=(patchLocation1+1500); i<(patchLocation1+3000); i++)
while(TRUE) {
if (bytes[i] == 0x90 && bytes[i+1] == 0x90 && bytes[i+2] == 0x55 ) {
patchlast = (i+1) - patchLocation1;
DBG("Found SSE3 last data addres at 0x%08X\n", patchlast);
// DBG("Found SSE3 last data addres at 0x%08X\n", patchlast);
break;
}
i++;
}
if (!patchlast) {
DBG("Can't found SSE3 data last addres at 0x%08X\n", patchlast);
// DBG("Can't found SSE3 data last addres at 0x%08X\n", patchlast);
return;
}
// patch sse3_64 data
@ -1492,14 +1492,14 @@ VOID Patcher_SSE3_5(VOID* kernelData)
UINT32 Length = sizeof(kernelData);
UINT32 i;
DBG("Start find SSE3 address\n");
// DBG("Start find SSE3 address\n");
for (i=256; i<(Length-256); i++) {
if (bytes[i] == 0x66 && bytes[i+1] == 0x0F && bytes[i+2] == 0x6F &&
bytes[i+3] == 0x44 && bytes[i+4] == 0x0E && bytes[i+5] == 0xF1 &&
bytes[i-1680-32] == 0x55) {
patchLocation1 = i-1680-32;
DBG("Found SSE3 data address at 0x%08X\n",patchLocation1);
// DBG("Found SSE3 data address at 0x%08X\n",patchLocation1);
}
// khasSSE2+..... title
@ -1508,28 +1508,28 @@ VOID Patcher_SSE3_5(VOID* kernelData)
bytes[i+6] == 0xFF && bytes[i+7] == 0xFF && bytes[i+8] == 0x24 &&
bytes[i+9] == 0x01) {
patchLocation2 = i;
DBG("Found SSE3 Title address at 0x%08X\n",patchLocation2);
// DBG("Found SSE3 Title address at 0x%08X\n",patchLocation2);
break;
}
}
if (!patchLocation1 || !patchLocation2) {
DBG("Can't found SSE3 data addres or Title address at 0x%08X 0x%08X\n", patchLocation1, patchLocation2);
// DBG("Can't found SSE3 data addres or Title address at 0x%08X 0x%08X\n", patchLocation1, patchLocation2);
return;
}
DBG("Found SSE3 last data addres Start\n");
// DBG("Found SSE3 last data addres Start\n");
for (i=(patchLocation1+1500);i<Length;i++) {
if (bytes[i] == 0x90 && bytes[i+1] == 0x90 && bytes[i+2] == 0x55) {
patchlast = (i+1) - patchLocation1;
DBG("Found SSE3 last data addres at 0x%08X\n", patchlast);
// DBG("Found SSE3 last data addres at 0x%08X\n", patchlast);
break;
}
}
if (!patchlast) {
DBG("Can't found SSE3 data last addres at 0x%08X\n", patchlast);
// DBG("Can't found SSE3 data last addres at 0x%08X\n", patchlast);
return;
}
@ -1784,6 +1784,9 @@ KernelUserPatch(IN UINT8 *UKernelData, LOADER_ENTRY *Entry)
{
INTN Num, i = 0, y = 0;
// old confuse
// We are using Entry->KernelAndKextPatches as set by Custom Entries.
// while config patches go to gSettings.KernelAndKextPatches
// how to resolve it?
for (; i < Entry->KernelAndKextPatches->NrKernels; ++i) {
DBG_RT(Entry, "Patch[%lld]: %s\n", i, Entry->KernelAndKextPatches->KernelPatches[i].Label);
@ -1792,23 +1795,41 @@ KernelUserPatch(IN UINT8 *UKernelData, LOADER_ENTRY *Entry)
DBG_RT(Entry, "==> disabled\n");
continue;
}
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++;
if (!Entry->KernelAndKextPatches->KernelPatches[i].SearchLen) {
Entry->KernelAndKextPatches->KernelPatches[i].SearchLen = KERNEL_MAX_SIZE;
}
UINT8 * curs = UKernelData;
UINTN j = 0;
while (j < KERNEL_MAX_SIZE) {
if (!Entry->KernelAndKextPatches->KernelPatches[i].StartPattern || //old behavior
CompareMemMask(curs,
Entry->KernelAndKextPatches->KernelPatches[i].StartPattern,
Entry->KernelAndKextPatches->KernelPatches[i].StartMask,
Entry->KernelAndKextPatches->KernelPatches[i].StartPatternLen)) {
DBG_RT(Entry, " StartPattern found\n");
Num = SearchAndReplaceMask(curs,
Entry->KernelAndKextPatches->KernelPatches[i].SearchLen,
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++;
curs += Entry->KernelAndKextPatches->KernelPatches[i].SearchLen - 1;
j += Entry->KernelAndKextPatches->KernelPatches[i].SearchLen - 1;
}
DBG_RT(Entry, "==> %s : %lld replaces done\n", Num ? "Success" : "Error", Num);
if (!Entry->KernelAndKextPatches->KernelPatches[i].StartPattern ||
!Entry->KernelAndKextPatches->KernelPatches[i].StartPatternLen) {
break;
}
}
j++; curs++;
}
DBG_RT(Entry, "==> %s : %lld replaces done\n", Num ? "Success" : "Error", Num);
}
if (Entry->KernelAndKextPatches->KPDebug) {
gBS->Stall(2000000);
@ -1821,29 +1842,48 @@ BOOLEAN
BooterPatch(IN UINT8 *BooterData, IN UINT64 BooterSize, LOADER_ENTRY *Entry)
{
INTN Num, i = 0, y = 0;
if (!Entry->KernelAndKextPatches->BootPatches[i].SearchLen) {
Entry->KernelAndKextPatches->BootPatches[i].SearchLen = BooterSize;
}
for (; i < Entry->KernelAndKextPatches->NrBoots; ++i) {
DBG_RT(Entry, "Patch[%lld]: %s\n", i, Entry->KernelAndKextPatches->BootPatches[i].Label);
if (!Entry->KernelAndKextPatches->BootPatches[i].MenuItem.BValue) {
DBG_RT(Entry, "==> disabled\n");
continue;
}
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++;
UINT8 * curs = BooterData;
UINTN j = 0;
while (j < BooterSize) {
if (!Entry->KernelAndKextPatches->BootPatches[i].StartPattern || //old behavior
CompareMemMask(curs,
Entry->KernelAndKextPatches->BootPatches[i].StartPattern,
Entry->KernelAndKextPatches->BootPatches[i].StartMask,
Entry->KernelAndKextPatches->BootPatches[i].StartPatternLen)) {
DBG_RT(Entry, " StartPattern found\n");
Num = SearchAndReplaceMask(BooterData,
Entry->KernelAndKextPatches->BootPatches[i].SearchLen,
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++;
curs += Entry->KernelAndKextPatches->KernelPatches[i].SearchLen - 1;
j += Entry->KernelAndKextPatches->KernelPatches[i].SearchLen - 1;
}
DBG_RT(Entry, "==> %s : %lld replaces done\n", Num ? "Success" : "Error", Num);
if (!Entry->KernelAndKextPatches->BootPatches[i].StartPattern ||
!Entry->KernelAndKextPatches->BootPatches[i].StartPatternLen) {
break;
}
}
j++; curs++;
}
DBG_RT(Entry, "==> %s : %lld replaces done\n", Num ? "Success" : "Error", Num);
}
if (Entry->KernelAndKextPatches->KPDebug) {
gBS->Stall(2000000);
@ -2114,16 +2154,16 @@ KernelAndKextsPatcherStart(IN LOADER_ENTRY *Entry)
//
// Kext add
//
if (Entry->KernelAndKextPatches->KPDebug) {
if (OSFLAG_ISSET(Entry->Flags, OSFLAG_CHECKFAKESMC) &&
OSFLAG_ISUNSET(Entry->Flags, OSFLAG_WITHKEXTS)) {
// disabled kext injection if FakeSMC is already present
// Entry->Flags = OSFLAG_UNSET(Entry->Flags, OSFLAG_WITHKEXTS); //Slice - we are already here
DBG_RT(Entry, "\nInjectKexts: disabled because FakeSMC is already present and InjectKexts option set to Detect\n");
gBS->Stall(500000);
}
}
// if (Entry->KernelAndKextPatches->KPDebug) {
// if (OSFLAG_ISSET(Entry->Flags, OSFLAG_CHECKFAKESMC) &&
// OSFLAG_ISUNSET(Entry->Flags, OSFLAG_WITHKEXTS)) {
// disabled kext injection if FakeSMC is already present
// Entry->Flags = OSFLAG_UNSET(Entry->Flags, OSFLAG_WITHKEXTS); //Slice - we are already here
//
// DBG_RT(Entry, "\nInjectKexts: disabled because FakeSMC is already present and InjectKexts option set to Detect\n");
// gBS->Stall(500000);
// }
// }
if (OSFLAG_ISSET(Entry->Flags, OSFLAG_WITHKEXTS)) {
UINT32 deviceTreeP;

View File

@ -146,6 +146,8 @@ VOID KextPatcherStart(LOADER_ENTRY *Entry);
//
UINTN SearchAndCount(UINT8 *Source, UINT64 SourceSize, UINT8 *Search, UINTN SearchSize);
BOOLEAN CompareMemMask(UINT8 *Source, UINT8 *Search, UINT8 *Mask, UINTN SearchSize);
//
// Searches Source for Search pattern of size SearchSize
// and replaces it with Replace up to MaxReplaces times.

View File

@ -972,6 +972,11 @@ VOID AnyKextPatch(UINT8 *Driver, UINT32 DriverSize, CHAR8 *InfoPlist, UINT32 Inf
DBG_RT(Entry, "==> DISABLED!\n");
return;
}
if (!Entry->KernelAndKextPatches->KextPatches[N].SearchLen ||
(Entry->KernelAndKextPatches->KextPatches[N].SearchLen > DriverSize)) {
Entry->KernelAndKextPatches->KextPatches[N].SearchLen = DriverSize;
}
if (Entry->KernelAndKextPatches->KPDebug) {
ExtractKextBundleIdentifier(InfoPlist);
@ -982,14 +987,31 @@ 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 = 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);
UINT8 * curs = Driver;
UINTN j = 0;
while (j < DriverSize) {
if (!Entry->KernelAndKextPatches->KextPatches[N].StartPattern || //old behavior
CompareMemMask(curs,
Entry->KernelAndKextPatches->KextPatches[N].StartPattern,
Entry->KernelAndKextPatches->KextPatches[N].StartMask,
Entry->KernelAndKextPatches->KextPatches[N].StartPatternLen)) {
DBG_RT(Entry, " StartPattern found\n");
Num = SearchAndReplaceMask(Driver,
Entry->KernelAndKextPatches->KextPatches[N].SearchLen,
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);
if (Num) {
curs += Entry->KernelAndKextPatches->KextPatches[N].SearchLen - 1;
j += Entry->KernelAndKextPatches->KextPatches[N].SearchLen - 1;
}
}
j++; curs++;
}
} else {
// Info plist patch
DBG_RT(Entry, "Info.plist data : '");

View File

@ -277,6 +277,10 @@ struct KEXT_PATCH
UINT8 *Patch;
UINT8 *MaskFind;
UINT8 *MaskReplace;
UINT8 *StartPattern;
UINT8 *StartMask;
INTN StartPatternLen;
INTN SearchLen;
CHAR8 *MatchOS;
CHAR8 *MatchBuild;
INPUT_ITEM MenuItem;
@ -289,6 +293,10 @@ typedef struct {
UINT8 *Patch;
UINT8 *MaskFind;
UINT8 *MaskReplace;
UINT8 *StartPattern;
UINT8 *StartMask;
INTN StartPatternLen;
INTN SearchLen;
INTN Count;
CHAR8 *MatchOS;
CHAR8 *MatchBuild;