# hyperspace run code in a address space not associated with a process. The thread schedular loads CR3 with `KTHREAD->ApcState->Process->DirectoryTableBase`. You can make a clone of a KPROCESS structure and change DirectoryTableBase to your new address space. DirectoryTableBase contains a CR3 value just FYI... its not just a physical address... # KTHREAD, KAPC_STATE, KPROCESS ```cpp struct _KPROCESS { struct _DISPATCHER_HEADER Header; //0x0 struct _LIST_ENTRY ProfileListHead; //0x18 ULONGLONG DirectoryTableBase; //0x28 <---- put new CR3 value here... struct _LIST_ENTRY ThreadListHead; //0x30 ULONG ProcessLock; //0x40 // ... etc ... }; struct _KAPC_STATE { struct _LIST_ENTRY ApcListHead[2]; //0x0 struct _KPROCESS* Process; //0x20 <----- swap this with new fake KPROCESS... union { UCHAR InProgressFlags; //0x28 struct { UCHAR KernelApcInProgress:1; //0x28 UCHAR SpecialApcInProgress:1; //0x28 }; }; }; struct _KTHREAD { struct _DISPATCHER_HEADER Header; //0x0 VOID* SListFaultAddress; //0x18 ULONGLONG QuantumTarget; //0x20 // ... etc ... struct _KTRAP_FRAME* TrapFrame; //0x90 union { struct _KAPC_STATE ApcState; //0x98 struct { UCHAR ApcStateFill[43]; //0x98 CHAR Priority; //0xc3 ULONG UserIdealProcessor; //0xc4 }; }; }; ```