HANDLE GetCsrPid() { HANDLE Process, hObject; HANDLE CsrId = (HANDLE)0; OBJECT_ATTRIBUTES obj; CLIENT_ID cid; UCHAR Buff[0x100]; POBJECT_NAME_INFORMATION ObjName = (PVOID)&Buff; PSYSTEM_HANDLE_INFORMATION_EX Handles; ULONG r; Handles = GetInfoTable(SystemHandleInformation); if (!Handles) return CsrId; for (r = 0; r < Handles->NumberOfHandles; r++) { if (Handles->Information[r].ObjectTypeNumber == 21) //Port object { InitializeObjectAttributes(&obj, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); cid.UniqueProcess = (HANDLE)Handles->Information[r].ProcessId; cid.UniqueThread = 0; if (NT_SUCCESS(NtOpenProcess(&Process, PROCESS_DUP_HANDLE, &obj, &cid))) { if (NT_SUCCESS(ZwDuplicateObject(Process, (HANDLE)Handles->Information[r].Handle,NtCurrentProcess(), &hObject, 0, 0, DUPLICATE_SAME_ACCESS))) { if (NT_SUCCESS(ZwQueryObject(hObject, ObjectNameInformation, ObjName, 0x100, NULL))) { if (ObjName->Name.Buffer && !wcsncmp(L"\\Windows\\ApiPort", ObjName->Name.Buffer, 20)) { CsrId = (HANDLE)Handles->Information[r].ProcessId; } } ZwClose(hObject); } ZwClose(Process); } } } ExFreePool(Handles); return CsrId; }
NTSTATUS CWdfDevice::CreateUserModeHandle(HANDLE RequestorProcess, PHANDLE ObjectHandle) { IO_STATUS_BLOCK IoStatusBlock; PCUNICODE_STRING UniName = m_CachedName; OBJECT_ATTRIBUTES ObjectAttributes; InitializeObjectAttributes(&ObjectAttributes, const_cast<PUNICODE_STRING>(UniName), OBJ_KERNEL_HANDLE, nullptr, nullptr); HANDLE KernelHandle; auto status = ZwOpenFile(&KernelHandle, GENERIC_READ | GENERIC_WRITE, &ObjectAttributes, &IoStatusBlock, 0, FILE_NON_DIRECTORY_FILE | FILE_RANDOM_ACCESS); if (!NT_SUCCESS(status)) { return status; } status = ZwDuplicateObject(ZwCurrentProcess(), KernelHandle, RequestorProcess, ObjectHandle, 0, 0, DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES | DUPLICATE_CLOSE_SOURCE); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_WDFDEVICE, "%!FUNC! ZwDuplicateObject failed. %!STATUS!", status); ZwClose(KernelHandle); } return status; }
/* * @implemented * * Creates a process and its initial thread. * * NOTES: * - The first thread is created suspended, so it needs a manual resume!!! * - If ParentProcess is NULL, current process is used * - ProcessParameters must be normalized * - Attributes are object attribute flags used when opening the ImageFileName. * Valid flags are OBJ_INHERIT and OBJ_CASE_INSENSITIVE. * * -Gunnar */ NTSTATUS NTAPI RtlCreateUserProcess(IN PUNICODE_STRING ImageFileName, IN ULONG Attributes, IN OUT PRTL_USER_PROCESS_PARAMETERS ProcessParameters, IN PSECURITY_DESCRIPTOR ProcessSecurityDescriptor OPTIONAL, IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor OPTIONAL, IN HANDLE ParentProcess OPTIONAL, IN BOOLEAN InheritHandles, IN HANDLE DebugPort OPTIONAL, IN HANDLE ExceptionPort OPTIONAL, OUT PRTL_USER_PROCESS_INFORMATION ProcessInfo) { NTSTATUS Status; HANDLE hSection; PROCESS_BASIC_INFORMATION ProcessBasicInfo; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING DebugString = RTL_CONSTANT_STRING(L"\\WindowsSS"); DPRINT("RtlCreateUserProcess: %wZ\n", ImageFileName); /* Map and Load the File */ Status = RtlpMapFile(ImageFileName, Attributes, &hSection); if (!NT_SUCCESS(Status)) { DPRINT1("Could not map process image\n"); return Status; } /* Clean out the current directory handle if we won't use it */ if (!InheritHandles) ProcessParameters->CurrentDirectory.Handle = NULL; /* Use us as parent if none other specified */ if (!ParentProcess) ParentProcess = NtCurrentProcess(); /* Initialize the Object Attributes */ InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, ProcessSecurityDescriptor); /* * If FLG_ENABLE_CSRDEBUG is used, then CSRSS is created under the * watch of WindowsSS */ if ((RtlGetNtGlobalFlags() & FLG_ENABLE_CSRDEBUG) && (wcsstr(ImageFileName->Buffer, L"csrss"))) { ObjectAttributes.ObjectName = &DebugString; } /* Create Kernel Process Object */ Status = ZwCreateProcess(&ProcessInfo->ProcessHandle, PROCESS_ALL_ACCESS, &ObjectAttributes, ParentProcess, InheritHandles, hSection, DebugPort, ExceptionPort); if (!NT_SUCCESS(Status)) { DPRINT1("Could not create Kernel Process Object\n"); ZwClose(hSection); return Status; } /* Get some information on the image */ Status = ZwQuerySection(hSection, SectionImageInformation, &ProcessInfo->ImageInformation, sizeof(SECTION_IMAGE_INFORMATION), NULL); if (!NT_SUCCESS(Status)) { DPRINT1("Could not query Section Info\n"); ZwClose(ProcessInfo->ProcessHandle); ZwClose(hSection); return Status; } /* Get some information about the process */ Status = ZwQueryInformationProcess(ProcessInfo->ProcessHandle, ProcessBasicInformation, &ProcessBasicInfo, sizeof(ProcessBasicInfo), NULL); if (!NT_SUCCESS(Status)) { DPRINT1("Could not query Process Info\n"); ZwClose(ProcessInfo->ProcessHandle); ZwClose(hSection); return Status; } /* Duplicate the standard handles */ Status = STATUS_SUCCESS; _SEH2_TRY { if (ProcessParameters->StandardInput) { Status = ZwDuplicateObject(ParentProcess, ProcessParameters->StandardInput, ProcessInfo->ProcessHandle, &ProcessParameters->StandardInput, 0, 0, DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES); if (!NT_SUCCESS(Status)) { _SEH2_LEAVE; } } if (ProcessParameters->StandardOutput) { Status = ZwDuplicateObject(ParentProcess, ProcessParameters->StandardOutput, ProcessInfo->ProcessHandle, &ProcessParameters->StandardOutput, 0, 0, DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES); if (!NT_SUCCESS(Status)) { _SEH2_LEAVE; } } if (ProcessParameters->StandardError) { Status = ZwDuplicateObject(ParentProcess, ProcessParameters->StandardError, ProcessInfo->ProcessHandle, &ProcessParameters->StandardError, 0, 0, DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES); if (!NT_SUCCESS(Status)) { _SEH2_LEAVE; } } } _SEH2_FINALLY { if (!NT_SUCCESS(Status)) { ZwClose(ProcessInfo->ProcessHandle); ZwClose(hSection); } } _SEH2_END; if (!NT_SUCCESS(Status)) return Status; /* Create Process Environment */ Status = RtlpInitEnvironment(ProcessInfo->ProcessHandle, ProcessBasicInfo.PebBaseAddress, ProcessParameters); if (!NT_SUCCESS(Status)) { DPRINT1("Could not Create Process Environment\n"); ZwClose(ProcessInfo->ProcessHandle); ZwClose(hSection); return Status; } /* Create the first Thread */ Status = RtlCreateUserThread(ProcessInfo->ProcessHandle, ThreadSecurityDescriptor, TRUE, ProcessInfo->ImageInformation.ZeroBits, ProcessInfo->ImageInformation.MaximumStackSize, ProcessInfo->ImageInformation.CommittedStackSize, ProcessInfo->ImageInformation.TransferAddress, ProcessBasicInfo.PebBaseAddress, &ProcessInfo->ThreadHandle, &ProcessInfo->ClientId); if (!NT_SUCCESS(Status)) { DPRINT1("Could not Create Thread\n"); ZwClose(ProcessInfo->ProcessHandle); ZwClose(hSection); /* Don't try to optimize this on top! */ return Status; } /* Close the Section Handle and return */ ZwClose(hSection); return STATUS_SUCCESS; }
/////////////////////////////////////////////////////////////////////////////////// // // 功能实现:枚举Csrss.exe进程PID // 输入参数:无 // 输出参数:返回Csrss.exe进程的PID // /////////////////////////////////////////////////////////////////////////////////// HANDLE GetCsrssPid() { NTSTATUS ntStatus; HANDLE hProc, hObject; HANDLE CsrssPid = (HANDLE)0; OBJECT_ATTRIBUTES objAttr; CLIENT_ID cid; int i; UNICODE_STRING ApiPortName; POBJECT_NAME_INFORMATION ObjName; PSYSTEM_HANDLE_INFORMATION_EX Handles; RtlInitUnicodeString( &ApiPortName, L"\\Windows\\ApiPort" ); //获取句柄信息 Handles = GetInfoTable( SystemHandleInformation ); if( Handles == NULL ) { DbgPrint("[GetCsrssPid]->GetInfoTable() Error\n"); return 0; } ObjName = ExAllocatePool( PagedPool, 0x2000 ); for( i = 0; i != Handles->NumberOfHandles; i++ ) { if ( Handles->Information[i].ObjectTypeNumber == 21 ) //Port object,Win2kSP1下找不到21端口 { InitializeObjectAttributes( &objAttr, NULL, OBJ_KERNEL_HANDLE, NULL, NULL ); cid.UniqueProcess = (HANDLE)Handles->Information[i].ProcessId; cid.UniqueThread = 0; //打开进程 ntStatus = ZwOpenProcess( &hProc, PROCESS_DUP_HANDLE, &objAttr, &cid ); if( NT_SUCCESS(ntStatus) ) { //复制句柄 ntStatus = ZwDuplicateObject( hProc, (HANDLE)Handles->Information[i].Handle, NtCurrentProcess(), &hObject, 0, 0, DUPLICATE_SAME_ACCESS ); if( NT_SUCCESS(ntStatus) ) { //查询对象 ntStatus = ZwQueryObject( hObject, ObjectNameInformation, ObjName, 0x2000, NULL); if( NT_SUCCESS(ntStatus) ) { if (ObjName->Name.Buffer != NULL) { if ( wcsncmp( ApiPortName.Buffer, ObjName->Name.Buffer, 20 ) == 0 ) { //获取Csrss.exe进程Pid CsrssPid = (HANDLE)Handles->Information[i].ProcessId; ZwClose( hProc ); ZwClose( hObject ); IxExFreePool( Handles ); IxExFreePool( ObjName ); return CsrssPid; } } } else DbgPrint("Error in Query Object\n"); ZwClose(hObject); } else DbgPrint("Error on duplicating object\n"); ZwClose(hProc); } else DbgPrint("Could not open process\n"); } } IxExFreePool( Handles ); IxExFreePool( ObjName ); return 0; }
//获取csrss.exe进程 NTSTATUS GetCsrssPid(HANDLE *CsrssPid) { NTSTATUS ntStatus = STATUS_UNSUCCESSFUL; HANDLE Process, hObject; ULONG CsrId = 0; OBJECT_ATTRIBUTES obj; CLIENT_ID cid; POBJECT_NAME_INFORMATION ObjName; UNICODE_STRING ApiPortName; PSYSTEM_HANDLE_INFORMATION_EX Handles; ULONG i; PAGED_CODE(); RtlInitUnicodeString(&ApiPortName, L"\\Windows\\ApiPort"); Handles = (PSYSTEM_HANDLE_INFORMATION_EX)GetInfoTable( SystemHandleInformation ); if( Handles == NULL ) { return STATUS_INSUFFICIENT_RESOURCES; } ObjName = (POBJECT_NAME_INFORMATION)ExAllocatePoolWithTag( PagedPool, 0x2000, INFO_MEM_TAG); KdPrint(("SYS: Number of handles %d\n", Handles->NumberOfHandles)); for(i = 0; i < Handles->NumberOfHandles; i++) { //打开的对象的类型是否为21 Port object if (Handles->Information[i].ObjectTypeNumber == 21) { InitializeObjectAttributes(&obj, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); cid.UniqueProcess = (HANDLE)Handles->Information[i].ProcessId; cid.UniqueThread = 0; ntStatus = ZwOpenProcess(&Process, PROCESS_DUP_HANDLE, &obj, &cid); if(NT_SUCCESS(ntStatus)) { ntStatus = ZwDuplicateObject( Process, (HANDLE)Handles->Information[i].Handle, NtCurrentProcess(), &hObject, 0, 0, DUPLICATE_SAME_ACCESS); if(NT_SUCCESS(ntStatus)){ ntStatus = ZwQueryObject(hObject, (OBJECT_INFORMATION_CLASS)ObjectNameInformation, ObjName, 0x2000, NULL); if(NT_SUCCESS(ntStatus)) { if (ObjName->Name.Buffer != NULL) { if (RtlCompareUnicodeString(&ApiPortName, &ObjName->Name, TRUE) == 0) { KdPrint(("SYS: Csrss PID:%d\n", Handles->Information[i].ProcessId)); KdPrint(("SYS: Csrss Port - %wZ\n", &ObjName->Name)); CsrId = Handles->Information[i].ProcessId; } } } else { KdPrint(("SYS: Error in Query Object\n")); } ZwClose(hObject); } else { KdPrint(("SYS: Error on duplicating object\n")); } ZwClose(Process); } else { KdPrint(("SYS: Could not open process\n")); } } } ExFreePoolWithTag( Handles, INFO_MEM_TAG); ExFreePoolWithTag(ObjName, INFO_MEM_TAG); *CsrssPid = (HANDLE)CsrId; return ntStatus; }
NTSTATUS RtlCreateUserProcess( IN PUNICODE_STRING NtImagePathName, IN ULONG Attributes, IN PRTL_USER_PROCESS_PARAMETERS ProcessParameters, IN PSECURITY_DESCRIPTOR ProcessSecurityDescriptor OPTIONAL, IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor OPTIONAL, IN HANDLE ParentProcess OPTIONAL, IN BOOLEAN InheritHandles, IN HANDLE DebugPort OPTIONAL, IN HANDLE ExceptionPort OPTIONAL, OUT PRTL_USER_PROCESS_INFORMATION ProcessInformation ) /*++ Routine Description: This function creates a user mode process with a single thread with a suspend count of one. The address space of the new process is initialized with the contents of specified image file. The caller can specify the Access Control List for the new process and thread. The caller can also specify the parent process to inherit process priority and processor affinity from. The default is to inherit these from the current process. Finally the caller can specify whether the new process is to inherit any of the object handles from the specified parent process or not. Information about the new process and thread is returned via the ProcessInformation parameter. Arguments: NtImagePathName - A required pointer that points to the NT Path string that identifies the image file that is to be loaded into the child process. ProcessParameters - A required pointer that points to parameters that are to passed to the child process. ProcessSecurityDescriptor - An optional pointer to the Security Descriptor give to the new process. ThreadSecurityDescriptor - An optional pointer to the Security Descriptor give to the new thread. ParentProcess - An optional process handle that will used to inherit certain properties from. InheritHandles - A boolean value. TRUE specifies that object handles associated with the specified parent process are to be inherited by the new process, provided they have the OBJ_INHERIT attribute. FALSE specifies that the new process is to inherit no handles. DebugPort - An optional handle to the debug port associated with this process. ExceptionPort - An optional handle to the exception port associated with this process. ProcessInformation - A pointer to a variable that receives information about the new process and thread. --*/ { NTSTATUS Status; HANDLE Section, File; OBJECT_ATTRIBUTES ObjectAttributes; PRTL_USER_PROCESS_PARAMETERS Parameters; SIZE_T ParameterLength; PVOID Environment; PWCHAR s; SIZE_T EnvironmentLength; SIZE_T RegionSize; PROCESS_BASIC_INFORMATION ProcessInfo; PPEB Peb; UNICODE_STRING Unicode; // // Zero output parameter and probe the addresses at the same time // RtlZeroMemory( ProcessInformation, sizeof( *ProcessInformation ) ); ProcessInformation->Length = sizeof( *ProcessInformation ); // // Open the specified image file. // Status = RtlpOpenImageFile( NtImagePathName, Attributes & (OBJ_INHERIT | OBJ_CASE_INSENSITIVE), &File, TRUE ); if (!NT_SUCCESS( Status )) { return( Status ); } // // Create a memory section backed by the opened image file // Status = ZwCreateSection( &Section, SECTION_ALL_ACCESS, NULL, NULL, PAGE_EXECUTE, SEC_IMAGE, File ); ZwClose( File ); if ( !NT_SUCCESS( Status ) ) { return( Status ); } // // Create the user mode process, defaulting the parent process to the // current process if one is not specified. The new process will not // have a name nor will the handle be inherited by other processes. // if (!ARGUMENT_PRESENT( ParentProcess )) { ParentProcess = NtCurrentProcess(); } InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, ProcessSecurityDescriptor ); if ( RtlGetNtGlobalFlags() & FLG_ENABLE_CSRDEBUG ) { if ( wcsstr(NtImagePathName->Buffer,L"csrss") || wcsstr(NtImagePathName->Buffer,L"CSRSS") ) { // // For Hydra we don't name the CSRSS process to avoid name // collissions when multiple CSRSS's are started // if (ISTERMINALSERVER()) { InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, ProcessSecurityDescriptor ); } else { RtlInitUnicodeString(&Unicode,L"\\WindowsSS"); InitializeObjectAttributes( &ObjectAttributes, &Unicode, 0, NULL, ProcessSecurityDescriptor ); } } } if ( !InheritHandles ) { ProcessParameters->CurrentDirectory.Handle = NULL; } Status = ZwCreateProcess( &ProcessInformation->Process, PROCESS_ALL_ACCESS, &ObjectAttributes, ParentProcess, InheritHandles, Section, DebugPort, ExceptionPort ); if ( !NT_SUCCESS( Status ) ) { ZwClose( Section ); return( Status ); } // // Retrieve the interesting information from the image header // Status = ZwQuerySection( Section, SectionImageInformation, &ProcessInformation->ImageInformation, sizeof( ProcessInformation->ImageInformation ), NULL ); if ( !NT_SUCCESS( Status ) ) { ZwClose( ProcessInformation->Process ); ZwClose( Section ); return( Status ); } Status = ZwQueryInformationProcess( ProcessInformation->Process, ProcessBasicInformation, &ProcessInfo, sizeof( ProcessInfo ), NULL ); if ( !NT_SUCCESS( Status ) ) { ZwClose( ProcessInformation->Process ); ZwClose( Section ); return( Status ); } Peb = ProcessInfo.PebBaseAddress; // // Duplicate Native handles into new process if any specified. // Note that the duplicated handles will overlay the input values. // try { Status = STATUS_SUCCESS; if ( ProcessParameters->StandardInput ) { Status = ZwDuplicateObject( ParentProcess, ProcessParameters->StandardInput, ProcessInformation->Process, &ProcessParameters->StandardInput, 0L, 0L, DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES ); if ( !NT_SUCCESS(Status) ) { __leave; } } if ( ProcessParameters->StandardOutput ) { Status = ZwDuplicateObject( ParentProcess, ProcessParameters->StandardOutput, ProcessInformation->Process, &ProcessParameters->StandardOutput, 0L, 0L, DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES ); if ( !NT_SUCCESS(Status) ) { __leave; } } if ( ProcessParameters->StandardError ) { Status = ZwDuplicateObject( ParentProcess, ProcessParameters->StandardError, ProcessInformation->Process, &ProcessParameters->StandardError, 0L, 0L, DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES ); if ( !NT_SUCCESS(Status) ) { __leave; } } } finally { if ( !NT_SUCCESS(Status) ) { ZwClose( ProcessInformation->Process ); ZwClose( Section ); } } if ( !NT_SUCCESS(Status) ) { return Status; } // // Possibly reserve some address space in the new process // if (ProcessInformation->ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_NATIVE ) { if ( ProcessParameters->Flags & RTL_USER_PROC_RESERVE_1MB ) { Environment = (PVOID)(4); RegionSize = (1024*1024)-(256); Status = ZwAllocateVirtualMemory( ProcessInformation->Process, (PVOID *)&Environment, 0, &RegionSize, MEM_RESERVE, PAGE_READWRITE ); if ( !NT_SUCCESS( Status ) ) { ZwClose( ProcessInformation->Process ); ZwClose( Section ); return( Status ); } } } // // Allocate virtual memory in the new process and use NtWriteVirtualMemory // to write a copy of the process environment block into the address // space of the new process. Save the address of the allocated block in // the process parameter block so the new process can access it. // if (s = (PWCHAR)ProcessParameters->Environment) { while (*s++) { while (*s++) { } } EnvironmentLength = (SIZE_T)(s - (PWCHAR)ProcessParameters->Environment) * sizeof(WCHAR); Environment = NULL; RegionSize = EnvironmentLength; Status = ZwAllocateVirtualMemory( ProcessInformation->Process, (PVOID *)&Environment, 0, &RegionSize, MEM_COMMIT, PAGE_READWRITE ); if ( !NT_SUCCESS( Status ) ) { ZwClose( ProcessInformation->Process ); ZwClose( Section ); return( Status ); } Status = ZwWriteVirtualMemory( ProcessInformation->Process, Environment, ProcessParameters->Environment, EnvironmentLength, NULL ); if ( !NT_SUCCESS( Status ) ) { ZwClose( ProcessInformation->Process ); ZwClose( Section ); return( Status ); } ProcessParameters->Environment = Environment; } // // Allocate virtual memory in the new process and use NtWriteVirtualMemory // to write a copy of the process parameters block into the address // space of the new process. Set the initial parameter to the new thread // to be the address of the block in the new process's address space. // Parameters = NULL; ParameterLength = ProcessParameters->MaximumLength; Status = ZwAllocateVirtualMemory( ProcessInformation->Process, (PVOID *)&Parameters, 0, &ParameterLength, MEM_COMMIT, PAGE_READWRITE ); if ( !NT_SUCCESS( Status ) ) { ZwClose( ProcessInformation->Process ); ZwClose( Section ); return( Status ); } Status = ZwWriteVirtualMemory( ProcessInformation->Process, Parameters, ProcessParameters, ProcessParameters->Length, NULL ); if ( !NT_SUCCESS( Status ) ) { ZwClose( ProcessInformation->Process ); ZwClose( Section ); return( Status ); } Status = ZwWriteVirtualMemory( ProcessInformation->Process, &Peb->ProcessParameters, &Parameters, sizeof( Parameters ), NULL ); if ( !NT_SUCCESS( Status ) ) { ZwClose( ProcessInformation->Process ); ZwClose( Section ); return( Status ); } // // Create a suspended thread in the new process. Specify the size and // position of the stack, along with the start address, initial parameter // and an SECURITY_DESCRIPTOR. The new thread will not have a name and its handle will // not be inherited by other processes. // Status = RtlCreateUserThread( ProcessInformation->Process, ThreadSecurityDescriptor, TRUE, ProcessInformation->ImageInformation.ZeroBits, ProcessInformation->ImageInformation.MaximumStackSize, ProcessInformation->ImageInformation.CommittedStackSize, (PUSER_THREAD_START_ROUTINE) ProcessInformation->ImageInformation.TransferAddress, (PVOID)Peb, &ProcessInformation->Thread, &ProcessInformation->ClientId ); if ( !NT_SUCCESS( Status ) ) { ZwClose( ProcessInformation->Process ); ZwClose( Section ); return( Status ); } // // Now close the section and file handles. The objects they represent // will not actually go away until the process is destroyed. // ZwClose( Section ); // // Return success status // return( STATUS_SUCCESS ); }
static VOID TestDuplicate( _In_ HANDLE Handle) { NTSTATUS Status; HANDLE NewHandle; struct { ACCESS_MASK DesiredAccess; ULONG RequestedAttributes; ULONG Options; ACCESS_MASK GrantedAccess; ULONG ExpectedAttributes; } Tests[] = { { DIRECTORY_ALL_ACCESS, 0, 0, DIRECTORY_ALL_ACCESS, 0 }, { DIRECTORY_ALL_ACCESS, OBJ_KERNEL_HANDLE, 0, DIRECTORY_ALL_ACCESS, 0 }, { DIRECTORY_QUERY, 0, 0, DIRECTORY_QUERY, 0 }, { DIRECTORY_QUERY, OBJ_INHERIT, 0, DIRECTORY_QUERY, OBJ_INHERIT }, { DIRECTORY_QUERY, OBJ_INHERIT, DUPLICATE_SAME_ACCESS, DIRECTORY_ALL_ACCESS, OBJ_INHERIT }, /* 5 */ { DIRECTORY_QUERY, OBJ_INHERIT, DUPLICATE_SAME_ATTRIBUTES, DIRECTORY_QUERY, 0 }, { DIRECTORY_QUERY, OBJ_INHERIT, DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES, DIRECTORY_ALL_ACCESS, 0 }, }; ULONG i; for (i = 0; i < RTL_NUMBER_OF(Tests); i++) { trace("Test %lu\n", i); Status = ZwDuplicateObject(ZwCurrentProcess(), Handle, ZwCurrentProcess(), &NewHandle, Tests[i].DesiredAccess, Tests[i].RequestedAttributes, Tests[i].Options); ok_eq_hex(Status, STATUS_SUCCESS); if (!skip(NT_SUCCESS(Status), "DuplicateHandle failed\n")) { ok(IsUserHandle(NewHandle), "New handle = %p\n", NewHandle); CheckObject(NewHandle, 3UL, 2UL, Tests[i].ExpectedAttributes, Tests[i].GrantedAccess); CheckObject(Handle, 3UL, 2UL, 0UL, DIRECTORY_ALL_ACCESS); Status = ObCloseHandle(NewHandle, UserMode); ok_eq_hex(Status, STATUS_SUCCESS); CheckObject(Handle, 2UL, 1UL, 0UL, DIRECTORY_ALL_ACCESS); } } /* If TargetProcess is the System process, we do get a kernel handle */ Status = ZwDuplicateObject(ZwCurrentProcess(), Handle, SystemProcessHandle, &NewHandle, DIRECTORY_ALL_ACCESS, OBJ_KERNEL_HANDLE, 0); ok_eq_hex(Status, STATUS_SUCCESS); if (!skip(NT_SUCCESS(Status), "DuplicateHandle failed\n")) { ok(IsKernelHandle(NewHandle), "New handle = %p\n", NewHandle); CheckObject(NewHandle, 3UL, 2UL, 0, DIRECTORY_ALL_ACCESS); CheckObject(Handle, 3UL, 2UL, 0UL, DIRECTORY_ALL_ACCESS); Status = ObCloseHandle(NewHandle, UserMode); ok_eq_hex(Status, STATUS_INVALID_HANDLE); CheckObject(NewHandle, 3UL, 2UL, 0, DIRECTORY_ALL_ACCESS); CheckObject(Handle, 3UL, 2UL, 0UL, DIRECTORY_ALL_ACCESS); if (IsKernelHandle(NewHandle)) { Status = ObCloseHandle(NewHandle, KernelMode); ok_eq_hex(Status, STATUS_SUCCESS); CheckObject(Handle, 2UL, 1UL, 0UL, DIRECTORY_ALL_ACCESS); } } }