change a way to find symbols in kexts

Signed-off-by: SergeySlice <sergey.slice@gmail.com>
This commit is contained in:
SergeySlice 2020-05-03 20:16:50 +03:00
parent d7d3c960a9
commit 70fea56ee4
4 changed files with 94 additions and 19 deletions

View File

@ -110,6 +110,64 @@ EFI_STATUS LOADER_ENTRY::getVTable(UINT8 * kernel)
return EFI_SUCCESS; return EFI_SUCCESS;
} }
UINTN LOADER_ENTRY::searchProcInDriver(UINT8 * driver, UINT32 driverLen, const char *procedure)
{
if (!procedure) {
return 0;
}
INT32 LinkAdr = FindBin(driver, driverLen, (const UINT8 *)kLinkEditSegment, (UINT32)strlen(kLinkEditSegment));
if (LinkAdr == -1) {
return 0;
}
SEGMENT *LinkSeg = (SEGMENT*)&driver[LinkAdr];
// INT32 lAddrVtable = LinkSeg->AddrVtable;
INT32 lSizeVtable = LinkSeg->SizeVtable;
// INT32 lNamesTable = LinkSeg->AddrNames;
const char* Names = (const char*)(&driver[LinkSeg->AddrNames]);
VTABLE * vArray = (VTABLE*)(&driver[LinkSeg->AddrVtable]);
INT32 i;
bool found = false;
for (i = 0; i < lSizeVtable; ++i) {
size_t Offset = vArray[i].NameOffset;
if (strstr(&Names[Offset], procedure)) {
found = true;
break;
}
}
if (!found) {
DBG_RT("%s not found\n", procedure);
return 0;
}
size_t SegVAddr;
switch (vArray[i].Seg) {
case ID_SEG_DATA:
SegVAddr = FindBin(driver, 0x1600, (const UINT8 *)kDataSegment, (UINT32)strlen(kDataSegment));
break;
case ID_SEG_DATA_CONST:
SegVAddr = FindBin(driver, 0x1600, (const UINT8 *)kDataConstSegment, (UINT32)strlen(kDataConstSegment));
break;
case ID_SEG_KLD:
case ID_SEG_KLD2:
SegVAddr = FindBin(driver, 0x2000, (const UINT8 *)kKldSegment, (UINT32)strlen(kKldSegment));
break;
case ID_SEG_TEXT:
default:
SegVAddr = FindBin(driver, 0x600, (const UINT8 *)kTextSegment, (UINT32)strlen(kTextSegment));
break;
}
if (SegVAddr == 0) {
SegVAddr = 0x38;
}
SEGMENT *TextSeg = (SEGMENT*)&driver[SegVAddr];
UINT64 Absolut = TextSeg->SegAddress;
UINT64 FileOff = TextSeg->fileoff;
UINTN procAddr = vArray[i].ProcAddr - Absolut + FileOff;
return procAddr;
}
//search a procedure by Name and return its offset in the kernel //search a procedure by Name and return its offset in the kernel
UINTN LOADER_ENTRY::searchProc(UINT8 * kernel, const char *procedure, UINTN *procLen) UINTN LOADER_ENTRY::searchProc(UINT8 * kernel, const char *procedure, UINTN *procLen)
{ {
@ -1974,7 +2032,7 @@ LOADER_ENTRY::BooterPatch(IN UINT8 *BooterData, IN UINT64 BooterSize)
KernelAndKextPatches->BootPatches[i].StartPatternLen)) { KernelAndKextPatches->BootPatches[i].StartPatternLen)) {
DBG_RT( " StartPattern found\n"); DBG_RT( " StartPattern found\n");
Num = SearchAndReplaceMask(BooterData, Num = SearchAndReplaceMask(curs,
KernelAndKextPatches->BootPatches[i].SearchLen, KernelAndKextPatches->BootPatches[i].SearchLen,
(const UINT8*)KernelAndKextPatches->BootPatches[i].Data, (const UINT8*)KernelAndKextPatches->BootPatches[i].Data,
(const UINT8*)KernelAndKextPatches->BootPatches[i].MaskFind, (const UINT8*)KernelAndKextPatches->BootPatches[i].MaskFind,

View File

@ -40,6 +40,7 @@ const char kDataSegment[] = "__DATA";
const char kDataConstSegment[] = "__DATA_CONST"; const char kDataConstSegment[] = "__DATA_CONST";
const char kKldSegment[] = "__KLD"; const char kKldSegment[] = "__KLD";
#define ID_SEG_STEXT 0x010e
#define ID_SEG_TEXT 0x010f #define ID_SEG_TEXT 0x010f
#define ID_SEG_DATA 0x0f0f #define ID_SEG_DATA 0x0f0f
#define ID_SEG_DATA_CONST 0x110f #define ID_SEG_DATA_CONST 0x110f

View File

@ -121,9 +121,9 @@ VOID CopyMemMask(UINT8 *Dest, const UINT8 *Replace, const UINT8 *Mask, UINTN Sea
// 0 if not found // 0 if not found
UINTN FindRelative32(const UINT8 *Source, UINTN Start, UINTN SourceSize, UINTN taskLocation) UINTN FindRelative32(const UINT8 *Source, UINTN Start, UINTN SourceSize, UINTN taskLocation)
{ {
UINTN Offset; INT32 Offset; //can be negative, so 0xFFFFFFFF == -1
for (UINTN i = Start; i < Start + SourceSize - 4; ++i) { for (UINTN i = Start; i < Start + SourceSize - 4; ++i) {
Offset = Source[i] + (Source[i+1]<<8) + (Source[i+2]<<16) + (Source[i+3]<<24); //should not use *(UINT32*) because of alignment Offset = (INT32)((UINT32)Source[i] + ((UINT32)Source[i+1]<<8) + ((UINT32)Source[i+2]<<16) + ((UINT32)Source[i+3]<<24)); //should not use *(UINT32*) because of alignment
if (taskLocation == i + Offset + 4) { if (taskLocation == i + Offset + 4) {
return (i+4); return (i+4);
} }
@ -575,15 +575,33 @@ VOID LOADER_ENTRY::AppleRTCPatch(UINT8 *Driver, UINT32 DriverSize, CHAR8 *InfoPl
} }
#else #else
//RodionS //RodionS
UINTN procLen = DriverSize;
UINTN procLocation = searchProc(Driver, "updateChecksum", &procLen); UINTN procLocation = searchProcInDriver(Driver, DriverSize, "updateChecksum");
DBG_RT("AppleRTC:");
if (procLocation != 0) { if (procLocation != 0) {
Driver[procLocation] = 0xC3; Driver[procLocation] = 0xC3;
DBG_RT(" patched\n"); DBG_RT("AppleRTC: patched\n");
} else { } else {
DBG_RT(" failed\n"); DBG_RT("AppleRTC: not patched\n");
} }
/*
UINTN writeCmos = searchProc(Driver, "rtcWrite", &procLen);
UINTN patchLocation2 = FindRelative32(Driver, procLocation, 0x100, writeCmos);
DBG_RT("AppleRTC:");
if (patchLocation2 != 0) {
Driver[patchLocation2 - 5] = 0xEB;
Driver[patchLocation2 - 4] = 0x03;
DBG_RT(" patched 1\n");
UINTN patchLocation3 = FindRelative32(Driver, patchLocation2, 0x20, writeCmos);
if (patchLocation3 != 0) {
Driver[patchLocation3 - 5] = 0xEB;
Driver[patchLocation3 - 4] = 0x03;
DBG_RT(" patched 2\n");
}
} else {
DBG_RT(" not patched\n");
}
*/
#endif #endif
Stall(5000000); Stall(5000000);
@ -999,14 +1017,13 @@ VOID LOADER_ENTRY::AnyKextPatch(UINT8 *Driver, UINT32 DriverSize, CHAR8 *InfoPli
{ {
UINTN Num = 0; UINTN Num = 0;
INTN Ind; INTN Ind;
DBG_RT("\nAnyKextPatch %d: driverAddr = %s, driverSize = %x\nAnyKext = %s\n",
N, Driver, DriverSize, KernelAndKextPatches->KextPatches[N].Label);
if (!KernelAndKextPatches->KextPatches[N].MenuItem.BValue) { if (!KernelAndKextPatches->KextPatches[N].MenuItem.BValue) {
DBG_RT("==> DISABLED!\n");
return; return;
} }
DBG_RT("\nAnyKextPatch %d: driverAddr = %llx, driverSize = %x\nAnyKext = %s\n",
N, (UINTN)Driver, DriverSize, KernelAndKextPatches->KextPatches[N].Label);
if (!KernelAndKextPatches->KextPatches[N].SearchLen || if (!KernelAndKextPatches->KextPatches[N].SearchLen ||
(KernelAndKextPatches->KextPatches[N].SearchLen > DriverSize)) { (KernelAndKextPatches->KextPatches[N].SearchLen > DriverSize)) {
@ -1024,18 +1041,16 @@ VOID LOADER_ENTRY::AnyKextPatch(UINT8 *Driver, UINT32 DriverSize, CHAR8 *InfoPli
DBG_RT("Binary patch\n"); DBG_RT("Binary patch\n");
bool once = false; bool once = false;
UINTN procLen = 0; UINTN procLen = 0;
UINTN procAddr = searchProc(Driver, KernelAndKextPatches->KextPatches[N].ProcedureName, &procLen); UINTN procAddr = searchProcInDriver(Driver, DriverSize, KernelAndKextPatches->KextPatches[N].ProcedureName);
if (KernelAndKextPatches->KextPatches[N].SearchLen == 0) { if (KernelAndKextPatches->KextPatches[N].SearchLen == 0) {
KernelAndKextPatches->KextPatches[N].SearchLen = DriverSize; KernelAndKextPatches->KextPatches[N].SearchLen = DriverSize;
if (procLen > DriverSize) { procLen = DriverSize - procAddr;
procLen = DriverSize - procAddr; once = true;
once = true;
}
} else { } else {
procLen = KernelAndKextPatches->KextPatches[N].SearchLen; procLen = KernelAndKextPatches->KextPatches[N].SearchLen;
} }
const UINT8 * curs = &Driver[procAddr]; UINT8 * curs = &Driver[procAddr];
UINTN j = 0; UINTN j = 0;
while (j < DriverSize) { while (j < DriverSize) {
if (!KernelAndKextPatches->KextPatches[N].StartPattern || //old behavior if (!KernelAndKextPatches->KextPatches[N].StartPattern || //old behavior
@ -1046,7 +1061,7 @@ VOID LOADER_ENTRY::AnyKextPatch(UINT8 *Driver, UINT32 DriverSize, CHAR8 *InfoPli
KernelAndKextPatches->KextPatches[N].StartPatternLen)) { KernelAndKextPatches->KextPatches[N].StartPatternLen)) {
DBG_RT(" StartPattern found\n"); DBG_RT(" StartPattern found\n");
Num = SearchAndReplaceMask(Driver, Num = SearchAndReplaceMask(curs,
procLen, procLen,
(const UINT8*)KernelAndKextPatches->KextPatches[N].Data, (const UINT8*)KernelAndKextPatches->KextPatches[N].Data,
(const UINT8*)KernelAndKextPatches->KextPatches[N].MaskFind, (const UINT8*)KernelAndKextPatches->KextPatches[N].MaskFind,

View File

@ -373,6 +373,7 @@ class REFIT_ABSTRACT_MENU_ENTRY
VOID FindBootArgs(); VOID FindBootArgs();
EFI_STATUS getVTable(UINT8* kernel); EFI_STATUS getVTable(UINT8* kernel);
UINTN searchProc(UINT8 * kernel, const char *procedure, UINTN *procLen); UINTN searchProc(UINT8 * kernel, const char *procedure, UINTN *procLen);
UINTN searchProcInDriver(UINT8 * driver, UINT32 driverLen, const char *procedure);
VOID KernelAndKextsPatcherStart(); VOID KernelAndKextsPatcherStart();
VOID KernelAndKextPatcherInit(); VOID KernelAndKextPatcherInit();
BOOLEAN KernelUserPatch(UINT8 * kernel); BOOLEAN KernelUserPatch(UINT8 * kernel);