implement user mode catchable exceptions, refactor system status codes to use NTLSTATUS_ prefix, update build scripts to use shared literal macros for linker arguments, update named queue lifetime cleanup to include KeNamedQueueUnpublishHandle.
This commit is contained in:
1 parent
1f5477cf66
commit
b7fcfce6f7
140 files changed
+7649
-3943
No files matched your search
+20
-20
@@ -38,12 +38,12 @@ static bool KiUserRflagsValid(uint64_t rflags) {
|
||||
static KSTATUS KiValidateUserApcResumeState(uint64_t rip, uint64_t rsp, uint64_t rflags,
|
||||
uint64_t cs, uint64_t ss) {
|
||||
if (!KiUserAddressValid(rip) || !KiUserAddressValid(rsp))
|
||||
return STATUS_ACCESS_DENIED;
|
||||
return NTLSTATUS_ACCESS_DENIED;
|
||||
if (cs != KI_USER_CS || ss != KI_USER_SS)
|
||||
return STATUS_ACCESS_DENIED;
|
||||
return NTLSTATUS_ACCESS_DENIED;
|
||||
if (!KiUserRflagsValid(rflags))
|
||||
return STATUS_ACCESS_DENIED;
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_ACCESS_DENIED;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Allocates a nonzero token for one active user APC return frame.
|
||||
@@ -128,7 +128,7 @@ __declspec(dllexport) bool KeInsertQueueApc(KAPC* apc,
|
||||
|
||||
// If the target opted into an alertable wait, make the APC itself the
|
||||
// wait completion. The target thread will deliver the APC before
|
||||
// KeWaitForEvent(..., true) returns STATUS_KERNEL_APC.
|
||||
// KeWaitForEvent(..., true) returns NTLSTATUS_KERNEL_APC.
|
||||
if (wakeAlertable)
|
||||
KiWakeThreadForKernelApc(thread);
|
||||
|
||||
@@ -238,15 +238,15 @@ void KiDeliverKernelApcs(void) {
|
||||
// Updates user Apc Dispatcher.
|
||||
__declspec(dllexport) KSTATUS KeSetUserApcDispatcher(void* dispatcher) {
|
||||
THREAD* thread = KeGetCurrentThread();
|
||||
if (!thread) return STATUS_FAILURE;
|
||||
if (!dispatcher) return STATUS_INVALID_PARAMETER;
|
||||
if (!KiUserAddressValid((uint64_t)(uintptr_t)dispatcher)) return STATUS_ACCESS_DENIED;
|
||||
if (!thread) return NTLSTATUS_FAILURE;
|
||||
if (!dispatcher) return NTLSTATUS_INVALID_PARAMETER;
|
||||
if (!KiUserAddressValid((uint64_t)(uintptr_t)dispatcher)) return NTLSTATUS_ACCESS_DENIED;
|
||||
|
||||
KSTATUS s = MmProbeUserRead(dispatcher, 1);
|
||||
if (!KSUCCESS(s)) return s;
|
||||
|
||||
thread->UserApcDispatcher = (uintptr_t)dispatcher;
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
__declspec(dllexport) KSTATUS KeQueueUserApc(THREAD* thread,
|
||||
@@ -255,15 +255,15 @@ __declspec(dllexport) KSTATUS KeQueueUserApc(THREAD* thread,
|
||||
void* systemArgument1,
|
||||
void* systemArgument2) {
|
||||
if (!thread || !routine)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
if (!KiUserAddressValid((uint64_t)(uintptr_t)routine))
|
||||
return STATUS_ACCESS_DENIED;
|
||||
return NTLSTATUS_ACCESS_DENIED;
|
||||
if (thread->State == ThreadDead)
|
||||
return STATUS_OBJECT_DEAD;
|
||||
return NTLSTATUS_OBJECT_DEAD;
|
||||
|
||||
KUSER_APC* apc = (KUSER_APC*)MmAllocatePoolTag(sizeof(KUSER_APC), MM_POOL_TAG('a', 'p', 'c', ' '));
|
||||
if (!apc)
|
||||
return STATUS_NO_MEMORY;
|
||||
return NTLSTATUS_NO_MEMORY;
|
||||
|
||||
memset(apc, 0, sizeof(*apc));
|
||||
LIST_INIT(&apc->Link);
|
||||
@@ -283,7 +283,7 @@ __declspec(dllexport) KSTATUS KeQueueUserApc(THREAD* thread,
|
||||
if (wakeAlertable)
|
||||
KiWakeThreadForUserApc(thread);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Implements the pop User Apc operation.
|
||||
@@ -359,11 +359,11 @@ void KiCheckForUserApcDelivery(KTRAP_FRAME* frame) {
|
||||
thread->UserApcSavedRip = frame->Rip;
|
||||
thread->UserApcSavedRsp = frame->Rsp;
|
||||
thread->UserApcSavedRflags = frame->Rflags;
|
||||
thread->UserApcSavedRax = STATUS_USER_APC;
|
||||
thread->UserApcSavedRax = NTLSTATUS_USER_APC;
|
||||
|
||||
frame->Rip = thread->UserApcDispatcher;
|
||||
frame->Rsp = newRsp;
|
||||
frame->Rax = STATUS_USER_APC;
|
||||
frame->Rax = NTLSTATUS_USER_APC;
|
||||
|
||||
thread->UserApcDeliverable = 0;
|
||||
thread->UserApcDeliveryActive = 1;
|
||||
@@ -416,10 +416,10 @@ void KiRundownApcState(THREAD* thread) {
|
||||
__declspec(dllexport) uint64_t KeUserApcReturn(const SYS_USER_APC_FRAME_K* userFrame) {
|
||||
THREAD* thread = KeGetCurrentThread();
|
||||
if (!thread)
|
||||
return STATUS_FAILURE;
|
||||
return NTLSTATUS_FAILURE;
|
||||
|
||||
if (!thread->UserApcDeliveryActive || !userFrame)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
SYS_USER_APC_FRAME_K frameCopy;
|
||||
KSTATUS s = CopyFromUser(&frameCopy, userFrame, sizeof(frameCopy));
|
||||
@@ -434,12 +434,12 @@ __declspec(dllexport) uint64_t KeUserApcReturn(const SYS_USER_APC_FRAME_K* userF
|
||||
(uint64_t)thread->UserApcFrameUserAddress,
|
||||
frameCopy.ReturnToken,
|
||||
thread->UserApcReturnToken);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
KTRAP_FRAME* frame = KeGetCurrentTrapFrame();
|
||||
if (!frame || !KeTrapFrameFromUser(frame) || frame->Kind != KTRAP_KIND_SYSCALL)
|
||||
return STATUS_FAILURE;
|
||||
return NTLSTATUS_FAILURE;
|
||||
|
||||
s = KiValidateUserApcResumeState(thread->UserApcSavedRip,
|
||||
thread->UserApcSavedRsp,
|
||||
|
||||
Reference in new issue
Block a user