void test_open_process_param_size( void ) { NTSTATUS r; PVOID p = 0; PCLIENT_ID id; ULONG sz = 0x1000; OBJECT_ATTRIBUTES oa; HANDLE handle = 0, dummy = (void*) 1; r = NtAllocateVirtualMemory(NtCurrentProcess(), &p, 0, &sz, MEM_COMMIT, PAGE_READWRITE); ok( r == STATUS_SUCCESS, "wrong return %08lx\n", r ); memset( &oa, 0, sizeof oa ); id = (p + sz - 4); id->UniqueProcess = dummy; r = NtOpenProcess( &handle, 0, &oa, id ); ok( r == STATUS_ACCESS_VIOLATION, "wrong return %08lx\n", r ); id = (p + sz - 8); id->UniqueProcess = dummy; id->UniqueThread = dummy; r = NtOpenProcess( &handle, 0, &oa, id ); ok( r == STATUS_INVALID_CID, "wrong return %08lx\n", r ); r = NtFreeVirtualMemory(NtCurrentProcess(), &p, &sz, MEM_RELEASE ); ok( r == STATUS_SUCCESS, "wrong return %08lx\n", r ); }
HANDLE WINAPI ProcessIdToHandle(IN DWORD dwProcessId) { NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE Handle; CLIENT_ID ClientId; /* If we don't have a PID, look it up */ if (dwProcessId == MAXDWORD) dwProcessId = (DWORD_PTR)CsrGetProcessId(); /* Open a handle to the process */ ClientId.UniqueThread = NULL; ClientId.UniqueProcess = UlongToHandle(dwProcessId); InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); Status = NtOpenProcess(&Handle, PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ | PROCESS_SUSPEND_RESUME | PROCESS_QUERY_INFORMATION, &ObjectAttributes, &ClientId); if (!NT_SUCCESS(Status)) { /* Fail */ BaseSetLastNTError(Status); return 0; } /* Return the handle */ return Handle; }
void CheckProcessMemory() { UINT_PTR i,j,flag,addr; DWORD len; CLIENT_ID id; OBJECT_ATTRIBUTES oa={0}; HANDLE hProc; BYTE buffer[8]; AcquireLock(); id.UniqueThread=0; oa.uLength=sizeof(oa); for (i=0;i<count;i++) { id.UniqueProcess=(proc_record[i]&0xFFF)<<2; addr=proc_record[i]&~0xFFF; flag=0; if (NT_SUCCESS(NtOpenProcess(&hProc,PROCESS_VM_OPERATION|PROCESS_VM_READ,&oa,&id))) { if (NT_SUCCESS(NtReadVirtualMemory(hProc,(PVOID)addr,buffer,8,&len))) if (memcmp(buffer,normal_routine,4)==0) flag=1; NtClose(hProc); } if (flag==0) { for (j=i;j<count;j++) proc_record[j]=proc_record[j+1]; count--; i--; } } ReleaseLock(); }
HANDLE WINAPI ProcessIdToHandle(IN DWORD dwProcessId) { NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE Handle; CLIENT_ID ClientId; /* If we don't have a PID, look it up */ if (dwProcessId == MAXDWORD) dwProcessId = (DWORD_PTR)CsrGetProcessId(); /* Open a handle to the process */ ClientId.UniqueThread = NULL; ClientId.UniqueProcess = UlongToHandle(dwProcessId); InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); Status = NtOpenProcess(&Handle, PROCESS_ALL_ACCESS, &ObjectAttributes, &ClientId); if (!NT_SUCCESS(Status)) { /* Fail */ SetLastErrorByStatus(Status); return 0; } /* Return the handle */ return Handle; }
/* * @implemented */ HANDLE WINAPI OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId) { NTSTATUS errCode; HANDLE ProcessHandle; OBJECT_ATTRIBUTES ObjectAttributes; CLIENT_ID ClientId; ClientId.UniqueProcess = UlongToHandle(dwProcessId); ClientId.UniqueThread = 0; InitializeObjectAttributes(&ObjectAttributes, NULL, (bInheritHandle ? OBJ_INHERIT : 0), NULL, NULL); errCode = NtOpenProcess(&ProcessHandle, dwDesiredAccess, &ObjectAttributes, &ClientId); if (!NT_SUCCESS(errCode)) { SetLastErrorByStatus(errCode); return NULL; } return ProcessHandle; }
ULONG BaseSrvNlsPreserveSection( IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus) { PBASE_NLS_PRESERVE_SECTION_MSG a = (PBASE_NLS_PRESERVE_SECTION_MSG)&m->u.ApiMessageData; HANDLE hSection = (HANDLE)0; /* section handle */ HANDLE hProcess = (HANDLE)0; /* process handle */ OBJECT_ATTRIBUTES ObjA; /* object attributes structure */ NTSTATUS rc = 0L; /* return code */ /* * Duplicate the section handle for the server. */ InitializeObjectAttributes(&ObjA, NULL, 0, NULL, NULL); rc = NtOpenProcess(&hProcess, PROCESS_DUP_HANDLE, &ObjA, &m->h.ClientId); if (!NT_SUCCESS(rc)) { KdPrint(("NLSAPI (BaseSrv): Could NOT Open Process - %lx.\n", rc)); return (rc); } /* * The hSection value will not be used for anything. However, * it must remain open so that the object remains permanent. */ rc = NtDuplicateObject(hProcess, a->hSection, NtCurrentProcess(), &hSection, 0L, 0L, DUPLICATE_SAME_ACCESS); /* * Return the return value from NtDuplicateObject. */ return (rc); ReplyStatus; // get rid of unreferenced parameter warning message }
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; }
static NTSTATUS LsapCheckLogonProcess(PLSA_API_MSG RequestMsg, PLSAP_LOGON_CONTEXT *LogonContext) { OBJECT_ATTRIBUTES ObjectAttributes; HANDLE ProcessHandle = NULL; PLSAP_LOGON_CONTEXT Context = NULL; NTSTATUS Status; TRACE("LsapCheckLogonProcess(%p)\n", RequestMsg); TRACE("Client ID: %p %p\n", RequestMsg->h.ClientId.UniqueProcess, RequestMsg->h.ClientId.UniqueThread); InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); Status = NtOpenProcess(&ProcessHandle, PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE, &ObjectAttributes, &RequestMsg->h.ClientId); if (!NT_SUCCESS(Status)) { TRACE("NtOpenProcess() failed (Status %lx)\n", Status); return Status; } /* Allocate the logon context */ Context = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LSAP_LOGON_CONTEXT)); if (Context == NULL) { NtClose(ProcessHandle); return STATUS_INSUFFICIENT_RESOURCES; } TRACE("New LogonContext: %p\n", Context); Context->ClientProcessHandle = ProcessHandle; *LogonContext = Context; return STATUS_SUCCESS; }
NTSTATUS WINAPI SafeNtOpenProcess ( PHANDLE ProcessHandle, ACCESS_MASK AccessMask, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId ) { NTSTATUS rc; if (CheckOldFunction(&OldNtOpenProcess)) rc=OldNtOpenProcess(ProcessHandle,AccessMask,ObjectAttributes,ClientId); else rc=NtOpenProcess(ProcessHandle,AccessMask,ObjectAttributes,ClientId); return rc; }
IHFSERVICE DWORD IHFAPI IHF_InjectByPID(DWORD pid, LPWSTR engine) { WCHAR str[0x80]; DWORD s; if (!running) return 0; if (pid == current_process_id) { ConsoleOutput(SelfAttach); return -1; } if (man->GetProcessRecord(pid)) { ConsoleOutput(AlreadyAttach); return -1; } swprintf(str, L"ITH_HOOKMAN_%d", pid); NtClose(IthCreateMutex(str, 0, &s)); if (s) return -1; CLIENT_ID id; OBJECT_ATTRIBUTES oa = {}; HANDLE hProc; id.UniqueProcess = pid; id.UniqueThread = 0; oa.uLength=sizeof(oa); if (!NT_SUCCESS(NtOpenProcess(&hProc, PROCESS_QUERY_INFORMATION| PROCESS_CREATE_THREAD| PROCESS_VM_OPERATION| PROCESS_VM_READ| PROCESS_VM_WRITE, &oa, &id))) { ConsoleOutput(ErrorOpenProcess); return -1; } if (engine == 0) engine = EngineName; DWORD module = Inject(hProc,engine); NtClose(hProc); if (module == -1) return -1; swprintf(str, FormatInject, pid, module); ConsoleOutput(str); return module; }
NTSTATUS openProcByName(PHANDLE pProcess, PUNICODE_STRING pProcName, BOOLEAN useDebugPrivilege) { SYSTEM_PROCESS_INFORMATION procInfo; OBJECT_ATTRIBUTES procAttr; OBJECT_BASIC_INFORMATION processHandleInfo; CLIENT_ID cid; BOOLEAN oldValue; HANDLE pid; NTSTATUS status = STATUS_CACHE_PAGE_LOCKED; ULONG procListSize = 0; ULONGLONG memSize = 0; ULONG obQueryLen = 0; PVOID pProcListHead = NULL; PSYSTEM_PROCESS_INFORMATION pProcEntry = NULL; do { if (!pProcName || !pProcess) { status = STATUS_INVALID_PARAMETER; break; } *pProcess = NULL; ///Since we specify a buffer size of 0 the buffer must overflow for sure even if there was running a ///single process only. If we don't receive the dedicated error, something other has gone wrong ///and we cannot rely on the return length. status = NtQuerySystemInformation(SystemProcessInformation, &procInfo, procListSize, &procListSize); if (STATUS_INFO_LENGTH_MISMATCH != status) break; memSize = PAGE_ROUND_UP(procListSize) + PAGE_SIZE; ///We better allocate one page extra ///since between our "test" call and the real call below ///additional processes might be started. (race condition) status = NtAllocateVirtualMemory(INVALID_HANDLE_VALUE, &pProcListHead, 0, &memSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (status) { pProcListHead = NULL; break; } ///By now, we have allocated a buffer large enough for the complete process list, ///even if some new processes have been started in the mean time. ///Hence, the next call is entirely expected to succeed. procListSize = (ULONG)memSize; status = NtQuerySystemInformation(SystemProcessInformation, pProcListHead, procListSize, &procListSize); if (status) break; pid = NULL; pProcEntry = pProcListHead; ///The list of all system processes is a so called singly linked list. while (pProcEntry->NextEntryOffset) { ///If NextEntryOffset member is NULL, we have reached the list end (tail). pProcEntry = (PSYSTEM_PROCESS_INFORMATION)((PUCHAR)pProcEntry + pProcEntry->NextEntryOffset); //DebugPrint2A("PID: %d, %wZ", pProcEntry->UniqueProcessId, pProcEntry->ImageName); if (0 == RtlCompareUnicodeString(pProcName, &pProcEntry->ImageName, TRUE)) { pid = pProcEntry->UniqueProcessId; break; } } if (!pid) { status = STATUS_OBJECT_NAME_NOT_FOUND; break; } if (useDebugPrivilege) { status = RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &oldValue); if (status){ ///Since we're for some reason supposed to use the SeDebugPrivilege, useDebugPrivilege = FALSE; break; ///we fail deliberately if we can't enable it. } } InitializeObjectAttributes(&procAttr, NULL, 0, NULL, NULL); cid.UniqueThread = (HANDLE)0; cid.UniqueProcess = pid; ///Opening a process for full access might be less suspicious than opening with our real intentions. status = NtOpenProcess(pProcess, PROCESS_ALL_ACCESS, &procAttr, &cid); if (status) { ///Most likely STATUS_ACCESS_DENIED if ///either we didn't specify the useDebugPrivilege flag when opening a cross session process ///or if we tried to open an elevated process while running non-elevated ///or if the process being opened is a so-called "Protected Process". ///In x64 windows, HIPS or AV drivers have the possibility to legally ///receive a notification if a process is about to open a handle to another process. ///In those ObCallback routines they cannot completely deny the opening. ///However, they are able to modify the access masks, so a handle supposed for VM operations still ///will be lacking the PROCESS_VM_XXX rights, for example. If we therefore query the handle rights ///we can still return an appropriate error if wasn't granted the rights we want ///And are not going to fail at first when performing our process operations. *pProcess = NULL; break; } status = NtQueryObject(*pProcess, ObjectBasicInformation, &processHandleInfo, sizeof(OBJECT_BASIC_INFORMATION), &obQueryLen); if (status) ///Not sure if this call ever will fail... break; ///Maybe, HIPS just wanted to deny PROCESS_TERMINATE/PROCESS_SUSPEND right? ///If so, we don't care. We're only interested in VM rights. if (MIN_VM_ACCESS_MASK & ~processHandleInfo.GrantedAccess) { status = STATUS_UNSUCCESSFUL; break; } } while (status); if (status && pProcess) { if (*pProcess) { NtClose(*pProcess); *pProcess = NULL; } } if (pProcListHead) { memSize = 0; NtFreeVirtualMemory(INVALID_HANDLE_VALUE, &pProcListHead, &memSize, MEM_RELEASE); ///We don't need the list anymore. } if (useDebugPrivilege) RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, oldValue, FALSE, &oldValue); ///We don't need the privilege anymore. return status; }
int _cdecl main( int argc, char *argv[] ) { BOOL fShowUsage; PCHAR s, s1; ULONG ProcessId; HANDLE Process, ThreadToResume; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING Unicode; NTSTATUS Status; PRTL_EVENT_LOG EventLog; PRTL_EVENT Event; PRTL_EVENT_ID_INFO EventId; STARTUPINFO StartupInfo; PROCESS_INFORMATION ProcessInformation; PCHAR CommandLine; ULONG EventLogFlags; ULONG EventClassMask; ULONG ProcessCreateFlags; InitializeSymbolPathEnvVar(); VerboseFlag = FALSE; EventClassMask = 0xFFFFFFFF; CommandLine = NULL; ProcessId = 0xFFFFFFFF; fShowUsage = FALSE; ProcessCreateFlags = CREATE_SUSPENDED; while (--argc) { s = *++argv; if (*s == '-' || *s == '/') { while (*++s) { switch( toupper( *s ) ) { case 'M': if (--argc) { s1 = *++argv; if (isalpha( *s1 )) { EventClassMask = 0; while (*s1) { switch( toupper( *s1 ) ) { case 'H': if (isdigit( s1[1] )) { while (isdigit( *++s1 )) { switch (*s1) { case '0': EventClassMask |= RTL_EVENT_CLASS_PROCESS_HEAP ; break; case '1': EventClassMask |= RTL_EVENT_CLASS_PRIVATE_HEAP ; break; case '2': EventClassMask |= RTL_EVENT_CLASS_KERNEL_HEAP ; break; case '3': EventClassMask |= RTL_EVENT_CLASS_GDI_HEAP ; break; case '4': EventClassMask |= RTL_EVENT_CLASS_USER_HEAP ; break; case '5': EventClassMask |= RTL_EVENT_CLASS_CONSOLE_HEAP ; break; case '6': EventClassMask |= RTL_EVENT_CLASS_DESKTOP_HEAP ; break; case '7': EventClassMask |= RTL_EVENT_CLASS_CSR_SHARED_HEAP; break; default: fprintf( stderr, "RESMON: Invalid heap class digit '%c' flag.\n", *s1 ); fShowUsage = TRUE; break; } } s1 -= 1; } else { EventClassMask |= RTL_EVENT_CLASS_HEAP_ALL; } break; case 'O': EventClassMask |= RTL_EVENT_CLASS_OB; break; case 'F': EventClassMask |= RTL_EVENT_CLASS_IO; break; case 'V': EventClassMask |= RTL_EVENT_CLASS_VM; break; case 'P': EventClassMask |= RTL_EVENT_CLASS_PAGE_FAULT; break; case 'T': EventClassMask |= RTL_EVENT_CLASS_TRANSITION_FAULT; break; default: fprintf( stderr, "RESMON: Invalid event class letter '%c' flag.\n", *s1 ); fShowUsage = TRUE; break; } s1 += 1; } } else { Status = RtlCharToInteger( s1, 16, &EventClassMask ); } } else { fprintf( stderr, "RESMON: Missing process id of -%c flag.\n", *s ); fShowUsage = TRUE; } break; case 'P': if (--argc) { s1 = *++argv; ProcessId = atoi( s1 ); } else { fprintf( stderr, "RESMON: Missing process id of -%c flag.\n", *s ); fShowUsage = TRUE; } break; case 'O': EventLogFlags |= RTL_EVENT_LOG_INHERIT; break; case '2': ProcessCreateFlags |= CREATE_NEW_CONSOLE; break; case 'V': VerboseFlag = TRUE; break; case '?': case 'H': fShowUsage = TRUE; break; default: fprintf( stderr, "RESMON: Invalid flag - '%c'\n", *s ); fShowUsage = TRUE; break; } } } else if (fShowUsage) { break; } else if (CommandLine != NULL) { fShowUsage = TRUE; break; } else { CommandLine = s; } } if (fShowUsage) { fprintf( stderr, "usage: RESMON [-h] [-o] [-m EventMask] [-p ProcessId | Command]\n" ); fprintf( stderr, "where: -h - displays this help message.\n" ); fprintf( stderr, " -o - monitor all sub-processes too.\n" ); fprintf( stderr, " -m EventMask - specifies which events to monitor.\n" ); fprintf( stderr, " Default is all events. EventMask\n" ); fprintf( stderr, " consists of one or more letters\n" ); fprintf( stderr, " which stand for the following:\n" ); fprintf( stderr, " H[n] - heap events.\n" ); fprintf( stderr, " 0 - process heap.\n" ); fprintf( stderr, " 1 - private heap.\n" ); fprintf( stderr, " 2 - CSRSS heap.\n" ); fprintf( stderr, " 3 - CSR Port heap.\n" ); fprintf( stderr, " F - file events.\n" ); fprintf( stderr, " O - object events.\n" ); fprintf( stderr, " V - virtual memory events.\n" ); fprintf( stderr, " P - page faults.\n" ); fprintf( stderr, " -p ProcessId - specifies which process to monitor.\n" ); fprintf( stderr, " Default is -1 which is the Windows\n" ); fprintf( stderr, " SubSystem process.\n" ); fprintf( stderr, " Command - if -p is not specified then a command to\n" ); fprintf( stderr, " execute may be specified in quotes.\n" ); return 1; } ThreadToResume = NULL; if (CommandLine != NULL) { RtlZeroMemory( &StartupInfo, sizeof( StartupInfo ) ); StartupInfo.cb = sizeof( StartupInfo ); StartupInfo.lpReserved = NULL; StartupInfo.lpReserved2 = NULL; StartupInfo.lpDesktop = NULL; StartupInfo.lpTitle = CommandLine; StartupInfo.dwX = 0; StartupInfo.dwY = 1; StartupInfo.dwXSize = 100; StartupInfo.dwYSize = 100; StartupInfo.dwFlags = 0;//STARTF_SHELLOVERRIDE; StartupInfo.wShowWindow = SW_SHOWNORMAL; if (!CreateProcess( NULL, CommandLine, NULL, NULL, TRUE, ProcessCreateFlags, NULL, NULL, &StartupInfo, &ProcessInformation ) ) { fprintf( stderr, "RESMON: CreateProcess( %s ) failed - %lu\n", CommandLine, GetLastError() ); return 1; } Process = ProcessInformation.hProcess; ThreadToResume = ProcessInformation.hThread; ProcessId = ProcessInformation.dwProcessId; InitializeImageDebugInformation( LoadSymbolsFilter, Process, TRUE, TRUE ); } else if (ProcessId == 0xFFFFFFFF) { RtlInitUnicodeString( &Unicode, L"\\WindowsSS" ); InitializeObjectAttributes( &ObjectAttributes, &Unicode, 0, NULL, NULL ); Status = NtOpenProcess( &Process, MAXIMUM_ALLOWED, &ObjectAttributes, NULL ); if (!NT_SUCCESS( Status )) { fprintf( stderr, "OpenProcess( %wZ ) failed - %lx\n", &Unicode, Status ); return 1; } InitializeImageDebugInformation( LoadSymbolsFilter, Process, FALSE, TRUE ); } else { Process = OpenProcess( PROCESS_ALL_ACCESS, FALSE, ProcessId ); if (!Process) { fprintf( stderr, "OpenProcess( %ld ) failed - %lx\n", ProcessId, GetLastError() ); return 1; } InitializeImageDebugInformation( LoadSymbolsFilter, Process, FALSE, TRUE ); } Status = RtlCreateEventLog( Process, EventLogFlags, EventClassMask, &EventLog ); CloseHandle( Process ); if (NT_SUCCESS( Status )) { if (ThreadToResume != NULL) { printf( "Monitoring Command '%s'\n", CommandLine ); ResumeThread( ThreadToResume ); CloseHandle( ThreadToResume ); } else if (ProcessId == 0xFFFFFFFF) { printf( "Monitoring Windows SubSystem Process\n" ); } else { printf( "Monitoring Process %d\n", ProcessId ); } printf( " Events to monitor:" ); if (EventClassMask & RTL_EVENT_CLASS_HEAP_ALL) { printf( " Heap(" ); if (EventClassMask & RTL_EVENT_CLASS_PROCESS_HEAP) { printf( " Process" ); } if (EventClassMask & RTL_EVENT_CLASS_PRIVATE_HEAP) { printf( " Private" ); } if (EventClassMask & RTL_EVENT_CLASS_KERNEL_HEAP) { printf( " Kernel" ); } if (EventClassMask & RTL_EVENT_CLASS_GDI_HEAP) { printf( " GDI" ); } if (EventClassMask & RTL_EVENT_CLASS_USER_HEAP) { printf( " User" ); } if (EventClassMask & RTL_EVENT_CLASS_CONSOLE_HEAP) { printf( " Console" ); } if (EventClassMask & RTL_EVENT_CLASS_DESKTOP_HEAP) { printf( " Desktop" ); } if (EventClassMask & RTL_EVENT_CLASS_CSR_SHARED_HEAP) { printf( " CSR Shared" ); } printf( ")" ); } if (EventClassMask & RTL_EVENT_CLASS_OB) { printf( " Object" ); } if (EventClassMask & RTL_EVENT_CLASS_IO) { printf( " File I/O" ); } if (EventClassMask & RTL_EVENT_CLASS_VM) { printf( " Virtual Memory" ); } if (EventClassMask & RTL_EVENT_CLASS_PAGE_FAULT) { printf( " Page Faults" ); } if (EventClassMask & RTL_EVENT_CLASS_TRANSITION_FAULT) { printf( " Transition Page Faults" ); } printf( "\n" ); Event = (PRTL_EVENT)EventBuffer; while (TRUE) { if (EventLog->CountOfClients == 0) { break; } Status = RtlWaitForEvent( EventLog, sizeof( EventBuffer ), Event, &EventId ); if (!NT_SUCCESS( Status )) { fprintf( stderr, "RESMON: RtlWaitForEventFailed - %x\n", Status ); } if (CreateProcessEventId == NULL && !_stricmp( EventId->Name, "CreateProcess" ) ) { CreateProcessEventId = EventId; } else if (ExitProcessEventId == NULL && !_stricmp( EventId->Name, "ExitProcess" ) ) { ExitProcessEventId = EventId; } else if (LoadModuleEventId == NULL && !_stricmp( EventId->Name, "LoadModule" ) ) { LoadModuleEventId = EventId; } else if (UnloadModuleEventId == NULL && !_stricmp( EventId->Name, "UnloadModule" ) ) { UnloadModuleEventId = EventId; } else if (PageFaultEventId == NULL && !_stricmp( EventId->Name, "PageFault" ) ) { PageFaultEventId = EventId; } if (CreateProcessEventId == EventId || LoadModuleEventId == EventId ) { LoadSymbolsForEvent( Event, EventId ); DumpEvent( Event, EventId ); } else if (ExitProcessEventId == EventId) { EventLog->CountOfClients -= 1; DumpEvent( Event, EventId ); UnloadProcessForEvent( Event, EventId ); } else if (UnloadModuleEventId == EventId) { DumpEvent( Event, EventId ); UnloadSymbolsForEvent( Event, EventId ); } else { DumpEvent( Event, EventId ); } } RtlDestroyEventLog( EventLog ); } else { if (ThreadToResume != NULL) { fprintf( stderr, "RESMON: Unable (%x) to monitor Command '%s'\n", Status, CommandLine ); TerminateThread( ThreadToResume, GetLastError() ); CloseHandle( ThreadToResume ); } else { fprintf( stderr, "RESMON: Unable (%x) to monitor Process %d\n", Status, ProcessId ); } } return 0; }
NTSTATUS LsapGetLogonSessionData(IN OUT PLSA_API_MSG RequestMsg) { OBJECT_ATTRIBUTES ObjectAttributes; HANDLE ProcessHandle = NULL; PLSAP_LOGON_SESSION Session; PSECURITY_LOGON_SESSION_DATA LocalSessionData; PVOID ClientBaseAddress = NULL; ULONG Length, MemSize; LPWSTR Ptr; NTSTATUS Status; TRACE("LsapGetLogonSessionData(%p)\n", RequestMsg); TRACE("LogonId: %lx\n", RequestMsg->GetLogonSessionData.Request.LogonId.LowPart); Session = LsapGetLogonSession(&RequestMsg->GetLogonSessionData.Request.LogonId); if (Session == NULL) return STATUS_NO_SUCH_LOGON_SESSION; Length = sizeof(SECURITY_LOGON_SESSION_DATA); /* Session->UserName.MaximumLength + Session->LogonDomain.MaximumLength + Session->AuthenticationPackage.MaximumLength + Session->LogonServer.MaximumLength + Session->DnsDomainName.MaximumLength + Session->Upn.MaximumLength; if (Session->Sid != NULL) RtlLengthSid(Session->Sid); */ TRACE("Length: %lu\n", Length); LocalSessionData = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length); if (LocalSessionData == NULL) return STATUS_INSUFFICIENT_RESOURCES; Ptr = (LPWSTR)((ULONG_PTR)LocalSessionData + sizeof(SECURITY_LOGON_SESSION_DATA)); TRACE("LocalSessionData: %p Ptr: %p\n", LocalSessionData, Ptr); LocalSessionData->Size = sizeof(SECURITY_LOGON_SESSION_DATA); RtlCopyLuid(&LocalSessionData->LogonId, &RequestMsg->GetLogonSessionData.Request.LogonId); InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); Status = NtOpenProcess(&ProcessHandle, PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, &ObjectAttributes, &RequestMsg->h.ClientId); if (!NT_SUCCESS(Status)) { TRACE("NtOpenProcess() failed (Status %lx)\n", Status); goto done; } MemSize = Length; Status = NtAllocateVirtualMemory(ProcessHandle, &ClientBaseAddress, 0, &MemSize, MEM_COMMIT, PAGE_READWRITE); if (!NT_SUCCESS(Status)) { TRACE("NtAllocateVirtualMemory() failed (Status %lx)\n", Status); goto done; } TRACE("MemSize: %lu\n", MemSize); TRACE("ClientBaseAddress: %p\n", ClientBaseAddress); Status = NtWriteVirtualMemory(ProcessHandle, ClientBaseAddress, LocalSessionData, Length, NULL); if (!NT_SUCCESS(Status)) { TRACE("NtWriteVirtualMemory() failed (Status %lx)\n", Status); goto done; } RequestMsg->GetLogonSessionData.Reply.SessionDataBuffer = ClientBaseAddress; done: if (ProcessHandle != NULL) NtClose(ProcessHandle); if (LocalSessionData != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, LocalSessionData); return Status; }
/* * @unimplemented */ NTSTATUS NTAPI RtlQueryProcessDebugInformation(IN ULONG ProcessId, IN ULONG DebugInfoMask, IN OUT PRTL_DEBUG_INFORMATION Buf) { NTSTATUS Status = STATUS_SUCCESS; ULONG Pid = (ULONG)(ULONG_PTR) NtCurrentTeb()->ClientId.UniqueProcess; Buf->Flags = DebugInfoMask; Buf->OffsetFree = sizeof(RTL_DEBUG_INFORMATION); DPRINT("QueryProcessDebugInformation Start\n"); /* Currently ROS can not read-only from kenrel space, and doesn't check for boundaries inside kernel space that are page protected from every one but the kernel. aka page 0 - 2 */ if (ProcessId <= 1) { Status = STATUS_ACCESS_VIOLATION; } else if (Pid == ProcessId) { if (DebugInfoMask & RTL_DEBUG_QUERY_MODULES) { PRTL_PROCESS_MODULES Mp; ULONG ReturnSize = 0; ULONG MSize; Mp = (PRTL_PROCESS_MODULES)((PUCHAR)Buf + Buf->OffsetFree); /* I like this better than the do & while loop. */ Status = LdrQueryProcessModuleInformation(NULL, 0, &ReturnSize); Status = LdrQueryProcessModuleInformation(Mp, ReturnSize , &ReturnSize); if (!NT_SUCCESS(Status)) { return Status; } MSize = Mp->NumberOfModules * (sizeof(RTL_PROCESS_MODULES) + 8); Buf->Modules = Mp; Buf->OffsetFree = Buf->OffsetFree + MSize; } if (DebugInfoMask & RTL_DEBUG_QUERY_HEAPS) { PRTL_PROCESS_HEAPS Hp; ULONG HSize; Hp = (PRTL_PROCESS_HEAPS)((PUCHAR)Buf + Buf->OffsetFree); HSize = sizeof(RTL_PROCESS_HEAPS); if (DebugInfoMask & RTL_DEBUG_QUERY_HEAP_TAGS) { // TODO } if (DebugInfoMask & RTL_DEBUG_QUERY_HEAP_BLOCKS) { // TODO } Buf->Heaps = Hp; Buf->OffsetFree = Buf->OffsetFree + HSize; } if (DebugInfoMask & RTL_DEBUG_QUERY_LOCKS) { PRTL_PROCESS_LOCKS Lp; ULONG LSize; Lp = (PRTL_PROCESS_LOCKS)((PUCHAR)Buf + Buf->OffsetFree); LSize = sizeof(RTL_PROCESS_LOCKS); Buf->Locks = Lp; Buf->OffsetFree = Buf->OffsetFree + LSize; } DPRINT("QueryProcessDebugInformation end \n"); DPRINT("QueryDebugInfo : 0x%lx\n", Buf->OffsetFree); } else { HANDLE hProcess; CLIENT_ID ClientId; OBJECT_ATTRIBUTES ObjectAttributes; Buf->TargetProcessHandle = NtCurrentProcess(); ClientId.UniqueThread = 0; ClientId.UniqueProcess = (HANDLE)(ULONG_PTR)ProcessId; InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); Status = NtOpenProcess(&hProcess, (PROCESS_ALL_ACCESS), &ObjectAttributes, &ClientId ); if (!NT_SUCCESS(Status)) { return Status; } if (DebugInfoMask & RTL_DEBUG_QUERY_MODULES) { PRTL_PROCESS_MODULES Mp; ULONG ReturnSize = 0; ULONG MSize; Mp = (PRTL_PROCESS_MODULES)((PUCHAR)Buf + Buf->OffsetFree); Status = RtlpQueryRemoteProcessModules(hProcess, NULL, 0, &ReturnSize); Status = RtlpQueryRemoteProcessModules(hProcess, Mp, ReturnSize , &ReturnSize); if (!NT_SUCCESS(Status)) { return Status; } MSize = Mp->NumberOfModules * (sizeof(RTL_PROCESS_MODULES) + 8); Buf->Modules = Mp; Buf->OffsetFree = Buf->OffsetFree + MSize; } if (DebugInfoMask & RTL_DEBUG_QUERY_HEAPS) { PRTL_PROCESS_HEAPS Hp; ULONG HSize; Hp = (PRTL_PROCESS_HEAPS)((PUCHAR)Buf + Buf->OffsetFree); HSize = sizeof(RTL_PROCESS_HEAPS); if (DebugInfoMask & RTL_DEBUG_QUERY_HEAP_TAGS) { // TODO } if (DebugInfoMask & RTL_DEBUG_QUERY_HEAP_BLOCKS) { // TODO } Buf->Heaps = Hp; Buf->OffsetFree = Buf->OffsetFree + HSize; } if (DebugInfoMask & RTL_DEBUG_QUERY_LOCKS) { PRTL_PROCESS_LOCKS Lp; ULONG LSize; Lp = (PRTL_PROCESS_LOCKS)((PUCHAR)Buf + Buf->OffsetFree); LSize = sizeof(RTL_PROCESS_LOCKS); Buf->Locks = Lp; Buf->OffsetFree = Buf->OffsetFree + LSize; } DPRINT("QueryProcessDebugInformation end \n"); DPRINT("QueryDebugInfo : 0x%lx\n", Buf->OffsetFree); } return Status; }
NTSTATUS LsapEnumLogonSessions(IN OUT PLSA_API_MSG RequestMsg) { OBJECT_ATTRIBUTES ObjectAttributes; HANDLE ProcessHandle = NULL; PLIST_ENTRY SessionEntry; PLSAP_LOGON_SESSION CurrentSession; PLUID SessionList; ULONG i, Length, MemSize; PVOID ClientBaseAddress = NULL; NTSTATUS Status; TRACE("LsapEnumLogonSessions(%p)\n", RequestMsg); Length = SessionCount * sizeof(LUID); SessionList = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length); if (SessionList == NULL) return STATUS_INSUFFICIENT_RESOURCES; i = 0; SessionEntry = SessionListHead.Flink; while (SessionEntry != &SessionListHead) { CurrentSession = CONTAINING_RECORD(SessionEntry, LSAP_LOGON_SESSION, Entry); RtlCopyLuid(&SessionList[i], &CurrentSession->LogonId); SessionEntry = SessionEntry->Flink; i++; } InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); Status = NtOpenProcess(&ProcessHandle, PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, &ObjectAttributes, &RequestMsg->h.ClientId); if (!NT_SUCCESS(Status)) { TRACE("NtOpenProcess() failed (Status %lx)\n", Status); goto done; } TRACE("Length: %lu\n", Length); MemSize = Length; Status = NtAllocateVirtualMemory(ProcessHandle, &ClientBaseAddress, 0, &MemSize, MEM_COMMIT, PAGE_READWRITE); if (!NT_SUCCESS(Status)) { TRACE("NtAllocateVirtualMemory() failed (Status %lx)\n", Status); goto done; } TRACE("MemSize: %lu\n", MemSize); TRACE("ClientBaseAddress: %p\n", ClientBaseAddress); Status = NtWriteVirtualMemory(ProcessHandle, ClientBaseAddress, SessionList, Length, NULL); if (!NT_SUCCESS(Status)) { TRACE("NtWriteVirtualMemory() failed (Status %lx)\n", Status); goto done; } RequestMsg->EnumLogonSessions.Reply.LogonSessionCount = SessionCount; RequestMsg->EnumLogonSessions.Reply.LogonSessionBuffer = ClientBaseAddress; done: if (ProcessHandle != NULL) NtClose(ProcessHandle); if (SessionList != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, SessionList); return Status; }
NTSTATUS NTAPI SmpExecPgm(IN PSM_API_MSG SmApiMsg, IN PSMP_CLIENT_CONTEXT ClientContext, IN HANDLE SmApiPort) { HANDLE ProcessHandle; NTSTATUS Status; PSM_EXEC_PGM_MSG SmExecPgm; RTL_USER_PROCESS_INFORMATION ProcessInformation; OBJECT_ATTRIBUTES ObjectAttributes; /* Open the client process */ InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); Status = NtOpenProcess(&ProcessHandle, PROCESS_DUP_HANDLE, &ObjectAttributes, &SmApiMsg->h.ClientId); if (!NT_SUCCESS(Status)) { /* Fail */ DPRINT1("SmExecPgm: NtOpenProcess Failed %lx\n", Status); return Status; } /* Copy the process information out of the message */ SmExecPgm = &SmApiMsg->u.ExecPgm; ProcessInformation = SmExecPgm->ProcessInformation; /* Duplicate the process handle */ Status = NtDuplicateObject(ProcessHandle, SmExecPgm->ProcessInformation.ProcessHandle, NtCurrentProcess(), &ProcessInformation.ProcessHandle, PROCESS_ALL_ACCESS, 0, 0); if (!NT_SUCCESS(Status)) { /* Close the handle and fail */ NtClose(ProcessHandle); DPRINT1("SmExecPgm: NtDuplicateObject (Process) Failed %lx\n", Status); return Status; } /* Duplicate the thread handle */ Status = NtDuplicateObject(ProcessHandle, SmExecPgm->ProcessInformation.ThreadHandle, NtCurrentProcess(), &ProcessInformation.ThreadHandle, THREAD_ALL_ACCESS, 0, 0); if (!NT_SUCCESS(Status)) { /* Close both handles and fail */ NtClose(ProcessInformation.ProcessHandle); NtClose(ProcessHandle); DPRINT1("SmExecPgm: NtDuplicateObject (Thread) Failed %lx\n", Status); return Status; } /* Close the process handle and call the internal client API */ NtClose(ProcessHandle); return SmpSbCreateSession(NULL, NULL, &ProcessInformation, 0, SmExecPgm->DebugFlag ? &SmApiMsg->h.ClientId : NULL); }
NTSTATUS NTAPI SmpHandleConnectionRequest(IN HANDLE SmApiPort, IN PSB_API_MSG SbApiMsg) { BOOLEAN Accept = TRUE; HANDLE PortHandle, ProcessHandle; ULONG SessionId; UNICODE_STRING SubsystemPort; SMP_CLIENT_CONTEXT *ClientContext; NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; REMOTE_PORT_VIEW PortView; SECURITY_QUALITY_OF_SERVICE SecurityQos; PSMP_SUBSYSTEM CidSubsystem, TypeSubsystem; /* Initialize QoS data */ SecurityQos.ImpersonationLevel = SecurityIdentification; SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; SecurityQos.EffectiveOnly = TRUE; /* Check if this is SM connecting to itself */ if (SbApiMsg->h.ClientId.UniqueProcess == SmUniqueProcessId) { /* No need to get any handle -- assume session 0 */ ProcessHandle = NULL; SessionId = 0; } else { /* Reference the foreign process */ InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); Status = NtOpenProcess(&ProcessHandle, PROCESS_QUERY_INFORMATION, &ObjectAttributes, &SbApiMsg->h.ClientId); if (!NT_SUCCESS(Status)) Accept = FALSE; /* Get its session ID */ SmpGetProcessMuSessionId(ProcessHandle, &SessionId); } /* See if we already know about the caller's subystem */ CidSubsystem = SmpLocateKnownSubSysByCid(&SbApiMsg->h.ClientId); if ((CidSubsystem) && (Accept)) { /* Check if we already have a subsystem for this kind of image */ TypeSubsystem = SmpLocateKnownSubSysByType(SessionId, SbApiMsg->ConnectionInfo.SubsystemType); if (TypeSubsystem == CidSubsystem) { /* Someone is trying to take control of an existing subsystem, fail */ Accept = FALSE; DPRINT1("SMSS: Connection from SubSystem rejected\n"); DPRINT1("SMSS: Image type already being served\n"); } else { /* Set this image type as the type for this subsystem */ CidSubsystem->ImageType = SbApiMsg->ConnectionInfo.SubsystemType; } /* Drop the reference we had acquired */ if (TypeSubsystem) SmpDereferenceSubsystem(TypeSubsystem); } /* Check if we'll be accepting the connection */ if (Accept) { /* We will, so create a client context for it */ ClientContext = RtlAllocateHeap(SmpHeap, 0, sizeof(SMP_CLIENT_CONTEXT)); if (ClientContext) { ClientContext->ProcessHandle = ProcessHandle; ClientContext->Subsystem = CidSubsystem; ClientContext->dword10 = 0; ClientContext->PortHandle = NULL; } else { /* Failed to allocate a client context, so reject the connection */ DPRINT1("Rejecting connectiond due to lack of memory\n"); Accept = FALSE; } } else { /* Use a bogus context since we're going to reject the message */ ClientContext = (PSMP_CLIENT_CONTEXT)SbApiMsg; } /* Now send the actual accept reply (which could be a rejection) */ PortView.Length = sizeof(PortView); Status = NtAcceptConnectPort(&PortHandle, ClientContext, &SbApiMsg->h, Accept, NULL, &PortView); if (!(Accept) || !(NT_SUCCESS(Status))) { /* Close the process handle, reference the subsystem, and exit */ DPRINT1("Accept failed or rejected: %lx\n", Status); if (ClientContext != (PVOID)SbApiMsg) RtlFreeHeap(SmpHeap, 0, ClientContext); if (ProcessHandle) NtClose(ProcessHandle); if (CidSubsystem) SmpDereferenceSubsystem(CidSubsystem); return Status; } /* Save the port handle now that we've accepted it */ if (ClientContext) ClientContext->PortHandle = PortHandle; if (CidSubsystem) CidSubsystem->PortHandle = PortHandle; /* Complete the port connection */ Status = NtCompleteConnectPort(PortHandle); if ((NT_SUCCESS(Status)) && (CidSubsystem)) { /* This was an actual subsystem, so connect back to it */ SbApiMsg->ConnectionInfo.SbApiPortName[119] = UNICODE_NULL; RtlCreateUnicodeString(&SubsystemPort, SbApiMsg->ConnectionInfo.SbApiPortName); Status = NtConnectPort(&CidSubsystem->SbApiPort, &SubsystemPort, &SecurityQos, NULL, NULL, NULL, NULL, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("SMSS: Connect back to Sb %wZ failed %lx\n", &SubsystemPort, Status); } RtlFreeUnicodeString(&SubsystemPort); /* Now that we're connected, signal the event handle */ NtSetEvent(CidSubsystem->Event, NULL); } else if (CidSubsystem) { /* We failed to complete the connection, so clear the port handle */ DPRINT1("Completing the connection failed: %lx\n", Status); CidSubsystem->PortHandle = NULL; } /* Dereference the subsystem and return the result */ if (CidSubsystem) SmpDereferenceSubsystem(CidSubsystem); return Status; }
ULONG BaseSrvNlsCreateSortSection( IN OUT PCSR_API_MSG m, IN OUT PCSR_REPLY_STATUS ReplyStatus) { PBASE_NLS_CREATE_SORT_SECTION_MSG a = (PBASE_NLS_CREATE_SORT_SECTION_MSG)&m->u.ApiMessageData; HANDLE hNewSec = (HANDLE)0; /* new section handle */ HANDLE hProcess = (HANDLE)0; /* process handle */ OBJECT_ATTRIBUTES ObjA; /* object attributes structure */ NTSTATUS rc = 0L; /* return code */ ULONG pSecurityDescriptor[MAX_PATH_LEN]; /* security descriptor buffer */ PSID pWorldSid; /* ptr to world SID */ /* * Set the handles to null. */ a->hNewSection = NULL; /* * Create the NEW Section for Read and Write access. * Add a ReadOnly security descriptor so that only the * initial creating process may write to the section. */ if (rc = CreateSecurityDescriptor(pSecurityDescriptor, &pWorldSid, GENERIC_READ)) { return (rc); } InitializeObjectAttributes(&ObjA, &(a->SectionName), OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, NULL, pSecurityDescriptor); rc = NtCreateSection(&hNewSec, SECTION_MAP_READ | SECTION_MAP_WRITE, &ObjA, &(a->SectionSize), PAGE_READWRITE, SEC_COMMIT, NULL); /* * Check for error from NtCreateSection. */ if (!NT_SUCCESS(rc)) { /* * If the name has already been created, ignore the error. */ if (rc != STATUS_OBJECT_NAME_COLLISION) { KdPrint(("NLSAPI (BaseSrv): Could NOT Create Section %wZ - %lx.\n", &(a->SectionName), rc)); return (rc); } } /* * Duplicate the new section handle for the client. * The client will map a view of the section and fill in the data. */ InitializeObjectAttributes(&ObjA, NULL, 0, NULL, NULL); rc = NtOpenProcess(&hProcess, PROCESS_DUP_HANDLE, &ObjA, &m->h.ClientId); if (!NT_SUCCESS(rc)) { KdPrint(("NLSAPI (BaseSrv): Could NOT Open Process - %lx.\n", rc)); return (rc); } rc = NtDuplicateObject(NtCurrentProcess(), hNewSec, hProcess, &(a->hNewSection), 0L, 0L, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE); /* * Return the return value from NtDuplicateObject. */ return (rc); ReplyStatus; // get rid of unreferenced parameter warning message }
void test_open_process( void ) { NTSTATUS r; CLIENT_ID id; HANDLE handle, dummy = (void*) 0xf0de; OBJECT_ATTRIBUTES oa; UNICODE_STRING us; r = NtOpenProcess( NULL, 0, NULL, NULL ); ok( r == STATUS_ACCESS_VIOLATION, "wrong return %08lx\n", r ); r = NtOpenProcess( NULL, 0, NULL, &id ); ok( r == STATUS_ACCESS_VIOLATION, "wrong return %08lx\n", r ); id.UniqueProcess = 0; id.UniqueThread = 0; r = NtOpenProcess( &handle, 0, NULL, &id ); ok( r == STATUS_ACCESS_VIOLATION, "wrong return %08lx\n", r ); oa.Length = 0; oa.RootDirectory = 0; oa.ObjectName = 0; oa.Attributes = 0; oa.SecurityDescriptor = 0; oa.SecurityQualityOfService = 0; r = NtOpenProcess( &handle, 0, &oa, &id ); ok( r == STATUS_INVALID_PARAMETER, "wrong return %08lx\n", r ); oa.Length = sizeof oa; r = NtOpenProcess( &handle, 0, &oa, &id ); ok( r == STATUS_INVALID_PARAMETER, "wrong return %08lx\n", r ); us.Buffer = NULL; us.Length = 0; us.MaximumLength = 0; oa.ObjectName = &us; r = NtOpenProcess( &handle, 0, &oa, NULL ); ok( r == STATUS_OBJECT_PATH_SYNTAX_BAD, "wrong return %08lx\n", r ); oa.Length = 0; r = NtOpenProcess( &handle, 0, &oa, NULL ); ok( r == STATUS_INVALID_PARAMETER, "wrong return %08lx\n", r ); id.UniqueProcess = dummy; r = NtOpenProcess( &handle, 0, &oa, &id ); ok( r == STATUS_INVALID_PARAMETER_MIX, "wrong return %08lx\n", r ); oa.ObjectName = NULL; r = NtOpenProcess( &handle, 0, &oa, &id ); ok( r == STATUS_INVALID_PARAMETER, "wrong return %08lx\n", r ); r = NtOpenProcess( &handle, 0, NULL, &id ); ok( r == STATUS_ACCESS_VIOLATION, "wrong return %08lx\n", r ); oa.ObjectName = &us; us.Buffer = L"\\Process\\non-existant"; us.Length = 21*2; r = NtOpenProcess( &handle, 0, &oa, &id ); ok( r == STATUS_INVALID_PARAMETER_MIX, "wrong return %08lx\n", r ); id.UniqueProcess = 0; #if 0 r = NtOpenProcess( &handle, 0, &oa, &id ); ok( r == STATUS_INVALID_PARAMETER_MIX, "wrong return %08lx\n", r ); r = NtOpenProcess( &handle, 0, &oa, NULL ); ok( r == STATUS_OBJECT_PATH_NOT_FOUND, "wrong return %08lx\n", r ); #endif id.UniqueProcess = (void*) 0x10000; id.UniqueThread = (void*) 0x10000; r = NtOpenProcess( &handle, 0, NULL, &id ); ok( r == STATUS_ACCESS_VIOLATION, "wrong return %08lx\n", r ); memset( &oa, 0, sizeof oa ); id.UniqueProcess = dummy; id.UniqueThread = dummy; r = NtOpenProcess( &handle, 0, &oa, &id ); ok( r == STATUS_INVALID_CID, "wrong return %08lx\n", r ); oa.Length = 1; r = NtOpenProcess( &handle, 0, &oa, &id ); ok( r == STATUS_INVALID_CID, "wrong return %08lx\n", r ); oa.Length = sizeof oa; r = NtOpenProcess( &handle, 0, &oa, &id ); ok( r == STATUS_INVALID_CID, "wrong return %08lx\n", r ); id.UniqueProcess = 0; r = NtOpenProcess( &handle, 0, &oa, &id ); ok( r == STATUS_INVALID_CID, "wrong return %08lx\n", r ); oa.ObjectName = &us; r = NtOpenProcess( &handle, 0, &oa, &id ); ok( r == STATUS_INVALID_PARAMETER_MIX, "wrong return %08lx\n", r ); oa.Length = 0; r = NtOpenProcess( &handle, 0, &oa, &id ); ok( r == STATUS_INVALID_PARAMETER_MIX, "wrong return %08lx\n", r ); id.UniqueProcess = 0; id.UniqueThread = 0; r = NtOpenProcess( &handle, 0, &oa, &id ); ok( r == STATUS_INVALID_PARAMETER_MIX, "wrong return %08lx\n", r ); oa.ObjectName = NULL; r = NtOpenProcess( &handle, 0, &oa, &id ); ok( r == STATUS_INVALID_PARAMETER, "wrong return %08lx\n", r ); oa.Length = sizeof oa; r = NtOpenProcess( &handle, 0, &oa, &id ); ok( r == STATUS_INVALID_PARAMETER, "wrong return %08lx\n", r ); r = NtOpenProcess( &handle, PROCESS_DUP_HANDLE, &oa, &id ); ok( r == STATUS_INVALID_PARAMETER, "wrong return %08lx\n", r ); }
VOID NTAPI UserServerHardError( IN PCSR_THREAD ThreadData, IN PHARDERROR_MSG Message) { #if DBG PCSR_PROCESS ProcessData = ThreadData->Process; #endif ULONG_PTR Parameters[MAXIMUM_HARDERROR_PARAMETERS]; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING TextU, CaptionU; NTSTATUS Status; HANDLE hProcess; ULONG Size; /* Default to not handled */ ASSERT(ProcessData != NULL); Message->Response = ResponseNotHandled; /* Make sure we don't have too many parameters */ if (Message->NumberOfParameters > MAXIMUM_HARDERROR_PARAMETERS) Message->NumberOfParameters = MAXIMUM_HARDERROR_PARAMETERS; /* Initialize object attributes */ InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); /* Open client process */ Status = NtOpenProcess(&hProcess, PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, &ObjectAttributes, &Message->h.ClientId); if (!NT_SUCCESS(Status)) { DPRINT1("NtOpenProcess failed with code: %lx\n", Status); return; } /* Capture all string parameters from the process memory */ Status = UserpCaptureStringParameters(Parameters, &Size, Message, hProcess); if (!NT_SUCCESS(Status)) { NtClose(hProcess); return; } /* Format the caption and message box text */ Status = UserpFormatMessages(&TextU, &CaptionU, Parameters, Size, Message, hProcess); /* Cleanup */ UserpFreeStringParameters(Parameters, Message); NtClose(hProcess); if (!NT_SUCCESS(Status)) { return; } /* Display the message box */ Message->Response = UserpMessageBox(TextU.Buffer, CaptionU.Buffer, Message->ValidResponseOptions, (ULONG)Message->Status >> 30); RtlFreeUnicodeString(&TextU); RtlFreeUnicodeString(&CaptionU); return; }