mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 23:35:45 +00:00
- support for kernel handles
- attach to owning process before accessing the handle table if necessary svn path=/trunk/; revision=20038
This commit is contained in:
parent
1c08d2c447
commit
656411d9b8
8 changed files with 379 additions and 181 deletions
|
@ -247,7 +247,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status);
|
DPRINT1("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status);
|
||||||
goto Cleanup;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostCreateKeyInfo.CompleteName = &ObjectName;
|
PostCreateKeyInfo.CompleteName = &ObjectName;
|
||||||
|
@ -255,7 +255,6 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
Status = CmiCallRegisteredCallbacks(RegNtPreCreateKey, &PreCreateKeyInfo);
|
Status = CmiCallRegisteredCallbacks(RegNtPreCreateKey, &PreCreateKeyInfo);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
|
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,7 +263,6 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
(PVOID*)&Object,
|
(PVOID*)&Object,
|
||||||
&RemainingPath,
|
&RemainingPath,
|
||||||
CmiKeyType);
|
CmiKeyType);
|
||||||
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
PostCreateKeyInfo.Object = NULL;
|
PostCreateKeyInfo.Object = NULL;
|
||||||
|
@ -291,10 +289,9 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ObpCreateHandle(PsGetCurrentProcess(),
|
Status = ObpCreateHandle(Object,
|
||||||
Object,
|
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
TRUE,
|
ObjectCreateInfo.Attributes,
|
||||||
&hKey);
|
&hKey);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -466,6 +463,7 @@ SuccessReturn:
|
||||||
_SEH_END;
|
_SEH_END;
|
||||||
|
|
||||||
Cleanup:
|
Cleanup:
|
||||||
|
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
|
||||||
if (Class != NULL)
|
if (Class != NULL)
|
||||||
{
|
{
|
||||||
ReleaseCapturedUnicodeString(&CapturedClass,
|
ReleaseCapturedUnicodeString(&CapturedClass,
|
||||||
|
@ -1332,7 +1330,6 @@ NtOpenKey(OUT PHANDLE KeyHandle,
|
||||||
(PVOID*)&Object,
|
(PVOID*)&Object,
|
||||||
&RemainingPath,
|
&RemainingPath,
|
||||||
CmiKeyType);
|
CmiKeyType);
|
||||||
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("CmpFindObject() returned 0x%08lx\n", Status);
|
DPRINT("CmpFindObject() returned 0x%08lx\n", Status);
|
||||||
|
@ -1363,10 +1360,9 @@ NtOpenKey(OUT PHANDLE KeyHandle,
|
||||||
goto openkey_cleanup;
|
goto openkey_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ObpCreateHandle(PsGetCurrentProcess(),
|
Status = ObpCreateHandle(Object,
|
||||||
Object,
|
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
TRUE,
|
ObjectCreateInfo.Attributes,
|
||||||
&hKey);
|
&hKey);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -1374,6 +1370,7 @@ NtOpenKey(OUT PHANDLE KeyHandle,
|
||||||
|
|
||||||
openkey_cleanup:
|
openkey_cleanup:
|
||||||
|
|
||||||
|
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
|
||||||
PostOpenKeyInfo.Object = NT_SUCCESS(Status) ? (PVOID)Object : NULL;
|
PostOpenKeyInfo.Object = NT_SUCCESS(Status) ? (PVOID)Object : NULL;
|
||||||
PostOpenKeyInfo.Status = Status;
|
PostOpenKeyInfo.Status = Status;
|
||||||
CmiCallRegisteredCallbacks (RegNtPostOpenKey, &PostOpenKeyInfo);
|
CmiCallRegisteredCallbacks (RegNtPostOpenKey, &PostOpenKeyInfo);
|
||||||
|
|
|
@ -429,10 +429,9 @@ ExpLoadInitialProcess(PHANDLE ProcessHandle,
|
||||||
RTL_USER_PROCESS_INFORMATION Info;
|
RTL_USER_PROCESS_INFORMATION Info;
|
||||||
|
|
||||||
/* Create a handle to the process */
|
/* Create a handle to the process */
|
||||||
Status = ObpCreateHandle(PsGetCurrentProcess(),
|
Status = ObpCreateHandle(PsInitialSystemProcess,
|
||||||
PsInitialSystemProcess,
|
|
||||||
PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION,
|
PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION,
|
||||||
FALSE,
|
OBJ_KERNEL_HANDLE,
|
||||||
&SystemProcessHandle);
|
&SystemProcessHandle);
|
||||||
if(!NT_SUCCESS(Status))
|
if(!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
|
|
@ -51,6 +51,8 @@ typedef struct _SYMLINK_OBJECT
|
||||||
((ProcessorMode) == KernelMode))
|
((ProcessorMode) == KernelMode))
|
||||||
#define ObKernelHandleToHandle(Handle) \
|
#define ObKernelHandleToHandle(Handle) \
|
||||||
(HANDLE)((ULONG_PTR)(Handle) & ~KERNEL_HANDLE_FLAG)
|
(HANDLE)((ULONG_PTR)(Handle) & ~KERNEL_HANDLE_FLAG)
|
||||||
|
#define ObMarkHandleAsKernelHandle(Handle) \
|
||||||
|
(HANDLE)((ULONG_PTR)(Handle) | KERNEL_HANDLE_FLAG)
|
||||||
|
|
||||||
extern PDIRECTORY_OBJECT NameSpaceRoot;
|
extern PDIRECTORY_OBJECT NameSpaceRoot;
|
||||||
extern POBJECT_TYPE ObSymbolicLinkType;
|
extern POBJECT_TYPE ObSymbolicLinkType;
|
||||||
|
@ -75,10 +77,9 @@ ObInitSymbolicLinkImplementation(VOID);
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
ObpCreateHandle(
|
ObpCreateHandle(
|
||||||
struct _EPROCESS* Process,
|
|
||||||
PVOID ObjectBody,
|
PVOID ObjectBody,
|
||||||
ACCESS_MASK GrantedAccess,
|
ACCESS_MASK GrantedAccess,
|
||||||
BOOLEAN Inherit,
|
ULONG HandleAttributes,
|
||||||
PHANDLE Handle
|
PHANDLE Handle
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -134,7 +135,7 @@ ObDuplicateObject(
|
||||||
HANDLE SourceHandle,
|
HANDLE SourceHandle,
|
||||||
PHANDLE TargetHandle,
|
PHANDLE TargetHandle,
|
||||||
ACCESS_MASK DesiredAccess,
|
ACCESS_MASK DesiredAccess,
|
||||||
BOOLEAN InheritHandle,
|
ULONG HandleAttributes,
|
||||||
ULONG Options
|
ULONG Options
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -89,42 +89,57 @@ NTAPI
|
||||||
ObpQueryHandleAttributes(HANDLE Handle,
|
ObpQueryHandleAttributes(HANDLE Handle,
|
||||||
POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo)
|
POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo)
|
||||||
{
|
{
|
||||||
PHANDLE_TABLE HandleTable;
|
|
||||||
PHANDLE_TABLE_ENTRY HandleTableEntry;
|
PHANDLE_TABLE_ENTRY HandleTableEntry;
|
||||||
|
PEPROCESS Process, CurrentProcess;
|
||||||
|
KAPC_STATE ApcState;
|
||||||
|
BOOLEAN AttachedToProcess = FALSE;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("ObpQueryHandleAttributes(Handle %x)\n", Handle);
|
DPRINT("ObpQueryHandleAttributes(Handle %p)\n", Handle);
|
||||||
|
CurrentProcess = PsGetCurrentProcess();
|
||||||
if(ObIsKernelHandle(Handle, ExGetPreviousMode()))
|
|
||||||
{
|
|
||||||
HandleTable = ObpKernelHandleTable;
|
|
||||||
Handle = ObKernelHandleToHandle(Handle);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HandleTable = PsGetCurrentProcess()->ObjectTable;
|
|
||||||
}
|
|
||||||
|
|
||||||
KeEnterCriticalRegion();
|
KeEnterCriticalRegion();
|
||||||
|
|
||||||
HandleTableEntry = ExMapHandleToPointer(HandleTable,
|
if(ObIsKernelHandle(Handle, ExGetPreviousMode()))
|
||||||
Handle);
|
|
||||||
if (HandleTableEntry == NULL)
|
|
||||||
{
|
{
|
||||||
KeLeaveCriticalRegion();
|
Process = PsInitialSystemProcess;
|
||||||
return STATUS_INVALID_HANDLE;
|
Handle = ObKernelHandleToHandle(Handle);
|
||||||
|
|
||||||
|
if (Process != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeStackAttachProcess(&Process->Pcb,
|
||||||
|
&ApcState);
|
||||||
|
AttachedToProcess = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Process = CurrentProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HandleTableEntry = ExMapHandleToPointer(Process->ObjectTable,
|
||||||
|
Handle);
|
||||||
|
if (HandleTableEntry != NULL)
|
||||||
|
{
|
||||||
HandleInfo->Inherit = (HandleTableEntry->u1.ObAttributes & EX_HANDLE_ENTRY_INHERITABLE) != 0;
|
HandleInfo->Inherit = (HandleTableEntry->u1.ObAttributes & EX_HANDLE_ENTRY_INHERITABLE) != 0;
|
||||||
HandleInfo->ProtectFromClose = (HandleTableEntry->u1.ObAttributes & EX_HANDLE_ENTRY_PROTECTFROMCLOSE) != 0;
|
HandleInfo->ProtectFromClose = (HandleTableEntry->u1.ObAttributes & EX_HANDLE_ENTRY_PROTECTFROMCLOSE) != 0;
|
||||||
|
|
||||||
ExUnlockHandleTableEntry(HandleTable,
|
ExUnlockHandleTableEntry(Process->ObjectTable,
|
||||||
HandleTableEntry);
|
HandleTableEntry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Status = STATUS_INVALID_HANDLE;
|
||||||
|
|
||||||
|
if (AttachedToProcess)
|
||||||
|
{
|
||||||
|
KeUnstackDetachProcess(&ApcState);
|
||||||
|
}
|
||||||
|
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -133,33 +148,40 @@ NTAPI
|
||||||
ObpSetHandleAttributes(HANDLE Handle,
|
ObpSetHandleAttributes(HANDLE Handle,
|
||||||
POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo)
|
POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo)
|
||||||
{
|
{
|
||||||
PHANDLE_TABLE HandleTable;
|
|
||||||
PHANDLE_TABLE_ENTRY HandleTableEntry;
|
PHANDLE_TABLE_ENTRY HandleTableEntry;
|
||||||
|
PEPROCESS Process, CurrentProcess;
|
||||||
|
KAPC_STATE ApcState;
|
||||||
|
BOOLEAN AttachedToProcess = FALSE;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("ObpSetHandleAttributes(Handle %x)\n", Handle);
|
DPRINT("ObpSetHandleAttributes(Handle %p)\n", Handle);
|
||||||
|
CurrentProcess = PsGetCurrentProcess();
|
||||||
if(ObIsKernelHandle(Handle, ExGetPreviousMode()))
|
|
||||||
{
|
|
||||||
HandleTable = ObpKernelHandleTable;
|
|
||||||
Handle = ObKernelHandleToHandle(Handle);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HandleTable = PsGetCurrentProcess()->ObjectTable;
|
|
||||||
}
|
|
||||||
|
|
||||||
KeEnterCriticalRegion();
|
KeEnterCriticalRegion();
|
||||||
|
|
||||||
HandleTableEntry = ExMapHandleToPointer(HandleTable,
|
if(ObIsKernelHandle(Handle, ExGetPreviousMode()))
|
||||||
Handle);
|
|
||||||
if (HandleTableEntry == NULL)
|
|
||||||
{
|
{
|
||||||
KeLeaveCriticalRegion();
|
Process = PsInitialSystemProcess;
|
||||||
return STATUS_INVALID_HANDLE;
|
Handle = ObKernelHandleToHandle(Handle);
|
||||||
|
|
||||||
|
if (Process != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeStackAttachProcess(&Process->Pcb,
|
||||||
|
&ApcState);
|
||||||
|
AttachedToProcess = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Process = CurrentProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HandleTableEntry = ExMapHandleToPointer(Process->ObjectTable,
|
||||||
|
Handle);
|
||||||
|
if (HandleTableEntry != NULL)
|
||||||
|
{
|
||||||
if (HandleInfo->Inherit)
|
if (HandleInfo->Inherit)
|
||||||
HandleTableEntry->u1.ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE;
|
HandleTableEntry->u1.ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE;
|
||||||
else
|
else
|
||||||
|
@ -172,36 +194,46 @@ ObpSetHandleAttributes(HANDLE Handle,
|
||||||
|
|
||||||
/* FIXME: Do we need to set anything in the object header??? */
|
/* FIXME: Do we need to set anything in the object header??? */
|
||||||
|
|
||||||
ExUnlockHandleTableEntry(HandleTable,
|
ExUnlockHandleTableEntry(Process->ObjectTable,
|
||||||
HandleTableEntry);
|
HandleTableEntry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Status = STATUS_INVALID_HANDLE;
|
||||||
|
|
||||||
|
if (AttachedToProcess)
|
||||||
|
{
|
||||||
|
KeUnstackDetachProcess(&ApcState);
|
||||||
|
}
|
||||||
|
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
ObpDeleteHandle(PHANDLE_TABLE HandleTable,
|
ObpDeleteHandle(HANDLE Handle)
|
||||||
HANDLE Handle)
|
|
||||||
{
|
{
|
||||||
PHANDLE_TABLE_ENTRY HandleEntry;
|
PHANDLE_TABLE_ENTRY HandleEntry;
|
||||||
PVOID Body;
|
PVOID Body;
|
||||||
POBJECT_HEADER ObjectHeader;
|
POBJECT_HEADER ObjectHeader;
|
||||||
|
PHANDLE_TABLE ObjectTable;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("ObpDeleteHandle(Handle %x)\n",Handle);
|
DPRINT("ObpDeleteHandle(Handle %p)\n",Handle);
|
||||||
|
|
||||||
|
ObjectTable = PsGetCurrentProcess()->ObjectTable;
|
||||||
|
|
||||||
KeEnterCriticalRegion();
|
KeEnterCriticalRegion();
|
||||||
|
|
||||||
HandleEntry = ExMapHandleToPointer(HandleTable,
|
HandleEntry = ExMapHandleToPointer(ObjectTable,
|
||||||
Handle);
|
Handle);
|
||||||
if(HandleEntry != NULL)
|
if(HandleEntry != NULL)
|
||||||
{
|
{
|
||||||
if(HandleEntry->u1.ObAttributes & EX_HANDLE_ENTRY_PROTECTFROMCLOSE)
|
if(HandleEntry->u1.ObAttributes & EX_HANDLE_ENTRY_PROTECTFROMCLOSE)
|
||||||
{
|
{
|
||||||
ExUnlockHandleTableEntry(HandleTable,
|
ExUnlockHandleTableEntry(ObjectTable,
|
||||||
HandleEntry);
|
HandleEntry);
|
||||||
|
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
|
@ -212,13 +244,13 @@ ObpDeleteHandle(PHANDLE_TABLE HandleTable,
|
||||||
ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
|
ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
|
||||||
Body = &ObjectHeader->Body;
|
Body = &ObjectHeader->Body;
|
||||||
|
|
||||||
ObpDecrementHandleCount(Body);
|
|
||||||
|
|
||||||
/* destroy and unlock the handle entry */
|
/* destroy and unlock the handle entry */
|
||||||
ExDestroyHandleByEntry(HandleTable,
|
ExDestroyHandleByEntry(ObjectTable,
|
||||||
HandleEntry,
|
HandleEntry,
|
||||||
Handle);
|
Handle);
|
||||||
|
|
||||||
|
ObpDecrementHandleCount(Body);
|
||||||
|
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
@ -235,35 +267,48 @@ ObDuplicateObject(PEPROCESS SourceProcess,
|
||||||
HANDLE SourceHandle,
|
HANDLE SourceHandle,
|
||||||
PHANDLE TargetHandle,
|
PHANDLE TargetHandle,
|
||||||
ACCESS_MASK DesiredAccess,
|
ACCESS_MASK DesiredAccess,
|
||||||
BOOLEAN InheritHandle,
|
ULONG HandleAttributes,
|
||||||
ULONG Options)
|
ULONG Options)
|
||||||
{
|
{
|
||||||
PHANDLE_TABLE SourceHandleTable;
|
|
||||||
PHANDLE_TABLE_ENTRY SourceHandleEntry;
|
PHANDLE_TABLE_ENTRY SourceHandleEntry;
|
||||||
HANDLE_TABLE_ENTRY NewHandleEntry;
|
HANDLE_TABLE_ENTRY NewHandleEntry;
|
||||||
|
BOOLEAN AttachedToProcess = FALSE;
|
||||||
PVOID ObjectBody;
|
PVOID ObjectBody;
|
||||||
POBJECT_HEADER ObjectHeader;
|
POBJECT_HEADER ObjectHeader;
|
||||||
ULONG NewHandleCount;
|
ULONG NewHandleCount;
|
||||||
HANDLE NewTargetHandle;
|
HANDLE NewTargetHandle;
|
||||||
|
PEPROCESS CurrentProcess;
|
||||||
|
KAPC_STATE ApcState;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
if(ObIsKernelHandle(SourceHandle, ExGetPreviousMode()))
|
if(SourceProcess == NULL ||
|
||||||
|
ObIsKernelHandle(SourceHandle, ExGetPreviousMode()))
|
||||||
{
|
{
|
||||||
SourceHandleTable = ObpKernelHandleTable;
|
SourceProcess = PsInitialSystemProcess;
|
||||||
SourceHandle = ObKernelHandleToHandle(SourceHandle);
|
SourceHandle = ObKernelHandleToHandle(SourceHandle);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
CurrentProcess = PsGetCurrentProcess();
|
||||||
SourceHandleTable = SourceProcess->ObjectTable;
|
|
||||||
}
|
|
||||||
|
|
||||||
KeEnterCriticalRegion();
|
KeEnterCriticalRegion();
|
||||||
|
|
||||||
SourceHandleEntry = ExMapHandleToPointer(SourceHandleTable,
|
if (SourceProcess != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeStackAttachProcess(&SourceProcess->Pcb,
|
||||||
|
&ApcState);
|
||||||
|
AttachedToProcess = TRUE;
|
||||||
|
}
|
||||||
|
SourceHandleEntry = ExMapHandleToPointer(SourceProcess->ObjectTable,
|
||||||
SourceHandle);
|
SourceHandle);
|
||||||
if (SourceHandleEntry == NULL)
|
if (SourceHandleEntry == NULL)
|
||||||
{
|
{
|
||||||
|
if (AttachedToProcess)
|
||||||
|
{
|
||||||
|
KeUnstackDetachProcess(&ApcState);
|
||||||
|
}
|
||||||
|
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
return STATUS_INVALID_HANDLE;
|
return STATUS_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
@ -272,7 +317,7 @@ ObDuplicateObject(PEPROCESS SourceProcess,
|
||||||
ObjectBody = &ObjectHeader->Body;
|
ObjectBody = &ObjectHeader->Body;
|
||||||
|
|
||||||
NewHandleEntry.u1.Object = SourceHandleEntry->u1.Object;
|
NewHandleEntry.u1.Object = SourceHandleEntry->u1.Object;
|
||||||
if(InheritHandle)
|
if(HandleAttributes & OBJ_INHERIT)
|
||||||
NewHandleEntry.u1.ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE;
|
NewHandleEntry.u1.ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE;
|
||||||
else
|
else
|
||||||
NewHandleEntry.u1.ObAttributes &= ~EX_HANDLE_ENTRY_INHERITABLE;
|
NewHandleEntry.u1.ObAttributes &= ~EX_HANDLE_ENTRY_INHERITABLE;
|
||||||
|
@ -305,27 +350,54 @@ ObDuplicateObject(PEPROCESS SourceProcess,
|
||||||
NewHandleCount = InterlockedIncrement(&ObjectHeader->HandleCount);
|
NewHandleCount = InterlockedIncrement(&ObjectHeader->HandleCount);
|
||||||
ASSERT(NewHandleCount >= 2);
|
ASSERT(NewHandleCount >= 2);
|
||||||
|
|
||||||
ExUnlockHandleTableEntry(SourceHandleTable,
|
ExUnlockHandleTableEntry(SourceProcess->ObjectTable,
|
||||||
SourceHandleEntry);
|
SourceHandleEntry);
|
||||||
|
|
||||||
KeLeaveCriticalRegion();
|
if (AttachedToProcess)
|
||||||
|
{
|
||||||
|
KeUnstackDetachProcess(&ApcState);
|
||||||
|
AttachedToProcess = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TargetProcess != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeStackAttachProcess(&TargetProcess->Pcb,
|
||||||
|
&ApcState);
|
||||||
|
AttachedToProcess = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* attempt to create the new handle */
|
/* attempt to create the new handle */
|
||||||
NewTargetHandle = ExCreateHandle(TargetProcess->ObjectTable,
|
NewTargetHandle = ExCreateHandle(TargetProcess->ObjectTable,
|
||||||
&NewHandleEntry);
|
&NewHandleEntry);
|
||||||
|
if (AttachedToProcess)
|
||||||
|
{
|
||||||
|
KeUnstackDetachProcess(&ApcState);
|
||||||
|
AttachedToProcess = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (NewTargetHandle != NULL)
|
if (NewTargetHandle != NULL)
|
||||||
{
|
{
|
||||||
if (Options & DUPLICATE_CLOSE_SOURCE)
|
if (Options & DUPLICATE_CLOSE_SOURCE)
|
||||||
{
|
{
|
||||||
ObpDeleteHandle(SourceHandleTable,
|
if (SourceProcess != CurrentProcess)
|
||||||
SourceHandle);
|
{
|
||||||
|
KeStackAttachProcess(&SourceProcess->Pcb,
|
||||||
|
&ApcState);
|
||||||
|
AttachedToProcess = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* delete the source handle */
|
||||||
|
ObpDeleteHandle(SourceHandle);
|
||||||
|
|
||||||
|
if (AttachedToProcess)
|
||||||
|
{
|
||||||
|
KeUnstackDetachProcess(&ApcState);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ObDereferenceObject(ObjectBody);
|
ObDereferenceObject(ObjectBody);
|
||||||
|
|
||||||
*TargetHandle = NewTargetHandle;
|
*TargetHandle = NewTargetHandle;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -337,8 +409,12 @@ ObDuplicateObject(PEPROCESS SourceProcess,
|
||||||
}
|
}
|
||||||
|
|
||||||
ObDereferenceObject(ObjectBody);
|
ObDereferenceObject(ObjectBody);
|
||||||
return STATUS_UNSUCCESSFUL;
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -350,7 +426,7 @@ NtDuplicateObject (IN HANDLE SourceProcessHandle,
|
||||||
IN HANDLE TargetProcessHandle,
|
IN HANDLE TargetProcessHandle,
|
||||||
OUT PHANDLE TargetHandle OPTIONAL,
|
OUT PHANDLE TargetHandle OPTIONAL,
|
||||||
IN ACCESS_MASK DesiredAccess,
|
IN ACCESS_MASK DesiredAccess,
|
||||||
IN ULONG InheritHandle,
|
IN ULONG HandleAttributes,
|
||||||
IN ULONG Options)
|
IN ULONG Options)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Copies a handle from one process space to another
|
* FUNCTION: Copies a handle from one process space to another
|
||||||
|
@ -364,8 +440,7 @@ NtDuplicateObject (IN HANDLE SourceProcessHandle,
|
||||||
* TargetHandle (OUT) = Caller should supply storage for the
|
* TargetHandle (OUT) = Caller should supply storage for the
|
||||||
* duplicated handle.
|
* duplicated handle.
|
||||||
* DesiredAccess = The desired access to the handle.
|
* DesiredAccess = The desired access to the handle.
|
||||||
* InheritHandle = Indicates wheter the new handle will be inheritable
|
* HandleAttributes = The desired handle attributes.
|
||||||
* or not.
|
|
||||||
* Options = Specifies special actions upon duplicating the handle.
|
* Options = Specifies special actions upon duplicating the handle.
|
||||||
* Can be one of the values DUPLICATE_CLOSE_SOURCE |
|
* Can be one of the values DUPLICATE_CLOSE_SOURCE |
|
||||||
* DUPLICATE_SAME_ACCESS. DUPLICATE_CLOSE_SOURCE specifies
|
* DUPLICATE_SAME_ACCESS. DUPLICATE_CLOSE_SOURCE specifies
|
||||||
|
@ -379,8 +454,11 @@ NtDuplicateObject (IN HANDLE SourceProcessHandle,
|
||||||
{
|
{
|
||||||
PEPROCESS SourceProcess;
|
PEPROCESS SourceProcess;
|
||||||
PEPROCESS TargetProcess;
|
PEPROCESS TargetProcess;
|
||||||
|
PEPROCESS CurrentProcess;
|
||||||
HANDLE hTarget;
|
HANDLE hTarget;
|
||||||
|
BOOLEAN AttachedToProcess = FALSE;
|
||||||
KPROCESSOR_MODE PreviousMode;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
KAPC_STATE ApcState;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
@ -428,6 +506,8 @@ NtDuplicateObject (IN HANDLE SourceProcessHandle,
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CurrentProcess = PsGetCurrentProcess();
|
||||||
|
|
||||||
/* Check for magic handle first */
|
/* Check for magic handle first */
|
||||||
if (SourceHandle == NtCurrentThread() ||
|
if (SourceHandle == NtCurrentThread() ||
|
||||||
SourceHandle == NtCurrentProcess())
|
SourceHandle == NtCurrentProcess())
|
||||||
|
@ -458,18 +538,42 @@ NtDuplicateObject (IN HANDLE SourceProcessHandle,
|
||||||
&ObjectType->TypeInfo.GenericMapping);
|
&ObjectType->TypeInfo.GenericMapping);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Status = ObpCreateHandle(TargetProcess,
|
|
||||||
ObjectBody,
|
if (TargetProcess != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeStackAttachProcess(&TargetProcess->Pcb,
|
||||||
|
&ApcState);
|
||||||
|
AttachedToProcess = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = ObpCreateHandle(ObjectBody,
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
InheritHandle,
|
HandleAttributes,
|
||||||
&hTarget);
|
&hTarget);
|
||||||
|
|
||||||
|
if (AttachedToProcess)
|
||||||
|
{
|
||||||
|
KeUnstackDetachProcess(&ApcState);
|
||||||
|
AttachedToProcess = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
ObDereferenceObject(ObjectBody);
|
ObDereferenceObject(ObjectBody);
|
||||||
|
|
||||||
if (Options & DUPLICATE_CLOSE_SOURCE)
|
if (Options & DUPLICATE_CLOSE_SOURCE)
|
||||||
{
|
{
|
||||||
ObpDeleteHandle(SourceProcess->ObjectTable,
|
if (SourceProcess != CurrentProcess)
|
||||||
SourceHandle);
|
{
|
||||||
|
KeStackAttachProcess(&SourceProcess->Pcb,
|
||||||
|
&ApcState);
|
||||||
|
AttachedToProcess = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObpDeleteHandle(SourceHandle);
|
||||||
|
|
||||||
|
if (AttachedToProcess)
|
||||||
|
{
|
||||||
|
KeUnstackDetachProcess(&ApcState);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -480,7 +584,7 @@ NtDuplicateObject (IN HANDLE SourceProcessHandle,
|
||||||
SourceHandle,
|
SourceHandle,
|
||||||
&hTarget,
|
&hTarget,
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
InheritHandle,
|
HandleAttributes,
|
||||||
Options);
|
Options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -591,10 +695,9 @@ ObKillProcess(PEPROCESS Process)
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
ObpCreateHandle(PEPROCESS Process,
|
ObpCreateHandle(PVOID ObjectBody,
|
||||||
PVOID ObjectBody,
|
|
||||||
ACCESS_MASK GrantedAccess,
|
ACCESS_MASK GrantedAccess,
|
||||||
BOOLEAN Inherit,
|
ULONG HandleAttributes,
|
||||||
PHANDLE HandleReturn)
|
PHANDLE HandleReturn)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Add a handle referencing an object
|
* FUNCTION: Add a handle referencing an object
|
||||||
|
@ -605,18 +708,23 @@ ObpCreateHandle(PEPROCESS Process,
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
HANDLE_TABLE_ENTRY NewEntry;
|
HANDLE_TABLE_ENTRY NewEntry;
|
||||||
|
PEPROCESS Process, CurrentProcess;
|
||||||
POBJECT_HEADER ObjectHeader;
|
POBJECT_HEADER ObjectHeader;
|
||||||
HANDLE Handle;
|
HANDLE Handle;
|
||||||
|
KAPC_STATE ApcState;
|
||||||
|
BOOLEAN AttachedToProcess = FALSE;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("ObpCreateHandle(Process %x, obj %x)\n",Process,ObjectBody);
|
DPRINT("ObpCreateHandle(obj %p)\n",ObjectBody);
|
||||||
|
|
||||||
ASSERT(Process);
|
|
||||||
ASSERT(ObjectBody);
|
ASSERT(ObjectBody);
|
||||||
|
|
||||||
|
CurrentProcess = PsGetCurrentProcess();
|
||||||
|
|
||||||
ObjectHeader = BODY_TO_HEADER(ObjectBody);
|
ObjectHeader = BODY_TO_HEADER(ObjectBody);
|
||||||
|
|
||||||
|
/* check that this is a valid kernel pointer */
|
||||||
ASSERT((ULONG_PTR)ObjectHeader & EX_HANDLE_ENTRY_LOCKED);
|
ASSERT((ULONG_PTR)ObjectHeader & EX_HANDLE_ENTRY_LOCKED);
|
||||||
|
|
||||||
if (GrantedAccess & MAXIMUM_ALLOWED)
|
if (GrantedAccess & MAXIMUM_ALLOWED)
|
||||||
|
@ -632,23 +740,49 @@ ObpCreateHandle(PEPROCESS Process,
|
||||||
}
|
}
|
||||||
|
|
||||||
NewEntry.u1.Object = ObjectHeader;
|
NewEntry.u1.Object = ObjectHeader;
|
||||||
if(Inherit)
|
if(HandleAttributes & OBJ_INHERIT)
|
||||||
NewEntry.u1.ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE;
|
NewEntry.u1.ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE;
|
||||||
else
|
else
|
||||||
NewEntry.u1.ObAttributes &= ~EX_HANDLE_ENTRY_INHERITABLE;
|
NewEntry.u1.ObAttributes &= ~EX_HANDLE_ENTRY_INHERITABLE;
|
||||||
NewEntry.u2.GrantedAccess = GrantedAccess;
|
NewEntry.u2.GrantedAccess = GrantedAccess;
|
||||||
|
|
||||||
|
if ((HandleAttributes & OBJ_KERNEL_HANDLE) &&
|
||||||
|
ExGetPreviousMode == KernelMode)
|
||||||
|
{
|
||||||
|
Process = PsInitialSystemProcess;
|
||||||
|
if (Process != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeStackAttachProcess(&Process->Pcb,
|
||||||
|
&ApcState);
|
||||||
|
AttachedToProcess = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Process = CurrentProcess;
|
||||||
|
/* mask out the OBJ_KERNEL_HANDLE attribute */
|
||||||
|
HandleAttributes &= ~OBJ_KERNEL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
Handle = ExCreateHandle(Process->ObjectTable,
|
Handle = ExCreateHandle(Process->ObjectTable,
|
||||||
&NewEntry);
|
&NewEntry);
|
||||||
DPRINT("ObCreateHandle(0x%x)==0x%x [HT:0x%x]\n", ObjectHeader, Handle, Process->ObjectTable);
|
|
||||||
|
if (AttachedToProcess)
|
||||||
|
{
|
||||||
|
KeUnstackDetachProcess(&ApcState);
|
||||||
|
}
|
||||||
|
|
||||||
if(Handle != NULL)
|
if(Handle != NULL)
|
||||||
{
|
{
|
||||||
|
if (HandleAttributes & OBJ_KERNEL_HANDLE)
|
||||||
|
{
|
||||||
|
/* mark the handle value */
|
||||||
|
Handle = ObMarkHandleAsKernelHandle(Handle);
|
||||||
|
}
|
||||||
|
|
||||||
if(InterlockedIncrement(&ObjectHeader->HandleCount) == 1)
|
if(InterlockedIncrement(&ObjectHeader->HandleCount) == 1)
|
||||||
{
|
{
|
||||||
ObReferenceObjectByPointer(ObjectBody,
|
ObReferenceObject(ObjectBody);
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
UserMode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*HandleReturn = Handle;
|
*HandleReturn = Handle;
|
||||||
|
@ -668,16 +802,34 @@ ObQueryObjectAuditingByHandle(IN HANDLE Handle,
|
||||||
OUT PBOOLEAN GenerateOnClose)
|
OUT PBOOLEAN GenerateOnClose)
|
||||||
{
|
{
|
||||||
PHANDLE_TABLE_ENTRY HandleEntry;
|
PHANDLE_TABLE_ENTRY HandleEntry;
|
||||||
PEPROCESS Process;
|
PEPROCESS Process, CurrentProcess;
|
||||||
|
KAPC_STATE ApcState;
|
||||||
|
BOOLEAN AttachedToProcess = FALSE;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("ObQueryObjectAuditingByHandle(Handle %x)\n", Handle);
|
DPRINT("ObQueryObjectAuditingByHandle(Handle %p)\n", Handle);
|
||||||
|
|
||||||
Process = PsGetCurrentProcess();
|
CurrentProcess = PsGetCurrentProcess();
|
||||||
|
|
||||||
KeEnterCriticalRegion();
|
KeEnterCriticalRegion();
|
||||||
|
|
||||||
|
if(ObIsKernelHandle(Handle, ExGetPreviousMode()))
|
||||||
|
{
|
||||||
|
Process = PsInitialSystemProcess;
|
||||||
|
Handle = ObKernelHandleToHandle(Handle);
|
||||||
|
|
||||||
|
if (Process != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeStackAttachProcess(&Process->Pcb,
|
||||||
|
&ApcState);
|
||||||
|
AttachedToProcess = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Process = CurrentProcess;
|
||||||
|
|
||||||
HandleEntry = ExMapHandleToPointer(Process->ObjectTable,
|
HandleEntry = ExMapHandleToPointer(Process->ObjectTable,
|
||||||
Handle);
|
Handle);
|
||||||
if(HandleEntry != NULL)
|
if(HandleEntry != NULL)
|
||||||
|
@ -686,15 +838,18 @@ ObQueryObjectAuditingByHandle(IN HANDLE Handle,
|
||||||
|
|
||||||
ExUnlockHandleTableEntry(Process->ObjectTable,
|
ExUnlockHandleTableEntry(Process->ObjectTable,
|
||||||
HandleEntry);
|
HandleEntry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Status = STATUS_INVALID_HANDLE;
|
||||||
|
|
||||||
KeLeaveCriticalRegion();
|
if (AttachedToProcess)
|
||||||
|
{
|
||||||
return STATUS_SUCCESS;
|
KeUnstackDetachProcess(&ApcState);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
return STATUS_INVALID_HANDLE;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -723,29 +878,32 @@ ObReferenceObjectByHandle(HANDLE Handle,
|
||||||
{
|
{
|
||||||
PHANDLE_TABLE_ENTRY HandleEntry;
|
PHANDLE_TABLE_ENTRY HandleEntry;
|
||||||
POBJECT_HEADER ObjectHeader;
|
POBJECT_HEADER ObjectHeader;
|
||||||
PHANDLE_TABLE HandleTable;
|
|
||||||
PVOID ObjectBody;
|
PVOID ObjectBody;
|
||||||
ACCESS_MASK GrantedAccess;
|
ACCESS_MASK GrantedAccess;
|
||||||
ULONG Attributes;
|
ULONG Attributes;
|
||||||
|
PEPROCESS CurrentProcess, Process;
|
||||||
|
BOOLEAN AttachedToProcess = FALSE;
|
||||||
|
KAPC_STATE ApcState;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("ObReferenceObjectByHandle(Handle %x, DesiredAccess %x, "
|
DPRINT("ObReferenceObjectByHandle(Handle %p, DesiredAccess %x, "
|
||||||
"ObjectType %x, AccessMode %d, Object %x)\n",Handle,DesiredAccess,
|
"ObjectType %p, AccessMode %d, Object %p)\n",Handle,DesiredAccess,
|
||||||
ObjectType,AccessMode,Object);
|
ObjectType,AccessMode,Object);
|
||||||
|
|
||||||
if (Handle == NULL)
|
if (Handle == NULL)
|
||||||
{
|
{
|
||||||
return STATUS_INVALID_HANDLE;
|
return STATUS_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CurrentProcess = PsGetCurrentProcess();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle special handle names
|
* Handle special handle names
|
||||||
*/
|
*/
|
||||||
if (Handle == NtCurrentProcess() &&
|
if (Handle == NtCurrentProcess() &&
|
||||||
(ObjectType == PsProcessType || ObjectType == NULL))
|
(ObjectType == PsProcessType || ObjectType == NULL))
|
||||||
{
|
{
|
||||||
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
|
||||||
|
|
||||||
ObReferenceObject(CurrentProcess);
|
ObReferenceObject(CurrentProcess);
|
||||||
|
|
||||||
if (HandleInformation != NULL)
|
if (HandleInformation != NULL)
|
||||||
|
@ -755,7 +913,7 @@ ObReferenceObjectByHandle(HANDLE Handle,
|
||||||
}
|
}
|
||||||
|
|
||||||
*Object = CurrentProcess;
|
*Object = CurrentProcess;
|
||||||
DPRINT("Referencing current process %x\n", CurrentProcess);
|
DPRINT("Referencing current process %p\n", CurrentProcess);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
else if (Handle == NtCurrentProcess())
|
else if (Handle == NtCurrentProcess())
|
||||||
|
@ -796,37 +954,53 @@ ObReferenceObjectByHandle(HANDLE Handle,
|
||||||
|
|
||||||
if(ObIsKernelHandle(Handle, AccessMode))
|
if(ObIsKernelHandle(Handle, AccessMode))
|
||||||
{
|
{
|
||||||
HandleTable = ObpKernelHandleTable;
|
Process = PsInitialSystemProcess;
|
||||||
Handle = ObKernelHandleToHandle(Handle);
|
Handle = ObKernelHandleToHandle(Handle);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HandleTable = PsGetCurrentProcess()->ObjectTable;
|
Process = CurrentProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
KeEnterCriticalRegion();
|
KeEnterCriticalRegion();
|
||||||
|
|
||||||
HandleEntry = ExMapHandleToPointer(HandleTable,
|
if (Process != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeStackAttachProcess(&Process->Pcb,
|
||||||
|
&ApcState);
|
||||||
|
AttachedToProcess = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
HandleEntry = ExMapHandleToPointer(Process->ObjectTable,
|
||||||
Handle);
|
Handle);
|
||||||
if (HandleEntry == NULL)
|
if (HandleEntry == NULL)
|
||||||
{
|
{
|
||||||
|
if (AttachedToProcess)
|
||||||
|
{
|
||||||
|
KeUnstackDetachProcess(&ApcState);
|
||||||
|
}
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
DPRINT("ExMapHandleToPointer() failed for handle 0x%x\n", Handle);
|
DPRINT("ExMapHandleToPointer() failed for handle 0x%p\n", Handle);
|
||||||
return(STATUS_INVALID_HANDLE);
|
return(STATUS_INVALID_HANDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
|
ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
|
||||||
ObjectBody = &ObjectHeader->Body;
|
ObjectBody = &ObjectHeader->Body;
|
||||||
|
|
||||||
DPRINT("locked1: ObjectHeader: 0x%x [HT:0x%x]\n", ObjectHeader, HandleTable);
|
DPRINT("locked1: ObjectHeader: 0x%p [HT:0x%p]\n", ObjectHeader, Process->ObjectTable);
|
||||||
|
|
||||||
if (ObjectType != NULL && ObjectType != ObjectHeader->Type)
|
if (ObjectType != NULL && ObjectType != ObjectHeader->Type)
|
||||||
{
|
{
|
||||||
DPRINT("ObjectType mismatch: %wZ vs %wZ (handle 0x%x)\n", &ObjectType->Name, ObjectHeader->Type ? &ObjectHeader->Type->Name : NULL, Handle);
|
DPRINT("ObjectType mismatch: %wZ vs %wZ (handle 0x%p)\n", &ObjectType->Name, ObjectHeader->Type ? &ObjectHeader->Type->Name : NULL, Handle);
|
||||||
|
|
||||||
ExUnlockHandleTableEntry(HandleTable,
|
ExUnlockHandleTableEntry(Process->ObjectTable,
|
||||||
HandleEntry);
|
HandleEntry);
|
||||||
|
|
||||||
|
if (AttachedToProcess)
|
||||||
|
{
|
||||||
|
KeUnstackDetachProcess(&ApcState);
|
||||||
|
}
|
||||||
|
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
return(STATUS_OBJECT_TYPE_MISMATCH);
|
return(STATUS_OBJECT_TYPE_MISMATCH);
|
||||||
|
@ -845,9 +1019,14 @@ ObReferenceObjectByHandle(HANDLE Handle,
|
||||||
rights than the handle can grant */
|
rights than the handle can grant */
|
||||||
if(AccessMode != KernelMode && (~GrantedAccess & DesiredAccess))
|
if(AccessMode != KernelMode && (~GrantedAccess & DesiredAccess))
|
||||||
{
|
{
|
||||||
ExUnlockHandleTableEntry(HandleTable,
|
ExUnlockHandleTableEntry(Process->ObjectTable,
|
||||||
HandleEntry);
|
HandleEntry);
|
||||||
|
|
||||||
|
if (AttachedToProcess)
|
||||||
|
{
|
||||||
|
KeUnstackDetachProcess(&ApcState);
|
||||||
|
}
|
||||||
|
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
DPRINT1("GrantedAccess: 0x%x, ~GrantedAccess: 0x%x, DesiredAccess: 0x%x, denied: 0x%x\n", GrantedAccess, ~GrantedAccess, DesiredAccess, ~GrantedAccess & DesiredAccess);
|
DPRINT1("GrantedAccess: 0x%x, ~GrantedAccess: 0x%x, DesiredAccess: 0x%x, denied: 0x%x\n", GrantedAccess, ~GrantedAccess, DesiredAccess, ~GrantedAccess & DesiredAccess);
|
||||||
|
@ -861,9 +1040,14 @@ ObReferenceObjectByHandle(HANDLE Handle,
|
||||||
EX_HANDLE_ENTRY_INHERITABLE |
|
EX_HANDLE_ENTRY_INHERITABLE |
|
||||||
EX_HANDLE_ENTRY_AUDITONCLOSE);
|
EX_HANDLE_ENTRY_AUDITONCLOSE);
|
||||||
|
|
||||||
ExUnlockHandleTableEntry(HandleTable,
|
ExUnlockHandleTableEntry(Process->ObjectTable,
|
||||||
HandleEntry);
|
HandleEntry);
|
||||||
|
|
||||||
|
if (AttachedToProcess)
|
||||||
|
{
|
||||||
|
KeUnstackDetachProcess(&ApcState);
|
||||||
|
}
|
||||||
|
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
if (HandleInformation != NULL)
|
if (HandleInformation != NULL)
|
||||||
|
@ -897,27 +1081,43 @@ ObReferenceObjectByHandle(HANDLE Handle,
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
NtClose(IN HANDLE Handle)
|
NtClose(IN HANDLE Handle)
|
||||||
{
|
{
|
||||||
PHANDLE_TABLE HandleTable;
|
PEPROCESS Process, CurrentProcess;
|
||||||
|
BOOLEAN AttachedToProcess = FALSE;
|
||||||
|
KAPC_STATE ApcState;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
if(ObIsKernelHandle(Handle, ExGetPreviousMode()))
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
CurrentProcess = PsGetCurrentProcess();
|
||||||
|
|
||||||
|
if(ObIsKernelHandle(Handle, PreviousMode))
|
||||||
{
|
{
|
||||||
HandleTable = ObpKernelHandleTable;
|
Process = PsInitialSystemProcess;
|
||||||
Handle = ObKernelHandleToHandle(Handle);
|
Handle = ObKernelHandleToHandle(Handle);
|
||||||
|
|
||||||
|
if (Process != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeStackAttachProcess(&Process->Pcb,
|
||||||
|
&ApcState);
|
||||||
|
AttachedToProcess = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Process = CurrentProcess;
|
||||||
|
|
||||||
|
Status = ObpDeleteHandle(Handle);
|
||||||
|
|
||||||
|
if (AttachedToProcess)
|
||||||
{
|
{
|
||||||
HandleTable = PsGetCurrentProcess()->ObjectTable;
|
KeUnstackDetachProcess(&ApcState);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ObpDeleteHandle(HandleTable,
|
|
||||||
Handle);
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
if((ExGetPreviousMode() != KernelMode) &&
|
if((PreviousMode != KernelMode) &&
|
||||||
(PsGetCurrentProcess()->ExceptionPort))
|
(CurrentProcess->ExceptionPort))
|
||||||
{
|
{
|
||||||
KeRaiseUserException(Status);
|
KeRaiseUserException(Status);
|
||||||
}
|
}
|
||||||
|
@ -1128,10 +1328,9 @@ ObInsertObject(IN PVOID Object,
|
||||||
DPRINT("Creating handle\n");
|
DPRINT("Creating handle\n");
|
||||||
if (Handle != NULL)
|
if (Handle != NULL)
|
||||||
{
|
{
|
||||||
Status = ObpCreateHandle(PsGetCurrentProcess(),
|
Status = ObpCreateHandle(&Header->Body,
|
||||||
&Header->Body,
|
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
ObjectCreateInfo->Attributes & OBJ_INHERIT,
|
ObjectCreateInfo->Attributes,
|
||||||
Handle);
|
Handle);
|
||||||
DPRINT("handle Created: %d. refcount. handlecount %d %d\n",
|
DPRINT("handle Created: %d. refcount. handlecount %d %d\n",
|
||||||
*Handle, Header->PointerCount, Header->HandleCount);
|
*Handle, Header->PointerCount, Header->HandleCount);
|
||||||
|
|
|
@ -183,19 +183,18 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
&Object,
|
&Object,
|
||||||
&RemainingPath,
|
&RemainingPath,
|
||||||
ObjectType);
|
ObjectType);
|
||||||
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
|
|
||||||
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("ObFindObject() failed (Status %lx)\n", Status);
|
DPRINT("ObFindObject() failed (Status %lx)\n", Status);
|
||||||
return Status;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("OBject: %x, Remaining Path: %wZ\n", Object, &RemainingPath);
|
DPRINT("OBject: %p, Remaining Path: %wZ\n", Object, &RemainingPath);
|
||||||
if (Object == NULL)
|
if (Object == NULL)
|
||||||
{
|
{
|
||||||
RtlFreeUnicodeString(&RemainingPath);
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
return STATUS_UNSUCCESSFUL;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
if (RemainingPath.Buffer != NULL)
|
if (RemainingPath.Buffer != NULL)
|
||||||
{
|
{
|
||||||
|
@ -203,19 +202,21 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
Status = STATUS_OBJECT_NAME_NOT_FOUND;
|
Status = STATUS_OBJECT_NAME_NOT_FOUND;
|
||||||
else
|
else
|
||||||
Status =STATUS_OBJECT_PATH_NOT_FOUND;
|
Status =STATUS_OBJECT_PATH_NOT_FOUND;
|
||||||
RtlFreeUnicodeString(&RemainingPath);
|
goto Cleanup;
|
||||||
ObDereferenceObject(Object);
|
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ObpCreateHandle(PsGetCurrentProcess(),
|
Status = ObpCreateHandle(Object,
|
||||||
Object,
|
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
FALSE,
|
ObjectCreateInfo.Attributes,
|
||||||
Handle);
|
Handle);
|
||||||
|
|
||||||
|
Cleanup:
|
||||||
|
if (Object != NULL)
|
||||||
|
{
|
||||||
ObDereferenceObject(Object);
|
ObDereferenceObject(Object);
|
||||||
|
}
|
||||||
RtlFreeUnicodeString(&RemainingPath);
|
RtlFreeUnicodeString(&RemainingPath);
|
||||||
|
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -316,7 +316,7 @@ ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
||||||
ObReferenceObjectByPointer(NameSpaceRoot,
|
ObReferenceObjectByPointer(NameSpaceRoot,
|
||||||
DIRECTORY_TRAVERSE,
|
DIRECTORY_TRAVERSE,
|
||||||
NULL,
|
NULL,
|
||||||
UserMode);
|
ObjectCreateInfo->ProbeMode);
|
||||||
CurrentObject = NameSpaceRoot;
|
CurrentObject = NameSpaceRoot;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -324,7 +324,7 @@ ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
||||||
Status = ObReferenceObjectByHandle(ObjectCreateInfo->RootDirectory,
|
Status = ObReferenceObjectByHandle(ObjectCreateInfo->RootDirectory,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
UserMode,
|
ObjectCreateInfo->ProbeMode,
|
||||||
&CurrentObject,
|
&CurrentObject,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -398,7 +398,7 @@ ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
|
||||||
ObReferenceObjectByPointer(NextObject,
|
ObReferenceObjectByPointer(NextObject,
|
||||||
DIRECTORY_TRAVERSE,
|
DIRECTORY_TRAVERSE,
|
||||||
NULL,
|
NULL,
|
||||||
UserMode);
|
ObjectCreateInfo->ProbeMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NextObject == NULL)
|
if (NextObject == NULL)
|
||||||
|
@ -926,10 +926,9 @@ ObOpenObjectByPointer(IN PVOID Object,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ObpCreateHandle(PsGetCurrentProcess(),
|
Status = ObpCreateHandle(Object,
|
||||||
Object,
|
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
(BOOLEAN)(HandleAttributes & OBJ_INHERIT),
|
HandleAttributes,
|
||||||
Handle);
|
Handle);
|
||||||
|
|
||||||
ObDereferenceObject(Object);
|
ObDereferenceObject(Object);
|
||||||
|
|
|
@ -97,10 +97,9 @@ NtOpenProcessTokenEx(IN HANDLE ProcessHandle,
|
||||||
&Token);
|
&Token);
|
||||||
if(NT_SUCCESS(Status))
|
if(NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
Status = ObpCreateHandle(PsGetCurrentProcess(),
|
Status = ObpCreateHandle(Token,
|
||||||
Token,
|
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
FALSE,
|
HandleAttributes,
|
||||||
&hToken);
|
&hToken);
|
||||||
ObDereferenceObject(Token);
|
ObDereferenceObject(Token);
|
||||||
|
|
||||||
|
|
|
@ -250,14 +250,17 @@ NtPrivilegeCheck (IN HANDLE ClientToken,
|
||||||
ULONG PrivilegeCount;
|
ULONG PrivilegeCount;
|
||||||
ULONG PrivilegeControl;
|
ULONG PrivilegeControl;
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
|
KPROCESSOR_MODE PreviousMode;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
PreviousMode = KeGetPreviousMode();
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle (ClientToken,
|
Status = ObReferenceObjectByHandle (ClientToken,
|
||||||
0,
|
TOKEN_QUERY,
|
||||||
SepTokenObjectType,
|
SepTokenObjectType,
|
||||||
UserMode,
|
PreviousMode,
|
||||||
(PVOID*)&Token,
|
(PVOID*)&Token,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue