Beispiel #1
1
VOID
GRAPHICS_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer)
{
    PGRAPHICS_SCREEN_BUFFER Buff = (PGRAPHICS_SCREEN_BUFFER)Buffer;

    /*
     * IMPORTANT !! Reinitialize the type so that we don't enter a recursive
     * infinite loop when calling CONSOLE_SCREEN_BUFFER_Destroy.
     */
    Buffer->Header.Type = SCREEN_BUFFER;

    /*
     * Uninitialize the graphics screen buffer
     * in the reverse way we initialized it.
     */
    NtUnmapViewOfSection(Buff->ClientProcess, Buff->ClientBitMap);
    NtUnmapViewOfSection(NtCurrentProcess(), Buff->BitMap);
    NtClose(Buff->hSection);
    NtDuplicateObject(Buff->ClientProcess, Buff->ClientMutex,
                      NULL, NULL, 0, 0, DUPLICATE_CLOSE_SOURCE);
    NtClose(Buff->Mutex);
    ConsoleFreeHeap(Buff->BitMapInfo);

    CONSOLE_SCREEN_BUFFER_Destroy(Buffer);
}
Beispiel #2
0
static NTSTATUS PhpDuplicateHandleFromProcessItem(
    _Out_ PHANDLE NewHandle,
    _In_ ACCESS_MASK DesiredAccess,
    _In_ HANDLE ProcessId,
    _In_ HANDLE Handle
    )
{
    NTSTATUS status;
    HANDLE processHandle;

    if (!NT_SUCCESS(status = PhOpenProcess(
        &processHandle,
        PROCESS_DUP_HANDLE,
        ProcessId
        )))
        return status;

    status = NtDuplicateObject(
        processHandle,
        Handle,
        NtCurrentProcess(),
        NewHandle,
        DesiredAccess,
        0,
        0
        );
    NtClose(processHandle);

    return status;
}
Beispiel #3
0
ULONG
BaseSrvCreateThread(
    IN OUT PCSR_API_MSG m,
    IN OUT PCSR_REPLY_STATUS ReplyStatus
    )
{
    PBASE_CREATETHREAD_MSG a = (PBASE_CREATETHREAD_MSG)&m->u.ApiMessageData;
    HANDLE Thread;
    NTSTATUS Status;
    PCSR_PROCESS Process;
    PCSR_THREAD t;

    t = CSR_SERVER_QUERYCLIENTTHREAD();

    Process = t->Process;
    if (Process->ClientId.UniqueProcess != a->ClientId.UniqueProcess) {
        if ( a->ClientId.UniqueProcess == NtCurrentTeb()->ClientId.UniqueProcess ) {
            return STATUS_SUCCESS;
            }
        Status = CsrLockProcessByClientId( a->ClientId.UniqueProcess,
                                           &Process
                                         );
        if (!NT_SUCCESS( Status )) {
            return( Status );
            }
        }

    //
    // Get handles to the thread local to the
    // Windows server.
    //

    Status = NtDuplicateObject(
                t->Process->ProcessHandle,
                a->ThreadHandle,
                NtCurrentProcess(),
                &Thread,
                0L,
                0L,
                DUPLICATE_SAME_ACCESS
                );
    if ( NT_SUCCESS(Status) ) {
        Status = CsrCreateThread(
                    Process,
                    Thread,
                    &a->ClientId
                    );
        }

    if (Process != t->Process) {
        CsrUnlockProcess( Process );
        }

    return( (ULONG)Status );
    ReplyStatus;    // get rid of unreferenced parameter warning message
}
Beispiel #4
0
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
}
Beispiel #5
0
/*
 * @implemented
 */
BOOL
WINAPI
DuplicateHandle(IN HANDLE hSourceProcessHandle,
                IN HANDLE hSourceHandle,
                IN HANDLE hTargetProcessHandle,
                OUT LPHANDLE lpTargetHandle,
                IN DWORD dwDesiredAccess,
                IN BOOL bInheritHandle,
                IN DWORD dwOptions)
{
    NTSTATUS Status;
    HANDLE hTargetHandle;

    hSourceHandle = TranslateStdHandle(hSourceHandle);

    if ((IsConsoleHandle(hSourceHandle)) &&
        ((hSourceHandle != NtCurrentProcess()) &&
         (hSourceHandle != NtCurrentThread())))
    {
        if ((hSourceProcessHandle != NtCurrentProcess()) &&
            (hTargetProcessHandle != NtCurrentProcess()))
        {
            BaseSetLastNTError(STATUS_INVALID_PARAMETER);
            return FALSE;
        }

        hTargetHandle = DuplicateConsoleHandle(hSourceHandle,
                                               dwDesiredAccess,
                                               bInheritHandle,
                                               dwOptions);
        if (hTargetHandle != INVALID_HANDLE_VALUE)
        {
            if (lpTargetHandle) *lpTargetHandle = hTargetHandle;
            return TRUE;
        }

        return FALSE;
    }

    Status = NtDuplicateObject(hSourceProcessHandle,
                               hSourceHandle,
                               hTargetProcessHandle,
                               lpTargetHandle,
                               dwDesiredAccess,
                               bInheritHandle ? OBJ_INHERIT : 0,
                               dwOptions);
    if (NT_SUCCESS(Status)) return TRUE;

    BaseSetLastNTError(Status);
    return FALSE;
}
Beispiel #6
0
NTSTATUS
BaseSrvNlsConnect(
    PCSR_PROCESS Process,
    PVOID pConnectionInfo,
    PULONG pConnectionInfoLength)
{
    /*
     *  Duplicate the mutant handle.
     */
    return ( NtDuplicateObject(NtCurrentProcess(),
                               hNlsCacheMutant,
                               Process->ProcessHandle,
                               (PHANDLE)pConnectionInfo,
                               SYNCHRONIZE,
                               0L,
                               0L ) );
}
Beispiel #7
0
/*
 * @implemented
 */
BOOL WINAPI DuplicateHandle(HANDLE hSourceProcessHandle,
				HANDLE hSourceHandle,
				HANDLE hTargetProcessHandle,
				LPHANDLE lpTargetHandle,
				DWORD dwDesiredAccess,
				BOOL bInheritHandle,
				DWORD dwOptions)
{
   DWORD SourceProcessId, TargetProcessId;
   NTSTATUS Status;

   hSourceHandle = TranslateStdHandle(hSourceHandle);

   if (IsConsoleHandle(hSourceHandle))
   {
      SourceProcessId = GetProcessId(hSourceProcessHandle);
      TargetProcessId = GetProcessId(hTargetProcessHandle);
      if (!SourceProcessId || !TargetProcessId ||
	  SourceProcessId != TargetProcessId ||
	  SourceProcessId != GetCurrentProcessId())
      {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
      }

      *lpTargetHandle = DuplicateConsoleHandle(hSourceHandle, dwDesiredAccess, bInheritHandle, dwOptions);
      return *lpTargetHandle != INVALID_HANDLE_VALUE;
   }

   Status = NtDuplicateObject(hSourceProcessHandle,
			      hSourceHandle,
			      hTargetProcessHandle,
			      lpTargetHandle,
			      dwDesiredAccess,
			      bInheritHandle ? OBJ_INHERIT : 0,
			      dwOptions);
   if (!NT_SUCCESS(Status))
     {
	SetLastErrorByStatus (Status);
	return FALSE;
     }

   return TRUE;
}
Beispiel #8
0
NTSTATUS NTAPI BaseSrvCreatePairWaitHandles(PHANDLE ServerEvent, PHANDLE ClientEvent)
{
    NTSTATUS Status;

    /* Create the event */
    Status = NtCreateEvent(ServerEvent, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE);
    if (!NT_SUCCESS(Status)) return Status;

    /* Duplicate the event into the client process */
    Status = NtDuplicateObject(NtCurrentProcess(),
                               *ServerEvent,
                               CsrGetClientThread()->Process->ProcessHandle,
                               ClientEvent,
                               0,
                               0,
                               DUPLICATE_SAME_ATTRIBUTES | DUPLICATE_SAME_ACCESS);

    if (!NT_SUCCESS(Status)) NtClose(*ServerEvent);
    return Status;
}
IHFSERVICE DWORD IHFAPI IHF_ActiveDetachProcess(DWORD pid)
{
	DWORD module, engine, dwWrite;
	HANDLE hProc, hThread, hCmd;	
	IO_STATUS_BLOCK ios;
	//man->LockHookman();
	ProcessRecord* pr = man->GetProcessRecord(pid);
	hCmd = man->GetCmdHandleByPID(pid);
	if (pr == 0 || hCmd == 0) return FALSE;
	//hProc = pr->process_handle; //This handle may be closed(thus invalid) during the detach process.
	NtDuplicateObject(NtCurrentProcess(), pr->process_handle, 
		NtCurrentProcess(), &hProc, 0, 0, DUPLICATE_SAME_ACCESS); //Make a copy of the process handle.
	module = pr->module_register;
	if (module == 0) return FALSE;
	engine = pr->engine_register;
	engine &= ~0xFF;
	SendParam sp = {};
	sp.type = 4;
	NtWriteFile(hCmd, 0,0,0, &ios, &sp, sizeof(SendParam),0,0);
	//cmdq->AddRequest(sp, pid);
	dwWrite = 0x1000;
	hThread = IthCreateThread(LdrUnloadDll, engine, hProc);
	if (hThread == 0 || 
		hThread == INVALID_HANDLE_VALUE) return FALSE;
	NtWaitForSingleObject(hThread, 0, 0);
	NtClose(hThread);
	hThread = IthCreateThread(LdrUnloadDll, module, hProc);
	if (hThread == 0 ||
		hThread == INVALID_HANDLE_VALUE) return FALSE;
	NtWaitForSingleObject(hThread, 0, 0);
	//man->UnlockHookman();
	THREAD_BASIC_INFORMATION info;
	NtQueryInformationThread(hThread, ThreadBasicInformation, &info, sizeof(info), 0);					
	NtClose(hThread);
	NtSetEvent(hPipeExist, 0);
	FreeThreadStart(hProc);
	NtClose(hProc);
	dwWrite = 0x1000;
	return info.ExitStatus;
}
Beispiel #10
0
VOID
PropertiesUpdate(
    IN PCONSOLE_INFORMATION Console,
    IN HANDLE hClientSection
    )

/*++

    Updates the console state from information sent by the properties
    dialog box.

--*/

{
    HANDLE hSection;
    ULONG ulViewSize;
    NTSTATUS Status;
    PCONSOLE_STATE_INFO pStateInfo;
    PCONSOLE_PROCESS_HANDLE ProcessHandleRecord;
    PSCREEN_INFORMATION ScreenInfo;
    ULONG FontIndex;
    WINDOWPLACEMENT wp;
    COORD NewSize;

    /*
     * Map the shared memory block handle into our address space.
     */
    ProcessHandleRecord = CONTAINING_RECORD(Console->ProcessHandleList.Blink,
                                            CONSOLE_PROCESS_HANDLE,
                                            ListLink);
    Status = NtDuplicateObject(ProcessHandleRecord->ProcessHandle,
                               hClientSection,
                               NtCurrentProcess(),
                               &hSection,
                               0,
                               0,
                               DUPLICATE_SAME_ACCESS);
    if (!NT_SUCCESS(Status)) {
        KdPrint(("CONSRV: error %x mapping client handle\n", Status));
        return;
    }

    /*
     * Get a pointer to the shared memory block.
     */
    pStateInfo = NULL;
    ulViewSize = 0;
    Status = NtMapViewOfSection(hSection,
                                NtCurrentProcess(),
                                &pStateInfo,
                                0,
                                0,
                                NULL,
                                &ulViewSize,
                                ViewUnmap,
                                0,
                                PAGE_READONLY);
    if (!NT_SUCCESS(Status)) {
        KdPrint(("CONSRV: error %x mapping view of file\n", Status));
        NtClose(hSection);
        return;
    }

    /*
     * Verify the size of the shared memory block.
     */
    if (ulViewSize < sizeof(CONSOLE_STATE_INFO)) {
        KdPrint(("CONSRV: sizeof(hSection) < sizeof(CONSOLE_STATE_INFO)\n"));
        NtUnmapViewOfSection(NtCurrentProcess(), pStateInfo);
        NtClose(hSection);
        return;
    }

    /*
     * Update the console state from the supplied values.
     */
    ScreenInfo = Console->CurrentScreenBuffer;
    if (!(Console->Flags & CONSOLE_VDM_REGISTERED) &&
        (pStateInfo->ScreenBufferSize.X != ScreenInfo->ScreenBufferSize.X ||
         pStateInfo->ScreenBufferSize.Y != ScreenInfo->ScreenBufferSize.Y)) {
        ResizeScreenBuffer(ScreenInfo,
                           pStateInfo->ScreenBufferSize,
                           TRUE);
    }
    FontIndex = FindCreateFont(pStateInfo->FontFamily,
                               pStateInfo->FaceName,
                               pStateInfo->FontSize,
                               pStateInfo->FontWeight);
    SetScreenBufferFont(ScreenInfo, FontIndex);
    SetCursorInformation(ScreenInfo,
                         pStateInfo->CursorSize,
                         ScreenInfo->BufferInfo.TextInfo.CursorVisible);

    NewSize.X = min(pStateInfo->WindowSize.X, ScreenInfo->MaximumWindowSize.X);
    NewSize.Y = min(pStateInfo->WindowSize.Y, ScreenInfo->MaximumWindowSize.Y);
    if (NewSize.X != CONSOLE_WINDOW_SIZE_X(ScreenInfo) ||
        NewSize.Y != CONSOLE_WINDOW_SIZE_Y(ScreenInfo)) {
        wp.length = sizeof(wp);
        GetWindowPlacement(Console->hWnd, &wp);
        wp.rcNormalPosition.right += (NewSize.X - CONSOLE_WINDOW_SIZE_X(ScreenInfo)) *
                            SCR_FONTSIZE(ScreenInfo).X;
        wp.rcNormalPosition.bottom += (NewSize.Y - CONSOLE_WINDOW_SIZE_Y(ScreenInfo)) *
                             SCR_FONTSIZE(ScreenInfo).Y;
        SetWindowPlacement(Console->hWnd, &wp);
    }

#ifdef i386
    if (FullScreenInitialized) {
        if (pStateInfo->FullScreen == FALSE) {
            if (Console->FullScreenFlags & CONSOLE_FULLSCREEN) {
                ConvertToWindowed(Console);
                ASSERT(!(Console->FullScreenFlags & CONSOLE_FULLSCREEN_HARDWARE));
                Console->FullScreenFlags = 0;

                ChangeDispSettings(Console, Console->hWnd, 0);
            }
        } else {
            if (Console->FullScreenFlags == 0) {
                ConvertToFullScreen(Console);
                Console->FullScreenFlags |= CONSOLE_FULLSCREEN;

                ChangeDispSettings(Console, Console->hWnd, CDS_FULLSCREEN);
            }
        }
    }
#endif
    if (pStateInfo->QuickEdit) {
        Console->Flags |= CONSOLE_QUICK_EDIT_MODE;
    } else {
        Console->Flags &= ~CONSOLE_QUICK_EDIT_MODE;
    }
    if (pStateInfo->AutoPosition) {
        Console->Flags |= CONSOLE_AUTO_POSITION;
    } else {
        Console->Flags &= ~CONSOLE_AUTO_POSITION;
        SetWindowPos(Console->hWnd, NULL,
                        pStateInfo->WindowPosX,
                        pStateInfo->WindowPosY,
                        0, 0, SWP_NOZORDER | SWP_NOSIZE);
    }
    if (Console->InsertMode != pStateInfo->InsertMode) {
        SetCursorMode(ScreenInfo, FALSE);
        Console->InsertMode = pStateInfo->InsertMode;
    }

    RtlCopyMemory(Console->ColorTable,
                  pStateInfo->ColorTable,
                  sizeof(Console->ColorTable));
    SetScreenColors(ScreenInfo,
                    pStateInfo->ScreenAttributes,
                    pStateInfo->PopupAttributes,
                    TRUE);

    Console->CommandHistorySize = pStateInfo->HistoryBufferSize;
    Console->MaxCommandHistories = pStateInfo->NumberOfHistoryBuffers;
    if (pStateInfo->HistoryNoDup) {
        Console->Flags |= CONSOLE_HISTORY_NODUP;
    } else {
        Console->Flags &= ~CONSOLE_HISTORY_NODUP;
    }

    NtUnmapViewOfSection(NtCurrentProcess(), pStateInfo);
    NtClose(hSection);

    return;
}
int wmain(int argc, WCHAR *argv[])
{

	/* Display welcome message */
	printf("handle_monitor %s - Adam Kramer\n", VERSION_NUMBER);

	/* These variables hold configuration options, which can be altered by arguments passed */
	BOOL bIncludeSigned = FALSE;
	BOOL bSuspendProcess = FALSE;
	BOOL bVerbose = FALSE;
	DWORD dNumberCycles = 10;
	DWORD dHandleChangeThreshold = 10;
	DWORD dIterationPause = 1000;

	/* Process arguments */
	if (argc > 1)
	{
		for (int iNumberArgs = 1; iNumberArgs < argc; iNumberArgs++)
		{
			/* /signed - will include signed files in the alerts */
			if (!wcscmp(argv[iNumberArgs], L"/signed"))
			{
				bIncludeSigned = TRUE;
				printf("Info: Will show signed files as well as unsigned\n");
			}
			/* /suspect - will attempt to suspend suspicious processes */
			else if (!wcscmp(argv[iNumberArgs], L"/suspend"))
			{
				bSuspendProcess = TRUE;
				printf("Info: Will attempt to suspend suspicious processes\n");
			}
			/* /verbose - will display details of iterations and hidden results */
			else if (!wcscmp(argv[iNumberArgs], L"/verbose"))
			{
				bVerbose = TRUE;
				printf("Info: Will display verbose status messages\n");
			}
			/* /cycles - allows the user to set cycles completed before analysis */
			else if (WCHAR* wSetCycles = wcsstr(argv[iNumberArgs], L"/cycles="))
			{
				wSetCycles = wcschr(wSetCycles, '=');

				if (!(dNumberCycles = _wtol(++wSetCycles)))
				{
					printf("Error: Invalid /cycles parameter\n");
					return 1;
				}

				printf("Info: Setting number of cycles to %d\n", dNumberCycles);
			}
			/* /threshold - allows the user to set the threshold for minimum number of new handles which are suspicious */
			else if (WCHAR* wSetThreshold = wcsstr(argv[iNumberArgs], L"/threshold="))
			{
				wSetThreshold = wcschr(wSetThreshold, '=');

				if (!(dHandleChangeThreshold = _wtol(++wSetThreshold)))
				{
					printf("Error: Invalid /threshold parameter\n");
					return 1;
				}

				printf("Info: Setting handle threshold to %d\n", dHandleChangeThreshold);
			}
			/* /pause - allows the user to set a pause between cycles (reduce system load, increase window for finding something) */
			else if (WCHAR* wSetPause = wcsstr(argv[iNumberArgs], L"/pause="))
			{
				wSetPause = wcschr(wSetPause, '=');

				dIterationPause = _wtol(++wSetPause);
				printf("Info: Setting pause between cycles to %dms\n", dIterationPause);
			}
		}
		/* End of argument processing */
	}
	else
	{
		/* No argument passed, accordingly display the usage instructions */
		printf("Usage: handle_monitor.exe <optional parameters>\n\n");
		printf("Optional parameters:\n");
		printf("/cycles=X - Set number of cycles before a review [Default: 10]\n");
		printf("/threshold=X - Set suspicion threshold for number of new handles [Default: 10]\n");
		printf("/pause=X - Set pause in milliseconds between cycles [Default: 1000]\n");
		printf("/signed - Include signed executables in review process\n");
		printf("/suspend - Suspend processes identified as suspicious\n");
		printf("/verbose - Display verbose progress messages\n\n");
		printf("Info: No parameters specified, launching monitoring (Ctrl+C to stop)\n");
	}

	/* Import functions manually from NTDLL */
	_NtQuerySystemInformation NtQuerySystemInformation =
		(_NtQuerySystemInformation)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQuerySystemInformation");

	_NtDuplicateObject NtDuplicateObject =
		(_NtDuplicateObject)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtDuplicateObject");

	_NtQueryObject NtQueryObject =
		(_NtQueryObject)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueryObject");

	/* Master loop! - This runs forever until a user presses Ctrl+C */
	for (;;)
	{
		/* Update user that process is starting (if /verbose mode activiated) */
		if (bVerbose)
			printf("Verbose Info: Starting sequence\n");

		/* Variables used for retrieving handles */
		NTSTATUS status;
		ULONG handleInfoSize = 0x10000;
		HANDLE processHandle;
		ULONG i;
		PSYSTEM_HANDLE_INFORMATION handleInfo;

		/* Used in each handle iteration to identify the index in iProcessArray of the specific process */
		int iCurrentProcess_ArrayIndex = -1;

		/* Handle array - PROCESS INDEX / HANDLE NUMBER / TEXT OF HANDLE
			This holds all handles which have been found per process */
		auto cHandleArray = new WCHAR[MAX_PROCESSES][MAX_FILE_HANDLES][MAX_PATH]();
		signed int iProcessArray[MAX_PROCESSES][3] = { 0 };

		/* Set process array to -1, which indicates nothing has been set */
		for (int j = 0; j < (MAX_PROCESSES - 1); j++)
			iProcessArray[j][0] = -1;

		/* Loop dNumberCycles [default: 10] times before analysing result */
		for (unsigned int iCycleCounter = 1; iCycleCounter <= dNumberCycles; iCycleCounter++)
		{
			handleInfoSize = 0x10000;
			handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);

			/* NtQuerySystemInformation won't give us the correct buffer size, so we guess by doubling the buffer size. */
			while ((status = NtQuerySystemInformation(SystemHandleInformation, handleInfo, handleInfoSize, NULL)) == STATUS_INFO_LENGTH_MISMATCH)
				handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2);

			/* NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH. */
			if (!NT_SUCCESS(status))
			{
				printf("NtQuerySystemInformation failed!\n");
				return 1;
			}

			/* Loop for each handle on the system, processing it accordingly... */
			for (i = 0; i < handleInfo->HandleCount; i++)
			{
				SYSTEM_HANDLE handle = handleInfo->Handles[i];
				HANDLE dupHandle = NULL;
				POBJECT_TYPE_INFORMATION objectTypeInfo;

				/* Open a handle to the process associated with the handle */
				if (!(processHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, handle.ProcessId)))
					continue;

				/* Duplicate the handle so we can query it. */
				if (!NT_SUCCESS(NtDuplicateObject(processHandle, (HANDLE)handle.Handle, GetCurrentProcess(), &dupHandle, GENERIC_READ, 0, 0)))
				{
					CloseHandle(processHandle);
					CloseHandle(dupHandle);
					continue;
				}

				/* Query the object type */
				objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000);
				if (!NT_SUCCESS(NtQueryObject(dupHandle, ObjectTypeInformation, objectTypeInfo, 0x1000, NULL)))
				{
					free(objectTypeInfo);
					CloseHandle(processHandle);
					CloseHandle(dupHandle);
					continue;
				}

				/* If it's not a file handle, go to next one (as we're only interested in file handles) */
				if (wcscmp(objectTypeInfo->Name.Buffer, L"File"))
				{
					free(objectTypeInfo);
					CloseHandle(processHandle);
					CloseHandle(dupHandle);
					continue;
				}

				/* Identify the filename from the handle we're looking at */
				WCHAR* wHandleFileName = new WCHAR[MAX_PATH]();

				if (!GetFileNameFromHandle(dupHandle, wHandleFileName))
				{
					free(objectTypeInfo);
					free(wHandleFileName);
					CloseHandle(processHandle);
					CloseHandle(dupHandle);
					continue;
				}

				/* This is where we add our findings to the database */
				iCurrentProcess_ArrayIndex = -1;

				/* Check whether we've already got an entry for the process we're looking at */
				for (int j = 0; j < (MAX_PROCESSES - 1); j++)
					if (iProcessArray[j][PROCESS_ARRAY_INDEX] == handle.ProcessId)
						iCurrentProcess_ArrayIndex = j;

				/* If not, create a new entry for the process associated with the current handle */
				if (iCurrentProcess_ArrayIndex == -1)
					for (int j = 0; j < (MAX_PROCESSES - 1); j++)
						if (iProcessArray[j][PROCESS_ARRAY_INDEX] == -1)
						{
							iProcessArray[j][PROCESS_ARRAY_INDEX] = handle.ProcessId;
							iCurrentProcess_ArrayIndex = j;
							break;
						}

				/* If there's more than MAX_PROCESSES, throw an error
					TODO: Tidy this up, identify number of running processes dynamically and set array size accordingly */
				if (iCurrentProcess_ArrayIndex == -1)
				{
					printf("Error: Too many processes running!\n");
					return 1;
				}

				/* Look through the handle array, to see whether the filename can be found */
				WCHAR cCurrentHandleText[MAX_PATH];
				for (int j = 0; j < (MAX_FILE_HANDLES - 1); j++)
				{
					/* If we hit NULL, there are no more to find, so add ours */
					swprintf_s(cCurrentHandleText, MAX_PATH, L"%ls", wHandleFileName);

					if (!wcscmp(cHandleArray[iCurrentProcess_ArrayIndex][j], L"")){
						wcscpy_s(cHandleArray[iCurrentProcess_ArrayIndex][j], cCurrentHandleText);
						break;
					}
					/* If we find ours, then stop searching */
					else if (!wcscmp(cHandleArray[iCurrentProcess_ArrayIndex][j], cCurrentHandleText))
						break;
				}

				/* If it's the first (or last) cycle, tally how many entries in the handle array for this
					particular process we have so far */

				if (iCycleCounter == 1)
					for (int j = 0; j < (MAX_FILE_HANDLES - 1); j++)
						if (!wcscmp(cHandleArray[iCurrentProcess_ArrayIndex][j], L"")){
							iProcessArray[iCurrentProcess_ArrayIndex][PROCESS_ARRAY_COUNT_START_CYCLE] = (j - 1);
							break;
						}

				if (iCycleCounter == dNumberCycles)
					for (int j = 0; j < (MAX_FILE_HANDLES - 1); j++)
						if (!wcscmp(cHandleArray[iCurrentProcess_ArrayIndex][j], L"")) {
							iProcessArray[iCurrentProcess_ArrayIndex][PROCESS_ARRAY_COUNT_END_CYCLE] = (j - 1);
							break;
						}

				free(objectTypeInfo);
				free(wHandleFileName);
				CloseHandle(dupHandle);
				CloseHandle(processHandle);
			}
			free(handleInfo);

			/* If the iteration pause is not 0, sleep for the requested time [Default: 1000ms] */
			if (dIterationPause)
				Sleep(dIterationPause);

			/* If /verbose active - inform user which cycle we are on */
			if (bVerbose)
				if (iCycleCounter == 1)
					printf("Verbose Info: Completed cycle %d", iCycleCounter);
				else if (iCycleCounter == dNumberCycles)
					printf(" %d\n", iCycleCounter);
				else
					printf(" %d", iCycleCounter);
		}

		/* If /verbose active - inform user we are now starting a review */
		if (bVerbose)
			printf("Verbose Info: Cycles completed, beginning review\n");

		/* Check if any of them met threshold*/
		for (int j = 0; j < (MAX_PROCESSES - 1); j++)
		{
			if (iProcessArray[j][PROCESS_ARRAY_COUNT_END_CYCLE] < iProcessArray[j][PROCESS_ARRAY_COUNT_START_CYCLE])
				continue;

			/* dHandleDelta is the difference between number of handles for a process from first cycle to the last one  */
			DWORD dHandleDelta = (iProcessArray[j][PROCESS_ARRAY_COUNT_END_CYCLE] - iProcessArray[j][PROCESS_ARRAY_COUNT_START_CYCLE]);

			/* Check whether the delta is equal or above the threshold */
			if (dHandleDelta >= dHandleChangeThreshold)
			{
				HANDLE pHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, iProcessArray[j][PROCESS_ARRAY_INDEX]);
				TCHAR tProcessName[MAX_PATH];
				GetModuleFileNameEx(pHandle, 0, tProcessName, MAX_PATH);
				CloseHandle(pHandle);

				/* If we don't want signed, yet it is signed, skip... */
				if (!bIncludeSigned && (is_signed(tProcessName) == 0))
				{
					if (bVerbose)
						wprintf(L"Verbose Info: Skipping alert on %s (%d) despite trigger, as it is signed (use /signed to alert on signed executables too)\n", tProcessName, iProcessArray[j][PROCESS_ARRAY_INDEX]);
					continue;
				}

				/* Inform the user if we have a suspicious process */
				wprintf(L"Alert! Process: %s (%d) has had a suspicious number of handles (%d) created in the last cycle\nNew handles created during this cycle:\n", tProcessName, iProcessArray[j][PROCESS_ARRAY_INDEX], dHandleDelta);

				for (DWORD k = 1; k <= dHandleDelta; k++)
					wprintf(L"%s\n", cHandleArray[j][iProcessArray[j][PROCESS_ARRAY_COUNT_START_CYCLE] + k]);

				if (bSuspendProcess)
				{

					printf("Info: Attempting to suspend process %d\n", iProcessArray[j][PROCESS_ARRAY_INDEX]);

					/* Attach debugger to process (freeze it!)*/
					if (!DebugActiveProcess(iProcessArray[j][PROCESS_ARRAY_INDEX]))
					{
						printf("Info: Could not attach to process %d as a debugger\n", iProcessArray[j][PROCESS_ARRAY_INDEX]);
					}
					else
					{
						DebugSetProcessKillOnExit(FALSE);

						printf("Info: Successfully attached to process %d as debugger\n", iProcessArray[j][PROCESS_ARRAY_INDEX]);
						printf("Info: It will remain frozen until this process is terminated\n");
					}
				}

				printf("------------------------------------------------------------------------------\n");

			}
		}

		if (bVerbose)
			printf("Verbose Info: Review complete\n");

		free(cHandleArray);

	}

	return 0;
}
Beispiel #12
0
VOID
GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
                                BOOL Defaults)
{
    NTSTATUS Status;
    PCONSRV_CONSOLE Console = GuiData->Console;
    PCONSOLE_PROCESS_DATA ProcessData;
    HANDLE hSection = NULL, hClientSection = NULL;
    PVOID ThreadParameter = NULL; // Is either hClientSection or the console window handle,
                                  // depending on whether we display the default settings or
                                  // the settings of a particular console.

    DPRINT("GuiConsoleShowConsoleProperties entered\n");

    if (!ConDrvValidateConsoleUnsafe((PCONSOLE)Console, CONSOLE_RUNNING, TRUE)) return;

    /* Get the console leader process, our client */
    ProcessData = ConSrvGetConsoleLeaderProcess(Console);

    /*
     * Be sure we effectively have a properties dialog routine (that launches
     * the console control panel applet). It resides in kernel32.dll (client).
     */
    if (ProcessData->PropRoutine == NULL) goto Quit;

    /*
     * Create a memory section to be shared with the console control panel applet
     * in the case we are displaying the settings of a particular console.
     * In that case the ThreadParameter is the hClientSection handle.
     * In the case we display the default console parameters, we don't need to
     * create a memory section. We just need to open the applet, and in this case
     * the ThreadParameter is the parent window handle of the applet's window,
     * that is, the console window.
     */
    if (!Defaults)
    {
        PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer;
        LARGE_INTEGER SectionSize;
        ULONG ViewSize = 0;
        PCONSOLE_STATE_INFO pSharedInfo = NULL;

        /*
         * Create a memory section to share with the applet, and map it.
         */
        SectionSize.QuadPart  = sizeof(CONSOLE_STATE_INFO);    // Standard size
        SectionSize.QuadPart += Console->OriginalTitle.Length; // Add the length in bytes of the console title string

        Status = NtCreateSection(&hSection,
                                 SECTION_ALL_ACCESS,
                                 NULL,
                                 &SectionSize,
                                 PAGE_READWRITE,
                                 SEC_COMMIT,
                                 NULL);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("Error: Impossible to create a shared section, Status = 0x%08lx\n", Status);
            goto Quit;
        }

        Status = NtMapViewOfSection(hSection,
                                    NtCurrentProcess(),
                                    (PVOID*)&pSharedInfo,
                                    0,
                                    0,
                                    NULL,
                                    &ViewSize,
                                    ViewUnmap,
                                    0,
                                    PAGE_READWRITE);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("Error: Impossible to map the shared section, Status = 0x%08lx\n", Status);
            goto Quit;
        }


        /*
         * Setup the shared console properties structure.
         */

        /* Store the real size of the structure */
        pSharedInfo->cbSize = SectionSize.QuadPart;

        /*
         * When we setup the settings of a particular console, the parent window
         * of the applet's window is the console window, and it is given via the
         * hWnd member of the shared console info structure.
         */
        pSharedInfo->hWnd = GuiData->hWindow;

        /* Console information */
        pSharedInfo->HistoryBufferSize = Console->HistoryBufferSize;
        pSharedInfo->NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers;
        pSharedInfo->HistoryNoDup = Console->HistoryNoDup;
        pSharedInfo->QuickEdit = Console->QuickEdit;
        pSharedInfo->InsertMode = Console->InsertMode;
        /// pSharedInfo->InputBufferSize = 0;
        pSharedInfo->ScreenBufferSize = ActiveBuffer->ScreenBufferSize;
        pSharedInfo->WindowSize = ActiveBuffer->ViewSize;
        pSharedInfo->CursorSize = ActiveBuffer->CursorInfo.dwSize;
        if (GetType(ActiveBuffer) == TEXTMODE_BUFFER)
        {
            PTEXTMODE_SCREEN_BUFFER Buffer = (PTEXTMODE_SCREEN_BUFFER)ActiveBuffer;

            pSharedInfo->ScreenAttributes = Buffer->ScreenDefaultAttrib;
            pSharedInfo->PopupAttributes  = Buffer->PopupDefaultAttrib;
        }
        else // if (GetType(ActiveBuffer) == GRAPHICS_BUFFER)
        {
            // PGRAPHICS_SCREEN_BUFFER Buffer = (PGRAPHICS_SCREEN_BUFFER)ActiveBuffer;
            DPRINT1("GuiConsoleShowConsoleProperties - Graphics buffer\n");

            // FIXME: Gather defaults from the registry ?
            pSharedInfo->ScreenAttributes = DEFAULT_SCREEN_ATTRIB;
            pSharedInfo->PopupAttributes  = DEFAULT_POPUP_ATTRIB ;
        }
        /// pSharedInfo->CodePage;

        /* GUI Information */
        wcsncpy(pSharedInfo->FaceName, GuiData->GuiInfo.FaceName, LF_FACESIZE);
        pSharedInfo->FaceName[LF_FACESIZE - 1] = UNICODE_NULL;
        pSharedInfo->FontFamily = GuiData->GuiInfo.FontFamily;
        pSharedInfo->FontSize   = GuiData->GuiInfo.FontSize;
        pSharedInfo->FontWeight = GuiData->GuiInfo.FontWeight;
        pSharedInfo->FullScreen = GuiData->GuiInfo.FullScreen;
        pSharedInfo->AutoPosition   = GuiData->GuiInfo.AutoPosition;
        pSharedInfo->WindowPosition = GuiData->GuiInfo.WindowOrigin;

        /* Palette */
        RtlCopyMemory(pSharedInfo->ColorTable,
                      Console->Colors, sizeof(Console->Colors));

        /* Copy the original title of the console and null-terminate it */
        RtlCopyMemory(pSharedInfo->ConsoleTitle,
                      Console->OriginalTitle.Buffer,
                      Console->OriginalTitle.Length);

        pSharedInfo->ConsoleTitle[Console->OriginalTitle.Length / sizeof(WCHAR)] = UNICODE_NULL;


        /* Unmap the view */
        NtUnmapViewOfSection(NtCurrentProcess(), pSharedInfo);

        /* Duplicate the section handle for the client */
        Status = NtDuplicateObject(NtCurrentProcess(),
                                   hSection,
                                   ProcessData->Process->ProcessHandle,
                                   &hClientSection,
                                   0, 0, DUPLICATE_SAME_ACCESS);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("Error: Impossible to duplicate section handle for client, Status = 0x%08lx\n", Status);
            goto Quit;
        }

        /* For the settings of a particular console, use the shared client section handle as the thread parameter */
        ThreadParameter = (PVOID)hClientSection;
    }
    else
    {
        /* For the default settings, use the console window handle as the thread parameter */
        ThreadParameter = (PVOID)GuiData->hWindow;
    }

    /* Start the console control panel applet */
    _SEH2_TRY
    {
        HANDLE Thread = NULL;

        _SEH2_TRY
        {
            Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
                                        ProcessData->PropRoutine,
                                        ThreadParameter, 0, NULL);
            if (NULL == Thread)
            {
                DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
            }
            else
            {
                DPRINT("ProcessData->PropRoutine remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n",
                       ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
            }
        }
        _SEH2_FINALLY
        {
            CloseHandle(Thread);
        }
        _SEH2_END;
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        Status = _SEH2_GetExceptionCode();
        DPRINT1("GuiConsoleShowConsoleProperties - Caught an exception, Status = 0x%08lx\n", Status);
    }
    _SEH2_END;

Quit:
    /* We have finished, close the section handle if any */
    if (hSection) NtClose(hSection);

    LeaveCriticalSection(&Console->Lock);
    return;
}
Beispiel #13
0
VOID
PropertiesDlgShow(
    IN PCONSOLE_INFORMATION Console
    )

/*++

    Displays the properties dialog and updates the window state,
    if necessary.

--*/

{
    HANDLE hSection = NULL;
    HANDLE hClientSection = NULL;
    HANDLE hThread;
    ULONG ulViewSize;
    LARGE_INTEGER li;
    NTSTATUS Status;
    PCONSOLE_STATE_INFO pStateInfo;
    PCONSOLE_PROCESS_HANDLE ProcessHandleRecord;
    PSCREEN_INFORMATION ScreenInfo;
    LPTHREAD_START_ROUTINE MyPropRoutine;

    /*
     * Create a shared memory block.
     */
    li.QuadPart = sizeof(CONSOLE_STATE_INFO) + Console->OriginalTitleLength;
    Status = NtCreateSection(&hSection,
                             SECTION_ALL_ACCESS,
                             NULL,
                             &li,
                             PAGE_READWRITE,
                             SEC_COMMIT,
                             NULL);
    if (!NT_SUCCESS(Status)) {
        KdPrint(("CONSRV: error %x creating file mapping\n", Status));
        return;
    }

    /*
     * Get a pointer to the shared memory block.
     */
    pStateInfo = NULL;
    ulViewSize = 0;
    Status = NtMapViewOfSection(hSection,
                                NtCurrentProcess(),
                                &pStateInfo,
                                0,
                                0,
                                NULL,
                                &ulViewSize,
                                ViewUnmap,
                                0,
                                PAGE_READWRITE);
    if (!NT_SUCCESS(Status)) {
        KdPrint(("CONSRV: error %x mapping view of file\n", Status));
        NtClose(hSection);
        return;
    }

    /*
     * Fill in the shared memory block with the current values.
     */
    ScreenInfo = Console->CurrentScreenBuffer;
    pStateInfo->Length = li.LowPart;
    pStateInfo->ScreenBufferSize = ScreenInfo->ScreenBufferSize;
    pStateInfo->WindowSize.X = CONSOLE_WINDOW_SIZE_X(ScreenInfo);
    pStateInfo->WindowSize.Y = CONSOLE_WINDOW_SIZE_Y(ScreenInfo);
    pStateInfo->WindowPosX = Console->WindowRect.left;
    pStateInfo->WindowPosY = Console->WindowRect.top;
    if (ScreenInfo->Flags & CONSOLE_TEXTMODE_BUFFER) {
        pStateInfo->FontSize = SCR_FONTSIZE(ScreenInfo);
        pStateInfo->FontFamily = SCR_FAMILY(ScreenInfo);
        pStateInfo->FontWeight = SCR_FONTWEIGHT(ScreenInfo);
        wcscpy(pStateInfo->FaceName, SCR_FACENAME(ScreenInfo));
        pStateInfo->CursorSize = ScreenInfo->BufferInfo.TextInfo.CursorSize;
    }
    pStateInfo->FullScreen = Console->FullScreenFlags & CONSOLE_FULLSCREEN;
    pStateInfo->QuickEdit = Console->Flags & CONSOLE_QUICK_EDIT_MODE;
    pStateInfo->AutoPosition = Console->Flags & CONSOLE_AUTO_POSITION;
    pStateInfo->InsertMode = Console->InsertMode;
    pStateInfo->ScreenAttributes = ScreenInfo->Attributes;
    pStateInfo->PopupAttributes = ScreenInfo->PopupAttributes;
    pStateInfo->HistoryBufferSize = Console->CommandHistorySize;
    pStateInfo->NumberOfHistoryBuffers = Console->MaxCommandHistories;
    pStateInfo->HistoryNoDup = Console->Flags & CONSOLE_HISTORY_NODUP;
    RtlCopyMemory(pStateInfo->ColorTable,
                  Console->ColorTable,
                  sizeof(Console->ColorTable));
    pStateInfo->hWnd = Console->hWnd;
    wcscpy(pStateInfo->ConsoleTitle, Console->OriginalTitle);
    NtUnmapViewOfSection(NtCurrentProcess(), pStateInfo);

    /*
     * Map the shared memory block handle into the client side process's
     * address space.
     */
    ProcessHandleRecord = CONTAINING_RECORD(Console->ProcessHandleList.Blink,
                                            CONSOLE_PROCESS_HANDLE,
                                            ListLink);
    Status = NtDuplicateObject(NtCurrentProcess(),
                               hSection,
                               ProcessHandleRecord->ProcessHandle,
                               &hClientSection,
                               0,
                               0,
                               DUPLICATE_SAME_ACCESS);
    if (!NT_SUCCESS(Status)) {
        KdPrint(("CONSRV: error %x mapping handle to client\n", Status));
        NtClose(hSection);
        return;
    }

    /*
     * Get a pointer to the client-side properties routine.
     */
    if (ProcessHandleRecord->PropRoutine) {
        MyPropRoutine = ProcessHandleRecord->PropRoutine;
    } else {
        MyPropRoutine = PropRoutine;
    }

    /*
     * Call back into the client process to spawn the properties dialog.
     */
    UnlockConsole(Console);
    hThread = InternalCreateCallbackThread(ProcessHandleRecord->ProcessHandle,
                                           (DWORD)MyPropRoutine,
                                           (DWORD)hClientSection);
    if (!hThread) {
        KdPrint(("CONSRV: CreateRemoteThread failed %d\n", GetLastError()));
    }
    LockConsole(Console);

    /*
     * Close any open handles and free allocated memory.
     */
    if (hThread)
        NtClose(hThread);
    if (hSection)
        NtClose(hSection);

    return;
}
Beispiel #14
0
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);
}
Beispiel #15
0
/*
 * Function for dealing with the undocumented message and structure used by
 * Windows' console.dll for setting console info.
 * See http://www.catch22.net/sites/default/source/files/setconsoleinfo.c
 * and http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf
 * for more information.
 */
VOID
GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
                     HANDLE hClientSection)
{
    NTSTATUS Status = STATUS_SUCCESS;
    PCONSRV_CONSOLE Console = GuiData->Console;
    PCONSOLE_PROCESS_DATA ProcessData;
    HANDLE hSection = NULL;
    ULONG ViewSize = 0;
    PCONSOLE_STATE_INFO pConInfo = NULL;

    if (!ConDrvValidateConsoleUnsafe((PCONSOLE)Console, CONSOLE_RUNNING, TRUE)) return;

    /* Get the console leader process, our client */
    ProcessData = ConSrvGetConsoleLeaderProcess(Console);

    /* Duplicate the section handle for ourselves */
    Status = NtDuplicateObject(ProcessData->Process->ProcessHandle,
                               hClientSection,
                               NtCurrentProcess(),
                               &hSection,
                               0, 0, DUPLICATE_SAME_ACCESS);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error when mapping client handle, Status = 0x%08lx\n", Status);
        goto Quit;
    }

    /* Get a view of the shared section */
    Status = NtMapViewOfSection(hSection,
                                NtCurrentProcess(),
                                (PVOID*)&pConInfo,
                                0,
                                0,
                                NULL,
                                &ViewSize,
                                ViewUnmap,
                                0,
                                PAGE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error when mapping view of file, Status = 0x%08lx\n", Status);
        goto Quit;
    }

    _SEH2_TRY
    {
        /* Check that the section is well-sized */
        if ( (ViewSize < sizeof(CONSOLE_STATE_INFO)) ||
             (pConInfo->cbSize < sizeof(CONSOLE_STATE_INFO)) )
        {
            DPRINT1("Error: section bad-sized: sizeof(Section) < sizeof(CONSOLE_STATE_INFO)\n");
            Status = STATUS_INVALID_VIEW_SIZE;
            _SEH2_YIELD(goto Quit);
        }

        // TODO: Check that GuiData->hWindow == pConInfo->hWnd

        /* Retrieve terminal informations */

        /* Console information */
#if 0 // FIXME: Things not set
        ConInfo.HistoryBufferSize = pConInfo->HistoryBufferSize;
        ConInfo.NumberOfHistoryBuffers = pConInfo->NumberOfHistoryBuffers;
        ConInfo.HistoryNoDup = !!pConInfo->HistoryNoDup;
        ConInfo.CodePage = pConInfo->CodePage;
#endif

        /*
         * Apply the settings
         */

        /* Set the console informations */
        ConSrvApplyUserSettings(Console, pConInfo);

        /* Set the terminal informations */

        /* Change the font */
        InitFonts(GuiData,
                  pConInfo->FaceName,
                  pConInfo->FontFamily,
                  pConInfo->FontSize,
                  pConInfo->FontWeight);
       // HACK, needed because changing font may change the size of the window
       /**/TermResizeTerminal(Console);/**/

        /* Move the window to the user's values */
        GuiData->GuiInfo.AutoPosition = !!pConInfo->AutoPosition;
        GuiData->GuiInfo.WindowOrigin = pConInfo->WindowPosition;
        GuiConsoleMoveWindow(GuiData);

        InvalidateRect(GuiData->hWindow, NULL, TRUE);

        /*
         * Apply full-screen mode.
         */
        if (!!pConInfo->FullScreen != GuiData->GuiInfo.FullScreen)
        {
            SwitchFullScreen(GuiData, !!pConInfo->FullScreen);
        }

        /*
         * The settings are saved in the registry by console.dll itself, if needed.
         */
        // if (SaveSettings)
        // {
            // GuiConsoleWriteUserSettings(GuiInfo);
        // }

        Status = STATUS_SUCCESS;
    }
Beispiel #16
0
PyObject*
psutil_get_open_files(long pid, HANDLE processHandle)
{
    _NtQuerySystemInformation NtQuerySystemInformation =
        GetLibraryProcAddress("ntdll.dll", "NtQuerySystemInformation");
    _NtDuplicateObject NtDuplicateObject =
        GetLibraryProcAddress("ntdll.dll", "NtDuplicateObject");
    _NtQueryObject NtQueryObject =
        GetLibraryProcAddress("ntdll.dll", "NtQueryObject");

    NTSTATUS                    status;
    PSYSTEM_HANDLE_INFORMATION  handleInfo;
    ULONG                       handleInfoSize = 0x10000;

    ULONG                       i;
    ULONG                       fileNameLength;
    PyObject                    *filesList = Py_BuildValue("[]");
    PyObject                    *arg = NULL;
    PyObject                    *fileFromWchar = NULL;

    if (filesList == NULL)
        return NULL;

    handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);
    if (handleInfo == NULL) {
        Py_DECREF(filesList);
        PyErr_NoMemory();
        return NULL;
    }

    /* NtQuerySystemInformation won't give us the correct buffer size,
       so we guess by doubling the buffer size. */
    while ((status = NtQuerySystemInformation(
        SystemHandleInformation,
        handleInfo,
        handleInfoSize,
        NULL
        )) == STATUS_INFO_LENGTH_MISMATCH)
    {
        handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2);
    }

    /* NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH. */
    if (!NT_SUCCESS(status)) {
        //printf("NtQuerySystemInformation failed!\n");
        Py_DECREF(filesList);
        free(handleInfo);
        return NULL;
    }

    for (i = 0; i < handleInfo->HandleCount; i++)
    {
        SYSTEM_HANDLE            handle = handleInfo->Handles[i];
        HANDLE                   dupHandle = NULL;
        POBJECT_TYPE_INFORMATION objectTypeInfo = NULL;
        PVOID                    objectNameInfo;
        UNICODE_STRING           objectName;
        ULONG                    returnLength;
        fileFromWchar = NULL;
        arg = NULL;

        /* Check if this handle belongs to the PID the user specified. */
        if (handle.ProcessId != pid)
            continue;

        /* Skip handles with the following access codes as the next call
           to NtDuplicateObject() or NtQueryObject() might hang forever. */
        if((handle.GrantedAccess == 0x0012019f)
        || (handle.GrantedAccess == 0x001a019f)
        || (handle.GrantedAccess == 0x00120189)
        || (handle.GrantedAccess == 0x00100000)) {
            continue;
        }

        /* Duplicate the handle so we can query it. */
        if (!NT_SUCCESS(NtDuplicateObject(
            processHandle,
            handle.Handle,
            GetCurrentProcess(),
            &dupHandle,
            0,
            0,
            0
            )))
        {
            //printf("[%#x] Error!\n", handle.Handle);
            continue;
        }

        /* Query the object type. */
        objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000);
        if (!NT_SUCCESS(NtQueryObject(
            dupHandle,
            ObjectTypeInformation,
            objectTypeInfo,
            0x1000,
            NULL
            )))
        {
            //printf("[%#x] Error!\n", handle.Handle);
            free(objectTypeInfo);
            CloseHandle(dupHandle);
            continue;
        }

        objectNameInfo = malloc(0x1000);
        if (!NT_SUCCESS(NtQueryObject(
            dupHandle,
            ObjectNameInformation,
            objectNameInfo,
            0x1000,
            &returnLength
            )))
        {
            /* Reallocate the buffer and try again. */
            objectNameInfo = realloc(objectNameInfo, returnLength);
            if (!NT_SUCCESS(NtQueryObject(
                dupHandle,
                ObjectNameInformation,
                objectNameInfo,
                returnLength,
                NULL
                )))
            {
                /* We have the type name, so just display that.*/
                /*
                printf(
                    "[%#x] %.*S: (could not get name)\n",
                    handle.Handle,
                    objectTypeInfo->Name.Length / 2,
                    objectTypeInfo->Name.Buffer
                    );
                */
                free(objectTypeInfo);
                free(objectNameInfo);
                CloseHandle(dupHandle);
                continue;

            }
        }

        /* Cast our buffer into an UNICODE_STRING. */
        objectName = *(PUNICODE_STRING)objectNameInfo;

        /* Print the information! */
        if (objectName.Length)
        {
            /* The object has a name.  Make sure it is a file otherwise
               ignore it */
            fileNameLength = objectName.Length / 2;
            if (wcscmp(objectTypeInfo->Name.Buffer, L"File") == 0) {
                //printf("%.*S\n", objectName.Length / 2, objectName.Buffer);
                fileFromWchar = PyUnicode_FromWideChar(objectName.Buffer,
                                                       fileNameLength);
                if (fileFromWchar == NULL)
                    goto error_py_fun;
                #if PY_MAJOR_VERSION >= 3
                    arg = Py_BuildValue("N", PyUnicode_AsUTF8String(fileFromWchar));
                #else
                    arg = Py_BuildValue("N", PyUnicode_FromObject(fileFromWchar));
                #endif
                if (!arg)
                    goto error_py_fun;
                Py_XDECREF(fileFromWchar);
                fileFromWchar = NULL;
                if (PyList_Append(filesList, arg))
                    goto error_py_fun;
                Py_XDECREF(arg);
            }
            /*
            printf(
                "[%#x] %.*S: %.*S\n",
                handle.Handle,
                objectTypeInfo->Name.Length / 2,
                objectTypeInfo->Name.Buffer,
                objectName.Length / 2,
                objectName.Buffer
                );
            */
        }
        else
        {
            /* Print something else. */
            /*
            printf(
                "[%#x] %.*S: (unnamed)\n",
                handle.Handle,
                objectTypeInfo->Name.Length / 2,
                objectTypeInfo->Name.Buffer
                );
            */
            ;;
        }
        free(objectTypeInfo);
        free(objectNameInfo);
        CloseHandle(dupHandle);
    }
    free(handleInfo);
    CloseHandle(processHandle);
    return filesList;

error_py_fun:
    Py_XDECREF(arg);
    Py_XDECREF(fileFromWchar);
    Py_DECREF(filesList);
    return NULL;
}
Beispiel #17
0
NTSTATUS PhpGetBestObjectName(
    __in HANDLE ProcessHandle,
    __in HANDLE Handle,
    __in PPH_STRING ObjectName,
    __in PPH_STRING TypeName,
    __out PPH_STRING *BestObjectName
    )
{
    NTSTATUS status;
    PPH_STRING bestObjectName = NULL;
    PPH_GET_CLIENT_ID_NAME handleGetClientIdName;

    if (PhEqualString2(TypeName, L"EtwRegistration", TRUE))
    {
        if (KphIsConnected())
        {
            ETWREG_BASIC_INFORMATION basicInfo;

            status = KphQueryInformationObject(
                ProcessHandle,
                Handle,
                KphObjectEtwRegBasicInformation,
                &basicInfo,
                sizeof(ETWREG_BASIC_INFORMATION),
                NULL
                );

            if (NT_SUCCESS(status))
            {
                static PH_STRINGREF publishersKeyName = PH_STRINGREF_INIT(L"Software\\Microsoft\\Windows\\CurrentVersion\\WINEVT\\Publishers\\");

                PPH_STRING guidString;
                PPH_STRING keyName;
                HANDLE keyHandle;
                PPH_STRING publisherName = NULL;

                guidString = PhFormatGuid(&basicInfo.Guid);

                // We should perform a lookup on the GUID to get the publisher name.

                keyName = PhConcatStringRef2(&publishersKeyName, &guidString->sr);

                if (NT_SUCCESS(PhOpenKey(
                    &keyHandle,
                    KEY_READ,
                    PH_KEY_LOCAL_MACHINE,
                    &keyName->sr,
                    0
                    )))
                {
                    publisherName = PhQueryRegistryString(keyHandle, NULL);

                    if (publisherName && publisherName->Length == 0)
                    {
                        PhDereferenceObject(publisherName);
                        publisherName = NULL;
                    }

                    NtClose(keyHandle);
                }

                PhDereferenceObject(keyName);

                if (publisherName)
                {
                    bestObjectName = publisherName;
                    PhDereferenceObject(guidString);
                }
                else
                {
                    bestObjectName = guidString;
                }
            }
        }
    }
    else if (PhEqualString2(TypeName, L"File", TRUE))
    {
        // Convert the file name to a DOS file name.
        bestObjectName = PhResolveDevicePrefix(ObjectName);

        if (!bestObjectName)
        {
            bestObjectName = ObjectName;
            PhReferenceObject(ObjectName);
        }
    }
    else if (PhEqualString2(TypeName, L"Key", TRUE))
    {
        bestObjectName = PhFormatNativeKeyName(ObjectName);
    }
    else if (PhEqualString2(TypeName, L"Process", TRUE))
    {
        CLIENT_ID clientId;

        clientId.UniqueThread = NULL;

        if (KphIsConnected())
        {
            PROCESS_BASIC_INFORMATION basicInfo;

            status = KphQueryInformationObject(
                ProcessHandle,
                Handle,
                KphObjectProcessBasicInformation,
                &basicInfo,
                sizeof(PROCESS_BASIC_INFORMATION),
                NULL
                );

            if (!NT_SUCCESS(status))
                goto CleanupExit;

            clientId.UniqueProcess = basicInfo.UniqueProcessId;
        }
        else
        {
            HANDLE dupHandle;
            PROCESS_BASIC_INFORMATION basicInfo;

            status = NtDuplicateObject(
                ProcessHandle,
                Handle,
                NtCurrentProcess(),
                &dupHandle,
                ProcessQueryAccess,
                0,
                0
                );

            if (!NT_SUCCESS(status))
                goto CleanupExit;

            status = PhGetProcessBasicInformation(dupHandle, &basicInfo);
            NtClose(dupHandle);

            if (!NT_SUCCESS(status))
                goto CleanupExit;

            clientId.UniqueProcess = basicInfo.UniqueProcessId;
        }

        handleGetClientIdName = PhHandleGetClientIdName;

        if (handleGetClientIdName)
            bestObjectName = handleGetClientIdName(&clientId);
    }
    else if (PhEqualString2(TypeName, L"Thread", TRUE))
    {
        CLIENT_ID clientId;

        if (KphIsConnected())
        {
            THREAD_BASIC_INFORMATION basicInfo;

            status = KphQueryInformationObject(
                ProcessHandle,
                Handle,
                KphObjectThreadBasicInformation,
                &basicInfo,
                sizeof(THREAD_BASIC_INFORMATION),
                NULL
                );

            if (!NT_SUCCESS(status))
                goto CleanupExit;

            clientId = basicInfo.ClientId;
        }
        else
        {
            HANDLE dupHandle;
            THREAD_BASIC_INFORMATION basicInfo;

            status = NtDuplicateObject(
                ProcessHandle,
                Handle,
                NtCurrentProcess(),
                &dupHandle,
                ThreadQueryAccess,
                0,
                0
                );

            if (!NT_SUCCESS(status))
                goto CleanupExit;

            status = PhGetThreadBasicInformation(dupHandle, &basicInfo);
            NtClose(dupHandle);

            if (!NT_SUCCESS(status))
                goto CleanupExit;

            clientId = basicInfo.ClientId;
        }

        handleGetClientIdName = PhHandleGetClientIdName;

        if (handleGetClientIdName)
            bestObjectName = handleGetClientIdName(&clientId);
    }
    else if (PhEqualString2(TypeName, L"TmEn", TRUE))
    {
        HANDLE dupHandle;
        ENLISTMENT_BASIC_INFORMATION basicInfo;

        status = NtDuplicateObject(
            ProcessHandle,
            Handle,
            NtCurrentProcess(),
            &dupHandle,
            ENLISTMENT_QUERY_INFORMATION,
            0,
            0
            );

        if (!NT_SUCCESS(status))
            goto CleanupExit;

        status = PhGetEnlistmentBasicInformation(dupHandle, &basicInfo);
        NtClose(dupHandle);

        if (NT_SUCCESS(status))
        {
            bestObjectName = PhFormatGuid(&basicInfo.EnlistmentId);
        }
    }
    else if (PhEqualString2(TypeName, L"TmRm", TRUE))
    {
        HANDLE dupHandle;
        GUID guid;
        PPH_STRING description;

        status = NtDuplicateObject(
            ProcessHandle,
            Handle,
            NtCurrentProcess(),
            &dupHandle,
            RESOURCEMANAGER_QUERY_INFORMATION,
            0,
            0
            );

        if (!NT_SUCCESS(status))
            goto CleanupExit;

        status = PhGetResourceManagerBasicInformation(
            dupHandle,
            &guid,
            &description
            );
        NtClose(dupHandle);

        if (NT_SUCCESS(status))
        {
            if (!PhIsNullOrEmptyString(description))
            {
                bestObjectName = description;
            }
            else
            {
                bestObjectName = PhFormatGuid(&guid);

                if (description)
                    PhDereferenceObject(description);
            }
        }
    }
    else if (PhEqualString2(TypeName, L"TmTm", TRUE))
    {
        HANDLE dupHandle;
        PPH_STRING logFileName = NULL;
        TRANSACTIONMANAGER_BASIC_INFORMATION basicInfo;

        status = NtDuplicateObject(
            ProcessHandle,
            Handle,
            NtCurrentProcess(),
            &dupHandle,
            TRANSACTIONMANAGER_QUERY_INFORMATION,
            0,
            0
            );

        if (!NT_SUCCESS(status))
            goto CleanupExit;

        status = PhGetTransactionManagerLogFileName(
            dupHandle,
            &logFileName
            );

        if (NT_SUCCESS(status) && !PhIsNullOrEmptyString(logFileName))
        {
            bestObjectName = PhGetFileName(logFileName);
            PhDereferenceObject(logFileName);
        }
        else
        {
            if (logFileName)
                PhDereferenceObject(logFileName);

            status = PhGetTransactionManagerBasicInformation(
                dupHandle,
                &basicInfo
                );

            if (NT_SUCCESS(status))
            {
                bestObjectName = PhFormatGuid(&basicInfo.TmIdentity);
            }
        }

        NtClose(dupHandle);
    }
    else if (PhEqualString2(TypeName, L"TmTx", TRUE))
    {
        HANDLE dupHandle;
        PPH_STRING description = NULL;
        TRANSACTION_BASIC_INFORMATION basicInfo;

        status = NtDuplicateObject(
            ProcessHandle,
            Handle,
            NtCurrentProcess(),
            &dupHandle,
            TRANSACTION_QUERY_INFORMATION,
            0,
            0
            );

        if (!NT_SUCCESS(status))
            goto CleanupExit;

        status = PhGetTransactionPropertiesInformation(
            dupHandle,
            NULL,
            NULL,
            &description
            );

        if (NT_SUCCESS(status) && !PhIsNullOrEmptyString(description))
        {
            bestObjectName = description;
        }
        else
        {
            if (description)
                PhDereferenceObject(description);

            status = PhGetTransactionBasicInformation(
                dupHandle,
                &basicInfo
                );

            if (NT_SUCCESS(status))
            {
                bestObjectName = PhFormatGuid(&basicInfo.TransactionId);
            }
        }

        NtClose(dupHandle);
    }
    else if (PhEqualString2(TypeName, L"Token", TRUE))
    {
        HANDLE dupHandle;
        PTOKEN_USER tokenUser = NULL;
        TOKEN_STATISTICS statistics = { 0 };

        status = NtDuplicateObject(
            ProcessHandle,
            Handle,
            NtCurrentProcess(),
            &dupHandle,
            TOKEN_QUERY,
            0,
            0
            );

        if (!NT_SUCCESS(status))
            goto CleanupExit;

        status = PhGetTokenUser(dupHandle, &tokenUser);
        PhGetTokenStatistics(dupHandle, &statistics);

        if (NT_SUCCESS(status))
        {
            PPH_STRING fullName;

            fullName = PhGetSidFullName(tokenUser->User.Sid, TRUE, NULL);

            if (fullName)
            {
                PH_FORMAT format[3];

                PhInitFormatSR(&format[0], fullName->sr);
                PhInitFormatS(&format[1], L": 0x");
                PhInitFormatX(&format[2], statistics.AuthenticationId.LowPart);

                bestObjectName = PhFormat(format, 3, fullName->Length + 8 + 16);
                PhDereferenceObject(fullName);
            }

            PhFree(tokenUser);
        }

        NtClose(dupHandle);
    }

CleanupExit:

    if (!bestObjectName)
    {
        bestObjectName = ObjectName;
        PhReferenceObject(ObjectName);
    }

    *BestObjectName = bestObjectName;

    return STATUS_SUCCESS;
}
Beispiel #18
0
VOID
GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
                     HANDLE hClientSection,
                     BOOL SaveSettings)
{
    NTSTATUS Status = STATUS_SUCCESS;
    PCONSRV_CONSOLE Console = GuiData->Console;
    PCONSOLE_PROCESS_DATA ProcessData;
    HANDLE hSection = NULL;
    ULONG ViewSize = 0;
    PCONSOLE_PROPS pConInfo = NULL;
    PCONSOLE_INFO  ConInfo  = NULL;
    PTERMINAL_INFO TermInfo = NULL;
    PGUI_CONSOLE_INFO GuiInfo = NULL;

    if (!ConDrvValidateConsoleUnsafe((PCONSOLE)Console, CONSOLE_RUNNING, TRUE)) return;

    /* Get the console leader process, our client */
    ProcessData = ConSrvGetConsoleLeaderProcess(Console);

    /* Duplicate the section handle for ourselves */
    Status = NtDuplicateObject(ProcessData->Process->ProcessHandle,
                               hClientSection,
                               NtCurrentProcess(),
                               &hSection,
                               0, 0, DUPLICATE_SAME_ACCESS);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error when mapping client handle, Status = 0x%08lx\n", Status);
        goto Quit;
    }

    /* Get a view of the shared section */
    Status = NtMapViewOfSection(hSection,
                                NtCurrentProcess(),
                                (PVOID*)&pConInfo,
                                0,
                                0,
                                NULL,
                                &ViewSize,
                                ViewUnmap,
                                0,
                                PAGE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error when mapping view of file, Status = 0x%08lx\n", Status);
        goto Quit;
    }

    _SEH2_TRY
    {
        /* Check that the section is well-sized */
        if ( (ViewSize < sizeof(CONSOLE_PROPS)) ||
             (pConInfo->TerminalInfo.Size != sizeof(GUI_CONSOLE_INFO)) ||
             (ViewSize < sizeof(CONSOLE_PROPS) + pConInfo->TerminalInfo.Size) )
        {
            DPRINT1("Error: section bad-sized: sizeof(Section) < sizeof(CONSOLE_PROPS) + sizeof(Terminal_specific_info)\n");
            Status = STATUS_INVALID_VIEW_SIZE;
            _SEH2_YIELD(goto Quit);
        }

        // TODO: Check that GuiData->hWindow == pConInfo->hConsoleWindow

        /* Retrieve terminal informations */
        ConInfo  = &pConInfo->ci;
        TermInfo = &pConInfo->TerminalInfo;
        GuiInfo  = TermInfo->TermInfo = (PVOID)((ULONG_PTR)pConInfo + (ULONG_PTR)TermInfo->TermInfo);

        /*
         * If we don't set the default parameters,
         * apply them, otherwise just save them.
         */
        if (pConInfo->ShowDefaultParams == FALSE)
        {
            /* Set the console informations */
            ConSrvApplyUserSettings(Console, ConInfo);

            /* Set the terminal informations */

            // memcpy(&GuiData->GuiInfo, GuiInfo, sizeof(GUI_CONSOLE_INFO));

            /* Change the font */
            InitFonts(GuiData,
                      GuiInfo->FaceName,
                      GuiInfo->FontFamily,
                      GuiInfo->FontSize,
                      GuiInfo->FontWeight);
           // HACK, needed because changing font may change the size of the window
           /**/TermResizeTerminal(Console);/**/

            /* Move the window to the user's values */
            GuiData->GuiInfo.AutoPosition = GuiInfo->AutoPosition;
            GuiData->GuiInfo.WindowOrigin = GuiInfo->WindowOrigin;
            GuiConsoleMoveWindow(GuiData);

            InvalidateRect(GuiData->hWindow, NULL, TRUE);

            /*
             * Apply full-screen mode.
             */
            if (GuiInfo->FullScreen != GuiData->GuiInfo.FullScreen)
            {
                SwitchFullScreen(GuiData, GuiInfo->FullScreen);
            }
        }

        /*
         * Save settings if needed
         */
        // FIXME: Do it in the console properties applet ??
        if (SaveSettings)
        {
            DWORD ProcessId = HandleToUlong(ProcessData->Process->ClientId.UniqueProcess);
            ConSrvWriteUserSettings(ConInfo, ProcessId);
            GuiConsoleWriteUserSettings(GuiInfo, ConInfo->ConsoleTitle, ProcessId);
        }

        Status = STATUS_SUCCESS;
    }
Beispiel #19
0
static INT_PTR CALLBACK PhpFindObjectsDlgProc(
    _In_ HWND hwndDlg,
    _In_ UINT uMsg,
    _In_ WPARAM wParam,
    _In_ LPARAM lParam
    )
{
    switch (uMsg)
    {
    case WM_INITDIALOG:
        {
            HWND lvHandle;

            PhCenterWindow(hwndDlg, GetParent(hwndDlg));
            PhFindObjectsListViewHandle = lvHandle = GetDlgItem(hwndDlg, IDC_RESULTS);

            PhInitializeLayoutManager(&WindowLayoutManager, hwndDlg);
            PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_FILTER),
                NULL, PH_ANCHOR_LEFT | PH_ANCHOR_TOP | PH_ANCHOR_RIGHT);
            PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_REGEX),
                NULL, PH_ANCHOR_TOP | PH_ANCHOR_RIGHT);
            PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDOK),
                NULL, PH_ANCHOR_TOP | PH_ANCHOR_RIGHT);
            PhAddLayoutItem(&WindowLayoutManager, lvHandle,
                NULL, PH_ANCHOR_ALL);

            MinimumSize.left = 0;
            MinimumSize.top = 0;
            MinimumSize.right = 150;
            MinimumSize.bottom = 100;
            MapDialogRect(hwndDlg, &MinimumSize);

            PhRegisterDialog(hwndDlg);

            PhLoadWindowPlacementFromSetting(L"FindObjWindowPosition", L"FindObjWindowSize", hwndDlg);

            PhSetListViewStyle(lvHandle, TRUE, TRUE);
            PhSetControlTheme(lvHandle, L"explorer");
            PhAddListViewColumn(lvHandle, 0, 0, 0, LVCFMT_LEFT, 100, L"Process");
            PhAddListViewColumn(lvHandle, 1, 1, 1, LVCFMT_LEFT, 100, L"Type");
            PhAddListViewColumn(lvHandle, 2, 2, 2, LVCFMT_LEFT, 200, L"Name");
            PhAddListViewColumn(lvHandle, 3, 3, 3, LVCFMT_LEFT, 80, L"Handle");

            PhSetExtendedListView(lvHandle);
            ExtendedListView_SetSortFast(lvHandle, TRUE);
            ExtendedListView_SetCompareFunction(lvHandle, 0, PhpObjectProcessCompareFunction);
            ExtendedListView_SetCompareFunction(lvHandle, 1, PhpObjectTypeCompareFunction);
            ExtendedListView_SetCompareFunction(lvHandle, 2, PhpObjectNameCompareFunction);
            ExtendedListView_SetCompareFunction(lvHandle, 3, PhpObjectHandleCompareFunction);
            PhLoadListViewColumnsFromSetting(L"FindObjListViewColumns", lvHandle);

            Button_SetCheck(GetDlgItem(hwndDlg, IDC_REGEX), PhGetIntegerSetting(L"FindObjRegex") ? BST_CHECKED : BST_UNCHECKED);
        }
        break;
    case WM_DESTROY:
        {
            PhSetIntegerSetting(L"FindObjRegex", Button_GetCheck(GetDlgItem(hwndDlg, IDC_REGEX)) == BST_CHECKED);
            PhSaveWindowPlacementToSetting(L"FindObjWindowPosition", L"FindObjWindowSize", hwndDlg);
            PhSaveListViewColumnsToSetting(L"FindObjListViewColumns", PhFindObjectsListViewHandle);
        }
        break;
    case WM_SHOWWINDOW:
        {
            SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDC_FILTER), TRUE);
            Edit_SetSel(GetDlgItem(hwndDlg, IDC_FILTER), 0, -1);
        }
        break;
    case WM_CLOSE:
        {
            ShowWindow(hwndDlg, SW_HIDE);
            // IMPORTANT
            // Set the result to 0 so the default dialog message
            // handler doesn't invoke IDCANCEL, which will send
            // WM_CLOSE, creating an infinite loop.
            SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, 0);
        }
        return TRUE;
    case WM_SETCURSOR:
        {
            if (SearchThreadHandle)
            {
                SetCursor(LoadCursor(NULL, IDC_WAIT));
                SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
                return TRUE;
            }
        }
        break;
    case WM_COMMAND:
        {
            switch (LOWORD(wParam))
            {
            case IDOK:
                {
                    // Don't continue if the user requested cancellation.
                    if (SearchStop)
                        break;

                    if (!SearchThreadHandle)
                    {
                        ULONG i;

                        PhMoveReference(&SearchString, PhGetWindowText(GetDlgItem(hwndDlg, IDC_FILTER)));

                        if (SearchRegexCompiledExpression)
                        {
                            pcre2_code_free(SearchRegexCompiledExpression);
                            SearchRegexCompiledExpression = NULL;
                        }

                        if (SearchRegexMatchData)
                        {
                            pcre2_match_data_free(SearchRegexMatchData);
                            SearchRegexMatchData = NULL;
                        }

                        if (Button_GetCheck(GetDlgItem(hwndDlg, IDC_REGEX)) == BST_CHECKED)
                        {
                            int errorCode;
                            PCRE2_SIZE errorOffset;

                            SearchRegexCompiledExpression = pcre2_compile(
                                SearchString->Buffer,
                                SearchString->Length / sizeof(WCHAR),
                                PCRE2_CASELESS | PCRE2_DOTALL,
                                &errorCode,
                                &errorOffset,
                                NULL
                                );

                            if (!SearchRegexCompiledExpression)
                            {
                                PhShowError(hwndDlg, L"Unable to compile the regular expression: \"%s\" at position %zu.",
                                    PhGetStringOrDefault(PH_AUTO(PhPcre2GetErrorMessage(errorCode)), L"Unknown error"),
                                    errorOffset
                                    );
                                break;
                            }

                            SearchRegexMatchData = pcre2_match_data_create_from_pattern(SearchRegexCompiledExpression, NULL);
                        }

                        // Clean up previous results.

                        ListView_DeleteAllItems(PhFindObjectsListViewHandle);

                        if (SearchResults)
                        {
                            for (i = 0; i < SearchResults->Count; i++)
                            {
                                PPHP_OBJECT_SEARCH_RESULT searchResult = SearchResults->Items[i];

                                PhDereferenceObject(searchResult->TypeName);
                                PhDereferenceObject(searchResult->Name);

                                if (searchResult->ProcessName)
                                    PhDereferenceObject(searchResult->ProcessName);

                                PhFree(searchResult);
                            }

                            PhDereferenceObject(SearchResults);
                        }

                        // Start the search.

                        SearchResults = PhCreateList(128);
                        SearchResultsAddIndex = 0;

                        SearchThreadHandle = PhCreateThread(0, PhpFindObjectsThreadStart, NULL);

                        if (!SearchThreadHandle)
                        {
                            PhClearReference(&SearchResults);
                            break;
                        }

                        SetDlgItemText(hwndDlg, IDOK, L"Cancel");

                        SetCursor(LoadCursor(NULL, IDC_WAIT));
                    }
                    else
                    {
                        SearchStop = TRUE;
                        EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
                    }
                }
                break;
            case IDCANCEL:
                {
                    SendMessage(hwndDlg, WM_CLOSE, 0, 0);
                }
                break;
            case ID_OBJECT_CLOSE:
                {
                    PPHP_OBJECT_SEARCH_RESULT *results;
                    ULONG numberOfResults;
                    ULONG i;

                    PhGetSelectedListViewItemParams(
                        PhFindObjectsListViewHandle,
                        &results,
                        &numberOfResults
                        );

                    if (numberOfResults != 0 && PhShowConfirmMessage(
                        hwndDlg,
                        L"close",
                        numberOfResults == 1 ? L"the selected handle" : L"the selected handles",
                        L"Closing handles may cause system instability and data corruption.",
                        FALSE
                        ))
                    {
                        for (i = 0; i < numberOfResults; i++)
                        {
                            NTSTATUS status;
                            HANDLE processHandle;

                            if (results[i]->ResultType != HandleSearchResult)
                                continue;

                            if (NT_SUCCESS(status = PhOpenProcess(
                                &processHandle,
                                PROCESS_DUP_HANDLE,
                                results[i]->ProcessId
                                )))
                            {
                                if (NT_SUCCESS(status = NtDuplicateObject(
                                    processHandle,
                                    results[i]->Handle,
                                    NULL,
                                    NULL,
                                    0,
                                    0,
                                    DUPLICATE_CLOSE_SOURCE
                                    )))
                                {
                                    PhRemoveListViewItem(PhFindObjectsListViewHandle,
                                        PhFindListViewItemByParam(PhFindObjectsListViewHandle, 0, results[i]));
                                }

                                NtClose(processHandle);
                            }

                            if (!NT_SUCCESS(status))
                            {
                                if (!PhShowContinueStatus(hwndDlg,
                                    PhaFormatString(L"Unable to close \"%s\"", results[i]->Name->Buffer)->Buffer,
                                    status,
                                    0
                                    ))
                                    break;
                            }
                        }
                    }

                    PhFree(results);
                }
                break;
            case ID_HANDLE_OBJECTPROPERTIES1:
            case ID_HANDLE_OBJECTPROPERTIES2:
                {
                    PPHP_OBJECT_SEARCH_RESULT result =
                        PhGetSelectedListViewItemParam(PhFindObjectsListViewHandle);

                    if (result)
                    {
                        PH_HANDLE_ITEM_INFO info;

                        info.ProcessId = result->ProcessId;
                        info.Handle = result->Handle;
                        info.TypeName = result->TypeName;
                        info.BestObjectName = result->Name;

                        if (LOWORD(wParam) == ID_HANDLE_OBJECTPROPERTIES1)
                            PhShowHandleObjectProperties1(hwndDlg, &info);
                        else
                            PhShowHandleObjectProperties2(hwndDlg, &info);
                    }
                }
                break;
            case ID_OBJECT_GOTOOWNINGPROCESS:
                {
                    PPHP_OBJECT_SEARCH_RESULT result =
                        PhGetSelectedListViewItemParam(PhFindObjectsListViewHandle);

                    if (result)
                    {
                        PPH_PROCESS_NODE processNode;

                        if (processNode = PhFindProcessNode(result->ProcessId))
                        {
                            ProcessHacker_SelectTabPage(PhMainWndHandle, 0);
                            ProcessHacker_SelectProcessNode(PhMainWndHandle, processNode);
                            ProcessHacker_ToggleVisible(PhMainWndHandle, TRUE);
                        }
                    }
                }
                break;
            case ID_OBJECT_PROPERTIES:
                {
                    PPHP_OBJECT_SEARCH_RESULT result =
                        PhGetSelectedListViewItemParam(PhFindObjectsListViewHandle);

                    if (result)
                    {
                        if (result->ResultType == HandleSearchResult)
                        {
                            PPH_HANDLE_ITEM handleItem;

                            handleItem = PhCreateHandleItem(&result->Info);

                            handleItem->BestObjectName = handleItem->ObjectName = result->Name;
                            PhReferenceObjectEx(result->Name, 2);

                            handleItem->TypeName = result->TypeName;
                            PhReferenceObject(result->TypeName);

                            PhShowHandleProperties(
                                hwndDlg,
                                result->ProcessId,
                                handleItem
                                );
                            PhDereferenceObject(handleItem);
                        }
                        else
                        {
                            // DLL or Mapped File. Just show file properties.
                            PhShellProperties(hwndDlg, result->Name->Buffer);
                        }
                    }
                }
                break;
            case ID_OBJECT_COPY:
                {
                    PhCopyListView(PhFindObjectsListViewHandle);
                }
                break;
            }
        }
        break;
    case WM_NOTIFY:
        {
            LPNMHDR header = (LPNMHDR)lParam;

            switch (header->code)
            {
            case NM_DBLCLK:
                {
                    if (header->hwndFrom == PhFindObjectsListViewHandle)
                    {
                        SendMessage(hwndDlg, WM_COMMAND, ID_OBJECT_PROPERTIES, 0);
                    }
                }
                break;
            case LVN_KEYDOWN:
                {
                    if (header->hwndFrom == PhFindObjectsListViewHandle)
                    {
                        LPNMLVKEYDOWN keyDown = (LPNMLVKEYDOWN)header;

                        switch (keyDown->wVKey)
                        {
                        case 'C':
                            if (GetKeyState(VK_CONTROL) < 0)
                                SendMessage(hwndDlg, WM_COMMAND, ID_OBJECT_COPY, 0);
                            break;
                        case 'A':
                            if (GetKeyState(VK_CONTROL) < 0)
                                PhSetStateAllListViewItems(PhFindObjectsListViewHandle, LVIS_SELECTED, LVIS_SELECTED);
                            break;
                        case VK_DELETE:
                            SendMessage(hwndDlg, WM_COMMAND, ID_OBJECT_CLOSE, 0);
                            break;
                        }
                    }
                }
                break;
            }
        }
        break;
    case WM_CONTEXTMENU:
        {
            if ((HWND)wParam == PhFindObjectsListViewHandle)
            {
                POINT point;
                PPHP_OBJECT_SEARCH_RESULT *results;
                ULONG numberOfResults;

                point.x = (SHORT)LOWORD(lParam);
                point.y = (SHORT)HIWORD(lParam);

                if (point.x == -1 && point.y == -1)
                    PhGetListViewContextMenuPoint((HWND)wParam, &point);

                PhGetSelectedListViewItemParams(PhFindObjectsListViewHandle, &results, &numberOfResults);

                if (numberOfResults != 0)
                {
                    PPH_EMENU menu;

                    menu = PhCreateEMenu();
                    PhLoadResourceEMenuItem(menu, PhInstanceHandle, MAKEINTRESOURCE(IDR_FINDOBJ), 0);
                    PhSetFlagsEMenuItem(menu, ID_OBJECT_PROPERTIES, PH_EMENU_DEFAULT, PH_EMENU_DEFAULT);

                    PhpInitializeFindObjMenu(menu, results, numberOfResults);
                    PhShowEMenu(
                        menu,
                        hwndDlg,
                        PH_EMENU_SHOW_SEND_COMMAND | PH_EMENU_SHOW_LEFTRIGHT,
                        PH_ALIGN_LEFT | PH_ALIGN_TOP,
                        point.x,
                        point.y
                        );
                    PhDestroyEMenu(menu);
                }

                PhFree(results);
            }
        }
        break;
    case WM_SIZE:
        {
            PhLayoutManagerLayout(&WindowLayoutManager);
        }
        break;
    case WM_SIZING:
        {
            PhResizingMinimumSize((PRECT)lParam, wParam, MinimumSize.right, MinimumSize.bottom);
        }
        break;
    case WM_PH_SEARCH_UPDATE:
        {
            HWND lvHandle;
            ULONG i;

            lvHandle = GetDlgItem(hwndDlg, IDC_RESULTS);

            ExtendedListView_SetRedraw(lvHandle, FALSE);

            PhAcquireQueuedLockExclusive(&SearchResultsLock);

            for (i = SearchResultsAddIndex; i < SearchResults->Count; i++)
            {
                PPHP_OBJECT_SEARCH_RESULT searchResult = SearchResults->Items[i];
                CLIENT_ID clientId;
                PPH_PROCESS_ITEM processItem;
                PPH_STRING clientIdName;
                INT lvItemIndex;

                clientId.UniqueProcess = searchResult->ProcessId;
                clientId.UniqueThread = NULL;

                processItem = PhReferenceProcessItem(clientId.UniqueProcess);
                clientIdName = PhGetClientIdNameEx(&clientId, processItem ? processItem->ProcessName : NULL);

                lvItemIndex = PhAddListViewItem(
                    lvHandle,
                    MAXINT,
                    clientIdName->Buffer,
                    searchResult
                    );

                PhDereferenceObject(clientIdName);

                if (processItem)
                {
                    PhSetReference(&searchResult->ProcessName, processItem->ProcessName);
                    PhDereferenceObject(processItem);
                }
                else
                {
                    searchResult->ProcessName = NULL;
                }

                PhSetListViewSubItem(lvHandle, lvItemIndex, 1, searchResult->TypeName->Buffer);
                PhSetListViewSubItem(lvHandle, lvItemIndex, 2, searchResult->Name->Buffer);
                PhSetListViewSubItem(lvHandle, lvItemIndex, 3, searchResult->HandleString);
            }

            SearchResultsAddIndex = i;

            PhReleaseQueuedLockExclusive(&SearchResultsLock);

            ExtendedListView_SetRedraw(lvHandle, TRUE);
        }
        break;
    case WM_PH_SEARCH_FINISHED:
        {
            NTSTATUS handleSearchStatus = (NTSTATUS)wParam;

            // Add any un-added items.
            SendMessage(hwndDlg, WM_PH_SEARCH_UPDATE, 0, 0);

            NtWaitForSingleObject(SearchThreadHandle, FALSE, NULL);
            NtClose(SearchThreadHandle);
            SearchThreadHandle = NULL;
            SearchStop = FALSE;

            ExtendedListView_SortItems(GetDlgItem(hwndDlg, IDC_RESULTS));

            SetDlgItemText(hwndDlg, IDOK, L"Find");
            EnableWindow(GetDlgItem(hwndDlg, IDOK), TRUE);

            SetCursor(LoadCursor(NULL, IDC_ARROW));

            if (handleSearchStatus == STATUS_INSUFFICIENT_RESOURCES)
            {
                PhShowWarning(
                    hwndDlg,
                    L"Unable to search for handles because the total number of handles on the system is too large. "
                    L"Please check if there are any processes with an extremely large number of handles open."
                    );
            }
        }
        break;
    }

    return FALSE;
}
Beispiel #20
0
NTSTATUS
GRAPHICS_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
                           IN OUT PCONSOLE Console,
                           IN PGRAPHICS_BUFFER_INFO GraphicsInfo)
{
    NTSTATUS Status = STATUS_SUCCESS;
    PGRAPHICS_SCREEN_BUFFER NewBuffer = NULL;

    LARGE_INTEGER SectionSize;
    ULONG ViewSize = 0;
    HANDLE ProcessHandle;

    if (Buffer == NULL || Console == NULL || GraphicsInfo == NULL)
        return STATUS_INVALID_PARAMETER;

    *Buffer = NULL;

    Status = CONSOLE_SCREEN_BUFFER_Initialize((PCONSOLE_SCREEN_BUFFER*)&NewBuffer,
                                              Console,
                                              sizeof(GRAPHICS_SCREEN_BUFFER));
    if (!NT_SUCCESS(Status)) return Status;
    NewBuffer->Header.Type = GRAPHICS_BUFFER;
    NewBuffer->Vtbl = &GraphicsVtbl;

    /*
     * Remember the handle to the process so that we can close or unmap
     * correctly the allocated resources when the client releases the
     * screen buffer.
     */
    ProcessHandle = CsrGetClientThread()->Process->ProcessHandle;
    NewBuffer->ClientProcess = ProcessHandle;

    /* Get infos from the graphics buffer information structure */
    NewBuffer->BitMapInfoLength = GraphicsInfo->Info.dwBitMapInfoLength;

    NewBuffer->BitMapInfo = ConsoleAllocHeap(HEAP_ZERO_MEMORY, NewBuffer->BitMapInfoLength);
    if (NewBuffer->BitMapInfo == NULL)
    {
        CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    /* Adjust the bitmap height if needed (bottom-top vs. top-bottom). Use always bottom-up. */
    if (GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight > 0)
        GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight = -GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight;

    /* We do not use anything else than uncompressed bitmaps */
    if (GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression != BI_RGB)
    {
        DPRINT1("biCompression == %d != BI_RGB, correct that!\n", GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression);
        GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression = BI_RGB;
    }

    RtlCopyMemory(NewBuffer->BitMapInfo,
                  GraphicsInfo->Info.lpBitMapInfo,
                  GraphicsInfo->Info.dwBitMapInfoLength);

    NewBuffer->BitMapUsage = GraphicsInfo->Info.dwUsage;

    /* Set the screen buffer size. Fight against overflows. */
    if ( GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biWidth  <= 0xFFFF &&
        -GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight <= 0xFFFF )
    {
        /* Be careful about the sign of biHeight */
        NewBuffer->ScreenBufferSize.X =  (SHORT)GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biWidth ;
        NewBuffer->ScreenBufferSize.Y = (SHORT)-GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight;

        NewBuffer->OldViewSize = NewBuffer->ViewSize = 
            NewBuffer->OldScreenBufferSize = NewBuffer->ScreenBufferSize;
    }
    else
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        ConsoleFreeHeap(NewBuffer->BitMapInfo);
        CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
        goto Quit;
    }

    /*
     * Create a mutex to synchronize bitmap memory access
     * between ourselves and the client.
     */
    Status = NtCreateMutant(&NewBuffer->Mutex, MUTANT_ALL_ACCESS, NULL, FALSE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtCreateMutant() failed: %lu\n", Status);
        ConsoleFreeHeap(NewBuffer->BitMapInfo);
        CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
        goto Quit;
    }

    /*
     * Duplicate the Mutex for the client. We must keep a trace of it
     * so that we can close it when the client releases the screen buffer.
     */
    Status = NtDuplicateObject(NtCurrentProcess(),
                               NewBuffer->Mutex,
                               ProcessHandle,
                               &NewBuffer->ClientMutex,
                               0, 0, DUPLICATE_SAME_ACCESS);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
        NtClose(NewBuffer->Mutex);
        ConsoleFreeHeap(NewBuffer->BitMapInfo);
        CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
        goto Quit;
    }

    /*
     * Create a memory section for the bitmap area, to share with the client.
     */
    SectionSize.QuadPart = NewBuffer->BitMapInfo->bmiHeader.biSizeImage;
    Status = NtCreateSection(&NewBuffer->hSection,
                             SECTION_ALL_ACCESS,
                             NULL,
                             &SectionSize,
                             PAGE_READWRITE,
                             SEC_COMMIT,
                             NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error: Impossible to create a shared section ; Status = %lu\n", Status);
        NtClose(NewBuffer->ClientMutex);
        NtClose(NewBuffer->Mutex);
        ConsoleFreeHeap(NewBuffer->BitMapInfo);
        CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
        goto Quit;
    }

    /*
     * Create a view for our needs.
     */
    ViewSize = 0;
    NewBuffer->BitMap = NULL;
    Status = NtMapViewOfSection(NewBuffer->hSection,
                                NtCurrentProcess(),
                                (PVOID*)&NewBuffer->BitMap,
                                0,
                                0,
                                NULL,
                                &ViewSize,
                                ViewUnmap,
                                0,
                                PAGE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error: Impossible to map the shared section ; Status = %lu\n", Status);
        NtClose(NewBuffer->hSection);
        NtClose(NewBuffer->ClientMutex);
        NtClose(NewBuffer->Mutex);
        ConsoleFreeHeap(NewBuffer->BitMapInfo);
        CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
        goto Quit;
    }

    /*
     * Create a view for the client. We must keep a trace of it so that
     * we can unmap it when the client releases the screen buffer.
     */
    ViewSize = 0;
    NewBuffer->ClientBitMap = NULL;
    Status = NtMapViewOfSection(NewBuffer->hSection,
                                ProcessHandle,
                                (PVOID*)&NewBuffer->ClientBitMap,
                                0,
                                0,
                                NULL,
                                &ViewSize,
                                ViewUnmap,
                                0,
                                PAGE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error: Impossible to map the shared section ; Status = %lu\n", Status);
        NtUnmapViewOfSection(NtCurrentProcess(), NewBuffer->BitMap);
        NtClose(NewBuffer->hSection);
        NtClose(NewBuffer->ClientMutex);
        NtClose(NewBuffer->Mutex);
        ConsoleFreeHeap(NewBuffer->BitMapInfo);
        CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
        goto Quit;
    }

    NewBuffer->ViewOrigin.X = NewBuffer->ViewOrigin.Y = 0;
    NewBuffer->VirtualY = 0;

    NewBuffer->CursorBlinkOn  = FALSE;
    NewBuffer->ForceCursorOff = TRUE;
    NewBuffer->CursorInfo.bVisible = FALSE;
    NewBuffer->CursorInfo.dwSize   = 0;
    NewBuffer->CursorPosition.X = NewBuffer->CursorPosition.Y = 0;

    NewBuffer->Mode = 0;

    *Buffer = (PCONSOLE_SCREEN_BUFFER)NewBuffer;
    Status = STATUS_SUCCESS;

Quit:
    return Status;
}
PPH_LIST EnumerateAppDomainIpcBlockWow64(
    _In_ HANDLE ProcessHandle,
    _In_ AppDomainEnumerationIPCBlock_Wow64* AppDomainIpcBlock
    )
{
    LARGE_INTEGER timeout;
    SIZE_T appDomainInfoBlockLength;
    HANDLE legacyPrivateBlockMutexHandle = NULL;
    AppDomainEnumerationIPCBlock_Wow64 tempBlock;
    AppDomainInfo_Wow64* appDomainInfoBlock = NULL;
    PPH_LIST appDomainsList = PhCreateList(1);

    // If the mutex isn't filled in, the CLR is either starting up or shutting down
    if (!AppDomainIpcBlock->Mutex)
    {
        goto CleanupExit;
    }

    // Dup the valid mutex handle into this process.
    if (!NT_SUCCESS(NtDuplicateObject(
        ProcessHandle,
        UlongToHandle(AppDomainIpcBlock->Mutex),
        NtCurrentProcess(),
        &legacyPrivateBlockMutexHandle,
        GENERIC_ALL,
        0,
        DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES
        )))
    {
        goto CleanupExit;
    }

    // Acquire the mutex, only waiting two seconds.
    // We can't actually gaurantee that the target put a mutex object in here.
    if (NtWaitForSingleObject(
        legacyPrivateBlockMutexHandle,
        FALSE,
        PhTimeoutFromMilliseconds(&timeout, 2000)
        ) == STATUS_WAIT_0)
    {
        // Make sure the mutex handle is still valid. If its not, then we lost a shutdown race.
        if (!AppDomainIpcBlock->Mutex)
        {
            goto CleanupExit;
        }
    }
    else
    {
        // Again, landing here is most probably a shutdown race.
        goto CleanupExit;
    }

    // Beware: If the target pid is not properly honoring the mutex, the data in the IPC block may still shift underneath us.
    // If we get here, then hMutex is held by this process.

    // Make a copy of the IPC block so that we can gaurantee that it's not changing on us.
    memcpy(&tempBlock, AppDomainIpcBlock, sizeof(AppDomainEnumerationIPCBlock_Wow64));

    // It's possible the process will not have any appdomains.
    if ((tempBlock.ListOfAppDomains == 0) != (tempBlock.SizeInBytes == 0))
    {
        goto CleanupExit;
    }

    // All the data in the IPC block is signed integers. They should never be negative,
    // so check that now.
    if ((tempBlock.TotalSlots < 0) ||
        (tempBlock.NumOfUsedSlots < 0) ||
        (tempBlock.LastFreedSlot < 0) ||
        (tempBlock.SizeInBytes < 0) ||
        (tempBlock.ProcessNameLengthInBytes < 0))
    {
        goto CleanupExit;
    }

    // Allocate memory to read the remote process' memory into
    appDomainInfoBlockLength = tempBlock.SizeInBytes;

    // Check other invariants.
    if (appDomainInfoBlockLength != tempBlock.TotalSlots * sizeof(AppDomainInfo_Wow64))
    {
        goto CleanupExit;
    }

    appDomainInfoBlock = (AppDomainInfo_Wow64*)PhAllocate(appDomainInfoBlockLength);
    memset(appDomainInfoBlock, 0, appDomainInfoBlockLength);

    if (!NT_SUCCESS(NtReadVirtualMemory(
        ProcessHandle,
        UlongToPtr(tempBlock.ListOfAppDomains),
        appDomainInfoBlock,
        appDomainInfoBlockLength,
        NULL
        )))
    {
        PhFree(appDomainInfoBlock);
        goto CleanupExit;
    }

    // Collect all the AppDomain names into a list of strings.
    for (INT i = 0; i < tempBlock.NumOfUsedSlots; i++)
    {
        SIZE_T appDomainNameLength;
        PVOID appDomainName;

        if (!appDomainInfoBlock[i].AppDomainName)
            continue;

        // Should be positive, and at least have a null-terminator character.
        if (appDomainInfoBlock[i].NameLengthInBytes <= 1)
            continue;

        // Make sure buffer has right geometry.
        if (appDomainInfoBlock[i].NameLengthInBytes < 0)
            continue;

        // If it's not on a WCHAR boundary, then we may have a 1-byte buffer-overflow.
        appDomainNameLength = appDomainInfoBlock[i].NameLengthInBytes / sizeof(WCHAR);

        if ((appDomainNameLength * sizeof(WCHAR)) != appDomainInfoBlock[i].NameLengthInBytes)
            continue;

        // It should at least have 1 char for the null terminator.
        if (appDomainNameLength < 1)
            continue;

        // We know the string is a well-formed null-terminated string,
        // but beyond that, we can't verify that the data is actually truthful.
        appDomainName = PhAllocate(appDomainInfoBlock[i].NameLengthInBytes + 1);
        memset(appDomainName, 0, appDomainInfoBlock[i].NameLengthInBytes + 1);

        if (!NT_SUCCESS(NtReadVirtualMemory(
            ProcessHandle,
            UlongToPtr(appDomainInfoBlock[i].AppDomainName),
            appDomainName,
            appDomainInfoBlock[i].NameLengthInBytes,
            NULL
            )))
        {
            PhFree(appDomainName);
            continue;
        }

        PhAddItemList(appDomainsList, appDomainName);
    }

CleanupExit:

    if (appDomainInfoBlock)
    {
        PhFree(appDomainInfoBlock);
    }

    if (legacyPrivateBlockMutexHandle)
    {
        NtReleaseMutant(legacyPrivateBlockMutexHandle, NULL);
        NtClose(legacyPrivateBlockMutexHandle);
    }

    return appDomainsList;
}
Beispiel #22
0
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
}
Beispiel #23
0
NTSTATUS ModifySelfSizeOfImage(LPWSTR ExeFullPath, LPWSTR CommandLine, ULONG SizeOfImage)
{
    BOOL                        Result;
    ULONG                       Length;
    PVOID                       FakeCPInfoBuffer;
    WCHAR                       CmdFullPath[MAX_NTPATH];
    PWCHAR                      CmdLineBuffer;
    NTSTATUS                    Status;
    PLDR_MODULE                 LdrModule;
    PIMAGE_DOS_HEADER           DosHeader;
    PIMAGE_NT_HEADERS           NtHeader;
    PIMAGE_SECTION_HEADER       SectionHeader;
    FAKE_CREATE_PROCESS_INFO   *fcpi;
    PROCESS_INFORMATION         ProcessInformation;
    CONTEXT                     Context;
    NtFileDisk                 file;
    UNICODE_STRING              ExeNtPath, *ProcessCommandLine;

    UNREFERENCED_PARAMETER(CommandLine);

    LdrModule = Nt_FindLdrModuleByName(NULL);

    DosHeader   = (PIMAGE_DOS_HEADER)&__ImageBase;
    NtHeader    = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHeader + DosHeader->e_lfanew);

    fcpi = (FAKE_CREATE_PROCESS_INFO *)AllocStack(0x2000);
    fcpi->PeHeaderSize = (ULONG_PTR)(IMAGE_FIRST_SECTION(NtHeader) + NtHeader->FileHeader.NumberOfSections) - (ULONG_PTR)DosHeader;

    Status = file.Open(LdrModule->FullDllName.Buffer);
    if (!NT_SUCCESS(Status))
        return Status;

    Status = file.Read(fcpi->PeHeader, fcpi->PeHeaderSize);
    if (!NT_SUCCESS(Status))
        return Status;

    CmdLineBuffer = (PWCHAR)((ULONG_PTR)fcpi->PeHeader + fcpi->PeHeaderSize);

    fcpi->CommandLine.Buffer        = CmdLineBuffer;
    fcpi->CommandLine.Length        = (USHORT)(StrLengthW(ExeFullPath) * sizeof(WCHAR));

    ProcessCommandLine = &Nt_CurrentPeb()->ProcessParameters->CommandLine;
    CopyMemory(CmdLineBuffer, ProcessCommandLine->Buffer, ProcessCommandLine->Length);
    *(PULONG_PTR)&CmdLineBuffer += ProcessCommandLine->Length;
    CmdLineBuffer[0] = 0;

    fcpi->CommandLine.Length        = ProcessCommandLine->Length;
    fcpi->CommandLine.MaximumLength = fcpi->CommandLine.Length + sizeof(WCHAR);

    ++CmdLineBuffer;
    CmdLineBuffer = (PWCHAR)ROUND_UP((ULONG_PTR)CmdLineBuffer, 16);

    RtlDosPathNameToNtPathName_U(LdrModule->FullDllName.Buffer, &ExeNtPath, NULL, NULL);

    fcpi->ExeNtPath.Buffer = CmdLineBuffer;
    CopyMemory(CmdLineBuffer, ExeNtPath.Buffer, ExeNtPath.Length);
    *(PULONG_PTR)&CmdLineBuffer += ExeNtPath.Length;
    CmdLineBuffer[0] = 0;

    fcpi->ExeNtPath.Length        = ExeNtPath.Length;
    fcpi->ExeNtPath.MaximumLength = fcpi->ExeNtPath.Length + sizeof(WCHAR);

    *CmdLineBuffer++ = 0;

    RtlFreeUnicodeString(&ExeNtPath);

    DosHeader       = (PIMAGE_DOS_HEADER)fcpi->PeHeader;
    NtHeader        = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHeader + DosHeader->e_lfanew);
    SectionHeader   = IMAGE_FIRST_SECTION(NtHeader);

    SectionHeader   += NtHeader->FileHeader.NumberOfSections - 1;
    SizeOfImage     -= LdrModule->SizeOfImage;
    SizeOfImage      = ROUND_UP(SizeOfImage, MEMORY_PAGE_SIZE);

    SectionHeader->Misc.VirtualSize = ROUND_UP(SectionHeader->Misc.VirtualSize, MEMORY_PAGE_SIZE) + SizeOfImage;

    if (NtHeader->FileHeader.SizeOfOptionalHeader > FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, SizeOfImage) + RTL_FIELD_SIZE(IMAGE_OPTIONAL_HEADER, SizeOfImage))
        NtHeader->OptionalHeader.SizeOfImage += SizeOfImage;

    Length = Nt_GetSystemDirectory(CmdFullPath, countof(CmdFullPath));
    StrCopyW(CmdFullPath + Length, L"cmd.exe");

    ProcessInformation.hProcess = NtCurrentProcess();
    ProcessInformation.hThread  = NtCurrentThread();

#if 1
    Result = Nt_CreateProcess(NULL, CmdFullPath, NULL, CREATE_SUSPENDED, NULL, &ProcessInformation);
    if (!Result)
        return STATUS_UNSUCCESSFUL;
#endif

    FakeCPInfoBuffer = NULL;
    LOOP_ONCE
    {
        ULONG_PTR Offset;

        Status = NtDuplicateObject(
                    NtCurrentProcess(),
                    NtCurrentProcess(),
                    ProcessInformation.hProcess,
                    &fcpi->ProcessHandle,
                    0,
                    0,
                    DUPLICATE_SAME_ACCESS
                 );
        if (!NT_SUCCESS(Status))
            break;
/*
        Status = NtDuplicateObject(
                    NtCurrentProcess(),
                    file,
                    ProcessInformation.hProcess,
                    &fcpi->FileHandle,
                    0,
                    0,
                    DUPLICATE_SAME_ACCESS
                 );
        if (!NT_SUCCESS(Status))
            break;
*/
        Status = Nt_AllocateMemory(ProcessInformation.hProcess, &FakeCPInfoBuffer, MEMORY_PAGE_SIZE);
        if (!NT_SUCCESS(Status))
            break;

        fcpi->CreateProcessInternalW    = CreateProcessInternalW;
        fcpi->NtTerminateProcess        = NtTerminateProcess;
        fcpi->LdrShutdownProcess        = LdrShutdownProcess;
        fcpi->NtCreateFile              = NtCreateFile;
        fcpi->NtWriteFile               = NtWriteFile;
        fcpi->NtClose                   = NtClose;
        fcpi->NtWaitForSingleObject     = NtWaitForSingleObject;
        fcpi->InitialDirectory.Buffer   = NULL;

        Offset = (ULONG_PTR)FakeCPInfoBuffer - (ULONG_PTR)fcpi;
        *(PULONG_PTR)&fcpi->CommandLine.Buffer += Offset;
        *(PULONG_PTR)&fcpi->ExeNtPath.Buffer   += Offset;

        Status = Nt_WriteMemory(
                    ProcessInformation.hProcess,
                    FakeCPInfoBuffer,
                    fcpi,
                    (ULONG_PTR)CmdLineBuffer - (ULONG_PTR)fcpi,
                    &Length
                );
        if (!NT_SUCCESS(Status))
            break;

        Context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
        Status = NtGetContextThread(ProcessInformation.hThread, &Context);
        if (!NT_SUCCESS(Status))
            break;

        Context.Eip = (ULONG_PTR)FakeCPInfoBuffer + Length;
        Context.Eip = ROUND_UP(Context.Eip, 16);
        Context.Ecx = (ULONG_PTR)FakeCPInfoBuffer;

        Status = Nt_WriteMemory(
                    ProcessInformation.hProcess,
                    (PVOID)Context.Eip,
                    ModifySizeOfImage,
                    (ULONG_PTR)ModifySizeOfImageEnd - (ULONG_PTR)ModifySizeOfImage,
                    &Length
                );
        if (!NT_SUCCESS(Status))
            break;

#if 1
        Status = NtSetContextThread(ProcessInformation.hThread, &Context);
        if (!NT_SUCCESS(Status))
            break;

        Status = NtResumeThread(ProcessInformation.hThread, NULL);
#else
        INLINE_ASM jmp Context.Eip;
#endif
    }

    if (!NT_SUCCESS(Status))
    {
        if (FakeCPInfoBuffer != NULL)
            Nt_FreeMemory(ProcessInformation.hProcess, FakeCPInfoBuffer);

        NtTerminateProcess(ProcessInformation.hProcess, 0);
    }

    NtClose(ProcessInformation.hProcess);
    NtClose(ProcessInformation.hThread);

    return Status;
}
Beispiel #24
0
        bool search::generate_pbo_list() {
            NTSTATUS status;
            PSYSTEM_HANDLE_INFORMATION handleInfo;
            ULONG handleInfoSize = 0x10000;
            ULONG pid;
            HANDLE processHandle;
            ULONG i;

            _NtQuerySystemInformation NtQuerySystemInformation =
                (_NtQuerySystemInformation)GetLibraryProcAddress("ntdll.dll", "NtQuerySystemInformation");
            _NtDuplicateObject NtDuplicateObject =
                (_NtDuplicateObject)GetLibraryProcAddress("ntdll.dll", "NtDuplicateObject");
            _NtQueryObject NtQueryObject =
                (_NtQueryObject)GetLibraryProcAddress("ntdll.dll", "NtQueryObject");

            if (!NtQuerySystemInformation || !NtDuplicateObject || !NtQueryObject)
                return false;

            pid = GetCurrentProcessId();
            processHandle = GetCurrentProcess();

            handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);

            while ((status = NtQuerySystemInformation(
                SystemHandleInformation,
                handleInfo,
                handleInfoSize,
                NULL
                )) == STATUS_INFO_LENGTH_MISMATCH)
                handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2);

            /* NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH. */
            if (!NT_SUCCESS(status))
            {
                LOG(ERROR) << "Error opening object for pbo search";
                free(handleInfo);
                return false;
            }

            for (i = 0; i < handleInfo->HandleCount; i++)
            {
                SYSTEM_HANDLE handle = handleInfo->Handles[i];
                HANDLE dupHandle = NULL;
                POBJECT_TYPE_INFORMATION objectTypeInfo;
                PVOID objectNameInfo;
                UNICODE_STRING objectName;
                ULONG returnLength;

                /* Check if this handle belongs to the PID the user specified. */
                if (handle.ProcessId != pid)
                    continue;

                /* Duplicate the handle so we can query it. */
                if (!NT_SUCCESS(NtDuplicateObject(
                    processHandle,
                    (HANDLE)handle.Handle,
                    GetCurrentProcess(),
                    &dupHandle,
                    0,
                    0,
                    0
                    )))
                {
                    continue;
                }

                /* Query the object type. */
                objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000);
                if (!NT_SUCCESS(NtQueryObject(
                    dupHandle,
                    ObjectTypeInformation,
                    objectTypeInfo,
                    0x1000,
                    NULL
                    )))
                {
                    CloseHandle(dupHandle);
                    continue;
                }

                /* Query the object name (unless it has an access of
                0x0012019f, on which NtQueryObject could hang. */
                if (handle.GrantedAccess == 0x0012019f)
                {

                    free(objectTypeInfo);
                    CloseHandle(dupHandle);
                    continue;
                }

                objectNameInfo = malloc(0x1000);
                if (!NT_SUCCESS(NtQueryObject(
                    dupHandle,
                    ObjectNameInformation,
                    objectNameInfo,
                    0x1000,
                    &returnLength
                    )))
                {
                    /* Reallocate the buffer and try again. */
                    objectNameInfo = realloc(objectNameInfo, returnLength);
                    if (!NT_SUCCESS(NtQueryObject(
                        dupHandle,
                        ObjectNameInformation,
                        objectNameInfo,
                        returnLength,
                        NULL
                        )))
                    {
                        free(objectTypeInfo);
                        free(objectNameInfo);
                        CloseHandle(dupHandle);
                        continue;
                    }
                }

                /* Cast our buffer into an UNICODE_STRING. */
                objectName = *(PUNICODE_STRING)objectNameInfo;
               
                

                /* Print the information! */
                if (objectName.Length)
                {
                    std::wstring tmp_type(objectTypeInfo->Name.Buffer);
                    std::wstring tmp_name(objectName.Buffer);
                    
                    std::string object_type(tmp_type.begin(), tmp_type.end());
                    std::string object_name(tmp_name.begin(), tmp_name.end());
                    if (object_type == "File" && object_name.find(".pbo") != object_name.npos) {
                        char buffer[MAX_PATH];
                        GetFinalPathNameByHandle(dupHandle, buffer, sizeof(buffer), VOLUME_NAME_DOS);

                        LOG(DEBUG) << "Pbo: " << buffer;
                        _active_pbo_list.push_back(std::string(buffer));
                    }
                }              

                free(objectTypeInfo);
                free(objectNameInfo);
                CloseHandle(dupHandle);
            }

            free(handleInfo);

            return true;
        }
Beispiel #25
0
VOID
GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
                                BOOL Defaults)
{
    NTSTATUS Status;
    PCONSRV_CONSOLE Console = GuiData->Console;
    PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer;
    PCONSOLE_PROCESS_DATA ProcessData;
    HANDLE hSection = NULL, hClientSection = NULL;
    LARGE_INTEGER SectionSize;
    ULONG ViewSize = 0;
    SIZE_T Length = 0;
    PCONSOLE_PROPS pSharedInfo = NULL;
    PGUI_CONSOLE_INFO GuiInfo = NULL;

    DPRINT("GuiConsoleShowConsoleProperties entered\n");

    if (!ConDrvValidateConsoleUnsafe((PCONSOLE)Console, CONSOLE_RUNNING, TRUE)) return;

    /*
     * Create a memory section to share with the applet, and map it.
     */
    /* Holds data for console.dll + console info + terminal-specific info */
    SectionSize.QuadPart = sizeof(CONSOLE_PROPS) + sizeof(GUI_CONSOLE_INFO);
    Status = NtCreateSection(&hSection,
                             SECTION_ALL_ACCESS,
                             NULL,
                             &SectionSize,
                             PAGE_READWRITE,
                             SEC_COMMIT,
                             NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error: Impossible to create a shared section, Status = 0x%08lx\n", Status);
        goto Quit;
    }

    Status = NtMapViewOfSection(hSection,
                                NtCurrentProcess(),
                                (PVOID*)&pSharedInfo,
                                0,
                                0,
                                NULL,
                                &ViewSize,
                                ViewUnmap,
                                0,
                                PAGE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error: Impossible to map the shared section, Status = 0x%08lx\n", Status);
        goto Quit;
    }


    /*
     * Setup the shared console properties structure.
     */

    /* Header */
    pSharedInfo->hConsoleWindow = GuiData->hWindow;
    pSharedInfo->ShowDefaultParams = Defaults;

    /*
     * We fill-in the fields only if we display
     * our properties, not the default ones.
     */
    if (!Defaults)
    {
        /* Console information */
        pSharedInfo->ci.HistoryBufferSize = Console->HistoryBufferSize;
        pSharedInfo->ci.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers;
        pSharedInfo->ci.HistoryNoDup = Console->HistoryNoDup;
        pSharedInfo->ci.QuickEdit = Console->QuickEdit;
        pSharedInfo->ci.InsertMode = Console->InsertMode;
        /////////////pSharedInfo->ci.InputBufferSize = 0;
        pSharedInfo->ci.ScreenBufferSize = ActiveBuffer->ScreenBufferSize;
        pSharedInfo->ci.ConsoleSize = ActiveBuffer->ViewSize;
        pSharedInfo->ci.CursorBlinkOn;
        pSharedInfo->ci.ForceCursorOff;
        pSharedInfo->ci.CursorSize = ActiveBuffer->CursorInfo.dwSize;
        if (GetType(ActiveBuffer) == TEXTMODE_BUFFER)
        {
            PTEXTMODE_SCREEN_BUFFER Buffer = (PTEXTMODE_SCREEN_BUFFER)ActiveBuffer;

            pSharedInfo->ci.ScreenAttrib = Buffer->ScreenDefaultAttrib;
            pSharedInfo->ci.PopupAttrib  = Buffer->PopupDefaultAttrib;
        }
        else // if (GetType(ActiveBuffer) == GRAPHICS_BUFFER)
        {
            // PGRAPHICS_SCREEN_BUFFER Buffer = (PGRAPHICS_SCREEN_BUFFER)ActiveBuffer;
            DPRINT1("GuiConsoleShowConsoleProperties - Graphics buffer\n");

            // FIXME: Gather defaults from the registry ?
            pSharedInfo->ci.ScreenAttrib = DEFAULT_SCREEN_ATTRIB;
            pSharedInfo->ci.PopupAttrib  = DEFAULT_POPUP_ATTRIB ;
        }
        pSharedInfo->ci.CodePage;

        /* GUI Information */
        pSharedInfo->TerminalInfo.Size = sizeof(GUI_CONSOLE_INFO);
        GuiInfo = pSharedInfo->TerminalInfo.TermInfo = (PGUI_CONSOLE_INFO)(pSharedInfo + 1);
        wcsncpy(GuiInfo->FaceName, GuiData->GuiInfo.FaceName, LF_FACESIZE);
        GuiInfo->FaceName[LF_FACESIZE - 1] = UNICODE_NULL;
        GuiInfo->FontFamily = GuiData->GuiInfo.FontFamily;
        GuiInfo->FontSize   = GuiData->GuiInfo.FontSize;
        GuiInfo->FontWeight = GuiData->GuiInfo.FontWeight;
        GuiInfo->FullScreen = GuiData->GuiInfo.FullScreen;
        GuiInfo->AutoPosition = GuiData->GuiInfo.AutoPosition;
        GuiInfo->WindowOrigin = GuiData->GuiInfo.WindowOrigin;
        /* Offsetize */
        pSharedInfo->TerminalInfo.TermInfo = (PVOID)((ULONG_PTR)GuiInfo - (ULONG_PTR)pSharedInfo);

        /* Palette */
        memcpy(pSharedInfo->ci.Colors, Console->Colors, sizeof(Console->Colors));

        /* Title of the console, original one corresponding to the one set by the console leader */
        Length = min(sizeof(pSharedInfo->ci.ConsoleTitle) / sizeof(pSharedInfo->ci.ConsoleTitle[0]) - 1,
                     Console->OriginalTitle.Length / sizeof(WCHAR));
        wcsncpy(pSharedInfo->ci.ConsoleTitle, Console->OriginalTitle.Buffer, Length);
    }
    else
    {
        Length = 0;
        // FIXME: Load the default parameters from the registry.
    }

    /* Null-terminate the title */
    pSharedInfo->ci.ConsoleTitle[Length] = L'\0';


    /* Unmap the view */
    NtUnmapViewOfSection(NtCurrentProcess(), pSharedInfo);

    /* Get the console leader process, our client */
    ProcessData = ConSrvGetConsoleLeaderProcess(Console);

    /* Duplicate the section handle for the client */
    Status = NtDuplicateObject(NtCurrentProcess(),
                               hSection,
                               ProcessData->Process->ProcessHandle,
                               &hClientSection,
                               0, 0, DUPLICATE_SAME_ACCESS);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error: Impossible to duplicate section handle for client, Status = 0x%08lx\n", Status);
        goto Quit;
    }

    /* Start the properties dialog */
    if (ProcessData->PropRoutine)
    {
        _SEH2_TRY
        {
            HANDLE Thread = NULL;

            _SEH2_TRY
            {
                Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
                                            ProcessData->PropRoutine,
                                            (PVOID)hClientSection, 0, NULL);
                if (NULL == Thread)
                {
                    DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
                }
                else
                {
                    DPRINT("ProcessData->PropRoutine remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n",
                           ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
                    /// WaitForSingleObject(Thread, INFINITE);
                }
            }
            _SEH2_FINALLY
            {
                CloseHandle(Thread);
            }
            _SEH2_END;
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            Status = _SEH2_GetExceptionCode();
            DPRINT1("GuiConsoleShowConsoleProperties - Caught an exception, Status = 0x%08lx\n", Status);
        }
        _SEH2_END;
    }
Beispiel #26
0
int wmain(int argc, WCHAR *argv[])
{
	_NtQuerySystemInformation NtQuerySystemInformation =
		(_NtQuerySystemInformation)GetLibraryProcAddress("ntdll.dll", "NtQuerySystemInformation");
	_NtDuplicateObject NtDuplicateObject =
		(_NtDuplicateObject)GetLibraryProcAddress("ntdll.dll", "NtDuplicateObject");
	_NtQueryObject NtQueryObject =
		(_NtQueryObject)GetLibraryProcAddress("ntdll.dll", "NtQueryObject");
	NTSTATUS status;
	PSYSTEM_HANDLE_INFORMATION handleInfo;
	ULONG handleInfoSize = 0x10000;
	ULONG pid = 0;
	HANDLE processHandle;
	ULONG i;

	if (argc < 2)
	{
		printf("Usage: handles filepath [pid]\n");
		return 1;
	}

	if (argc > 2)
	{
		pid = _wtoi(argv[2]);
	}

	// convert C:\Windows\System32 to \Device\HarddiskVolume1\Windows\System32
	const WCHAR* filePath = argv[1];
	if (wcslen(filePath) < 2 || filePath[1] != L':')
	{
		printf("Can't process input path which is tool short or not contain local driver!\n");
		return 1;
	}
	PWSTR pDosDriveName = new TCHAR[MAX_PATH];
	TCHAR szDrive[3] = TEXT(" :");
	szDrive[0] = filePath[0];
	DWORD uiLen = QueryDosDeviceW(szDrive, pDosDriveName, MAX_PATH);
	if (0 == uiLen)
	{
		if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
		{
			printf("QueryDosDeviceW failed: %d\n", GetLastError());
			return 1;
		}

		delete[]pDosDriveName;
		pDosDriveName = new TCHAR[uiLen + 1];
		uiLen = QueryDosDevice(szDrive, pDosDriveName, uiLen + 1);
		if (0 == uiLen)
		{
			printf("QueryDosDeviceW failed: %d\n", GetLastError());
			return 1;
		}
	}
	wcscat(pDosDriveName, &filePath[2]);

	handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);
	/* NtQuerySystemInformation won't give us the correct buffer size,
	so we guess by doubling the buffer size. */
	while ((status = NtQuerySystemInformation(
		SystemHandleInformation,
		handleInfo,
		handleInfoSize,
		NULL
	)) == STATUS_INFO_LENGTH_MISMATCH)
		handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2);

	/* NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH. */
	if (!NT_SUCCESS(status))
	{
		printf("NtQuerySystemInformation failed!\n");
		return 1;
	}

	for (i = 0; i < handleInfo->HandleCount; i++)
	{
		SYSTEM_HANDLE handle = handleInfo->Handles[i];
		HANDLE dupHandle = NULL;
		POBJECT_TYPE_INFORMATION objectTypeInfo;
		PVOID objectNameInfo;
		UNICODE_STRING objectName;
		ULONG returnLength;

		// Jump of no file
		/*if (handle.ObjectTypeNumber != 31)
		{
			continue;
		}*/

		/* Check if this handle belongs to the PID the user specified. */
		if (pid != 0 && handle.ProcessId != pid)
			continue;

		if (!(processHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, handle.ProcessId)))
		{
			//printf("Could not open PID %d! (Don't try to open a system process.)\n", handle.ProcessId);
			continue;
		}

		/* Duplicate the handle so we can query it. */
		DWORD re = NtDuplicateObject(
			processHandle,
			(HANDLE)handle.Handle,
			GetCurrentProcess(),
			&dupHandle,
			0,
			0,
			0
		);
		if (ERROR_SUCCESS != re)
		{
			printf("[%#x] Error!\n", handle.Handle);
			continue;
		}

		/* Query the object type. */
		objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000);
		if (!NT_SUCCESS(NtQueryObject(
			dupHandle,
			ObjectTypeInformation,
			objectTypeInfo,
			0x1000,
			NULL
		)))
		{
			printf("[%#x] Error!\n", handle.Handle);
			CloseHandle(dupHandle);
			continue;
		}

		/* Query the object name (unless it has an access of
		0x0012019f, on which NtQueryObject could hang. */
		if (handle.GrantedAccess == 0x0012019f)
		{
			/* We have the type, so display that. */
			printf(
				"[%#x] %.*S: (did not get name)\n",
				handle.Handle,
				objectTypeInfo->Name.Length / 2,
				objectTypeInfo->Name.Buffer
			);
			free(objectTypeInfo);
			CloseHandle(dupHandle);
			continue;
		}

		objectNameInfo = malloc(0x1000);
		if (!NT_SUCCESS(MyNtQueryObject(
			NtQueryObject,
			dupHandle,
			ObjectNameInformation,
			objectNameInfo,
			0x1000,
			&returnLength
		)))
		{
			/* Reallocate the buffer and try again. */
			objectNameInfo = realloc(objectNameInfo, returnLength);
			if (!NT_SUCCESS(MyNtQueryObject(
				NtQueryObject,
				dupHandle,
				ObjectNameInformation,
				objectNameInfo,
				returnLength,
				NULL
			)))
			{
				/* We have the type name, so just display that. */
				printf(
					"[%#x] %.*S: (could not get name)\n",
					handle.Handle,
					objectTypeInfo->Name.Length / 2,
					objectTypeInfo->Name.Buffer
				);
				free(objectTypeInfo);
				free(objectNameInfo);
				CloseHandle(dupHandle);
				continue;
			}
		}

		/* Cast our buffer into an UNICODE_STRING. */
		objectName = *(PUNICODE_STRING)objectNameInfo;

		/* Print the information! */
		if (objectName.Length)
		{
			/* The object has a name. */
			printf(
				"[%#x] %.*S: %.*S\n",
				handle.Handle,
				objectTypeInfo->Name.Length / 2,
				objectTypeInfo->Name.Buffer,
				objectName.Length / 2,
				objectName.Buffer
			);

			if (wcscmp(objectName.Buffer, pDosDriveName) == 0)
			{
				printf("opend by process: %d", handle.ProcessId);
				break;
			}
		}
		else
		{
			/* Print something else. */
			printf(
				"[%#x] %.*S: (unnamed)\n",
				handle.Handle,
				objectTypeInfo->Name.Length / 2,
				objectTypeInfo->Name.Buffer
			);
		}

		free(objectTypeInfo);
		free(objectNameInfo);
		CloseHandle(dupHandle);
	}

	free(handleInfo);
	CloseHandle(processHandle);

	return 0;
}
Beispiel #27
0
/*
 * Function for dealing with the undocumented message and structure used by
 * Windows' console.dll for setting console info.
 * See http://www.catch22.net/sites/default/source/files/setconsoleinfo.c
 * and http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf
 * for more information.
 */
VOID
GuiApplyWindowsConsoleSettings(PGUI_CONSOLE_DATA GuiData,
                               HANDLE hClientSection)
{
    NTSTATUS Status = STATUS_SUCCESS;
    PCONSRV_CONSOLE Console = GuiData->Console;
    PCONSOLE_PROCESS_DATA ProcessData;
    HANDLE hSection = NULL;
    ULONG ViewSize = 0;
    PCONSOLE_STATE_INFO pConInfo = NULL;
    CONSOLE_INFO     ConInfo;
    GUI_CONSOLE_INFO GuiInfo;
#if 0
    SIZE_T Length;
#endif

    if (!ConDrvValidateConsoleUnsafe((PCONSOLE)Console, CONSOLE_RUNNING, TRUE)) return;

    /* Get the console leader process, our client */
    ProcessData = ConSrvGetConsoleLeaderProcess(Console);

    /* Duplicate the section handle for ourselves */
    Status = NtDuplicateObject(ProcessData->Process->ProcessHandle,
                               hClientSection,
                               NtCurrentProcess(),
                               &hSection,
                               0, 0, DUPLICATE_SAME_ACCESS);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error when mapping client handle, Status = 0x%08lx\n", Status);
        goto Quit;
    }

    /* Get a view of the shared section */
    Status = NtMapViewOfSection(hSection,
                                NtCurrentProcess(),
                                (PVOID*)&pConInfo,
                                0,
                                0,
                                NULL,
                                &ViewSize,
                                ViewUnmap,
                                0,
                                PAGE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Error when mapping view of file, Status = 0x%08lx\n", Status);
        goto Quit;
    }

    _SEH2_TRY
    {
        /* Check that the section is well-sized */
        if ( (ViewSize < sizeof(CONSOLE_STATE_INFO)) ||
             (pConInfo->cbSize != sizeof(CONSOLE_STATE_INFO)) )
        {
            DPRINT1("Error: section bad-sized: sizeof(Section) < sizeof(CONSOLE_STATE_INFO)\n");
            Status = STATUS_INVALID_VIEW_SIZE;
            _SEH2_YIELD(goto Quit);
        }

        // TODO: Check that GuiData->hWindow == pConInfo->hConsoleWindow

        /* Retrieve terminal informations */

        // Console information
        ConInfo.HistoryBufferSize = pConInfo->HistoryBufferSize;
        ConInfo.NumberOfHistoryBuffers = pConInfo->NumberOfHistoryBuffers;
        ConInfo.HistoryNoDup = !!pConInfo->HistoryNoDup;
        ConInfo.QuickEdit = !!pConInfo->QuickEdit;
        ConInfo.InsertMode = !!pConInfo->InsertMode;
        ConInfo.ScreenBufferSize = pConInfo->ScreenBufferSize;
        ConInfo.ConsoleSize = pConInfo->WindowSize;
        ConInfo.CursorSize = pConInfo->CursorSize;
        ConInfo.ScreenAttrib = pConInfo->ScreenColors;
        ConInfo.PopupAttrib = pConInfo->PopupColors;
        memcpy(&ConInfo.Colors, pConInfo->ColorTable, sizeof(ConInfo.Colors));
        ConInfo.CodePage = pConInfo->CodePage;
        /**ConInfo.ConsoleTitle[MAX_PATH + 1] = pConInfo->ConsoleTitle; // FIXME: memcpy**/
#if 0
        /* Title of the console, original one corresponding to the one set by the console leader */
        Length = min(sizeof(pConInfo->ConsoleTitle) / sizeof(pConInfo->ConsoleTitle[0]) - 1,
               Console->OriginalTitle.Length / sizeof(WCHAR));
        wcsncpy(pSharedInfo->ci.ConsoleTitle, Console->OriginalTitle.Buffer, Length);
#endif
        // BOOLEAN ConInfo.CursorBlinkOn = pConInfo->
        // BOOLEAN ConInfo.ForceCursorOff = pConInfo->


        // Terminal information
        wcsncpy(GuiInfo.FaceName, pConInfo->FaceName, LF_FACESIZE);
        GuiInfo.FaceName[LF_FACESIZE - 1] = UNICODE_NULL;

        GuiInfo.FontFamily = pConInfo->FontFamily;
        GuiInfo.FontSize = pConInfo->FontSize;
        GuiInfo.FontWeight = pConInfo->FontWeight;
        GuiInfo.FullScreen = !!pConInfo->FullScreen;
        GuiInfo.AutoPosition = !!pConInfo->AutoPosition;
        GuiInfo.WindowOrigin = pConInfo->WindowPosition;
        // WORD  GuiInfo.ShowWindow = pConInfo->



        /*
         * If we don't set the default parameters,
         * apply them, otherwise just save them.
         */
#if 0
        if (pConInfo->ShowDefaultParams == FALSE)
#endif
        {
            /* Set the console informations */
            ConSrvApplyUserSettings(Console, &ConInfo);

            /* Set the terminal informations */

            // memcpy(&GuiData->GuiInfo, &GuiInfo, sizeof(GUI_CONSOLE_INFO));

            /* Change the font */
            InitFonts(GuiData,
                      GuiInfo.FaceName,
                      GuiInfo.FontFamily,
                      GuiInfo.FontSize,
                      GuiInfo.FontWeight);
           // HACK, needed because changing font may change the size of the window
           /**/TermResizeTerminal(Console);/**/

            /* Move the window to the user's values */
            GuiData->GuiInfo.AutoPosition = GuiInfo.AutoPosition;
            GuiData->GuiInfo.WindowOrigin = GuiInfo.WindowOrigin;
            GuiConsoleMoveWindow(GuiData);

            InvalidateRect(GuiData->hWindow, NULL, TRUE);

            /*
             * Apply full-screen mode.
             */
            if (GuiInfo.FullScreen != GuiData->GuiInfo.FullScreen)
            {
                SwitchFullScreen(GuiData, GuiInfo.FullScreen);
            }
        }

#if 0
        /*
         * Save settings if needed
         */
        // FIXME: Do it in the console properties applet ??
        if (SaveSettings)
        {
            DWORD ProcessId = HandleToUlong(ProcessData->Process->ClientId.UniqueProcess);
            ConSrvWriteUserSettings(&ConInfo, ProcessId);
            GuiConsoleWriteUserSettings(&GuiInfo, ConInfo.ConsoleTitle, ProcessId);
        }
#endif

        Status = STATUS_SUCCESS;
    }
Beispiel #28
0
// FIXME: Maybe return a NTSTATUS
static BOOL
GuiInit(IN PCONSOLE_INIT_INFO ConsoleInitInfo,
        IN HANDLE ConsoleLeaderProcessHandle,
        IN OUT PGUI_INIT_INFO GuiInitInfo)
{
    BOOL Success = TRUE;
    UNICODE_STRING DesktopPath;
    DESKTOP_CONSOLE_THREAD DesktopConsoleThreadInfo;
    HWINSTA hWinSta;
    HDESK hDesk;

    NTSTATUS Status;
    HANDLE hInputThread;
    CLIENT_ID ClientId;

    /*
     * Initialize and register the console window class, if needed.
     */
    if (!ConsInitialized)
    {
        if (!RegisterConWndClass(ConSrvDllInstance)) return FALSE;
        ConsInitialized = TRUE;
    }

    /*
     * Set-up the console input thread. We have
     * one console input thread per desktop.
     */

    if (!CsrImpersonateClient(NULL))
        // return STATUS_BAD_IMPERSONATION_LEVEL;
        return FALSE;

    if (ConsoleInitInfo->DesktopLength)
    {
        DesktopPath.MaximumLength = ConsoleInitInfo->DesktopLength;
        DesktopPath.Length = DesktopPath.MaximumLength - sizeof(UNICODE_NULL);
        DesktopPath.Buffer = ConsoleInitInfo->Desktop;
    }
    else
    {
        RtlInitUnicodeString(&DesktopPath, L"Default");
    }

    hDesk = NtUserResolveDesktop(ConsoleLeaderProcessHandle,
                                 &DesktopPath,
                                 0,
                                 &hWinSta);
    DPRINT("NtUserResolveDesktop(DesktopPath = '%wZ') returned hDesk = 0x%p; hWinSta = 0x%p\n",
           &DesktopPath, hDesk, hWinSta);

    CsrRevertToSelf();

    if (hDesk == NULL) return FALSE;

    /*
     * We need to see whether we need to create a
     * new console input thread for this desktop.
     */
    DesktopConsoleThreadInfo.DesktopHandle = hDesk;
    DesktopConsoleThreadInfo.ThreadId = (ULONG_PTR)INVALID_HANDLE_VALUE; // Special value to say we just want to retrieve the thread ID.
    NtUserConsoleControl(ConsoleCtrlDesktopConsoleThread,
                         &DesktopConsoleThreadInfo,
                         sizeof(DesktopConsoleThreadInfo));
    DPRINT("NtUserConsoleControl returned ThreadId = 0x%p\n", DesktopConsoleThreadInfo.ThreadId);

    /*
     * Save the opened window station and desktop handles in the initialization
     * structure. They will be used later on, and released, by the GUI frontend.
     */
    GuiInitInfo->WinSta  = hWinSta;
    GuiInitInfo->Desktop = hDesk;

    /* Here GuiInitInfo contains original handles */

    /* If we already have a console input thread on this desktop... */
    if (DesktopConsoleThreadInfo.ThreadId != 0)
    {
        /* ... just use it... */
        DPRINT("Using input thread InputThreadId = 0x%p\n", DesktopConsoleThreadInfo.ThreadId);
        GuiInitInfo->InputThreadId = DesktopConsoleThreadInfo.ThreadId;
        goto Quit;
    }

    /* ... otherwise create a new one. */

    /* Initialize a startup event for the thread to signal it */
    Status = NtCreateEvent(&GuiInitInfo->GuiThreadStartupEvent, EVENT_ALL_ACCESS,
                           NULL, SynchronizationEvent, FALSE);
    if (!NT_SUCCESS(Status))
    {
        Success = FALSE;
        goto Quit;
    }

    /*
     * Duplicate the desktop handle for the console input thread internal needs.
     * If it happens to need also a window station handle in the future, then
     * it is there that you also need to duplicate the window station handle!
     *
     * Note also that we are going to temporarily overwrite the stored handles
     * in GuiInitInfo because it happens that we use also this structure to give
     * the duplicated handles to the input thread that is going to initialize.
     * After the input thread finishes its initialization, we restore the handles
     * in GuiInitInfo to their old values.
     */
    Status = NtDuplicateObject(NtCurrentProcess(),
                               hDesk,
                               NtCurrentProcess(),
                               (PHANDLE)&GuiInitInfo->Desktop,
                               0, 0, DUPLICATE_SAME_ACCESS);
    if (!NT_SUCCESS(Status))
    {
        Success = FALSE;
        goto Quit;
    }

    /* Here GuiInitInfo contains duplicated handles */

    Status = RtlCreateUserThread(NtCurrentProcess(),
                                 NULL,
                                 TRUE, // Start the thread in suspended state
                                 0,
                                 0,
                                 0,
                                 (PVOID)GuiConsoleInputThread,
                                 (PVOID)GuiInitInfo,
                                 &hInputThread,
                                 &ClientId);
    if (NT_SUCCESS(Status))
    {
        /* Add it as a static server thread and resume it */
        CsrAddStaticServerThread(hInputThread, &ClientId, 0);
        Status = NtResumeThread(hInputThread, NULL);
    }
    DPRINT("Thread creation hInputThread = 0x%p, InputThreadId = 0x%p, Status = 0x%08lx\n",
           hInputThread, ClientId.UniqueThread, Status);

    if (!NT_SUCCESS(Status) || hInputThread == NULL)
    {
        /* Close the thread's handle */
        if (hInputThread) NtClose(hInputThread);

        /* We need to close here the duplicated desktop handle */
        CloseDesktop(GuiInitInfo->Desktop); // NtUserCloseDesktop

        /* Close the startup event and bail out */
        NtClose(GuiInitInfo->GuiThreadStartupEvent);

        DPRINT1("CONSRV: Failed to create graphics console thread.\n");
        Success = FALSE;
        goto Quit;
    }

    /* No need to close hInputThread, this is done by CSR automatically */

    /* Wait for the thread to finish its initialization, and close the startup event */
    NtWaitForSingleObject(GuiInitInfo->GuiThreadStartupEvent, FALSE, NULL);
    NtClose(GuiInitInfo->GuiThreadStartupEvent);

    /*
     * Save the input thread ID for later use, and restore the original handles.
     * The copies are held by the console input thread.
     */
    GuiInitInfo->InputThreadId = (ULONG_PTR)ClientId.UniqueThread;
    GuiInitInfo->WinSta  = hWinSta;
    GuiInitInfo->Desktop = hDesk;

    /* Here GuiInitInfo contains again original handles */

Quit:
    if (!Success)
    {
        /*
         * Close the original handles. Do not use the copies in GuiInitInfo
         * because we may have failed in the middle of the duplicate operation
         * and the handles stored in GuiInitInfo may have changed.
         */
        CloseDesktop(hDesk); // NtUserCloseDesktop
        CloseWindowStation(hWinSta); // NtUserCloseWindowStation
    }

    return Success;
}
Beispiel #29
0
NTSTATUS
NTAPI
SmpExecuteInitialCommand(IN ULONG MuSessionId,
                         IN PUNICODE_STRING InitialCommand,
                         IN HANDLE InitialCommandProcess,
                         OUT PHANDLE ReturnPid)
{
    NTSTATUS Status;
    RTL_USER_PROCESS_INFORMATION ProcessInfo;
    UNICODE_STRING Arguments, ImageFileDirectory, ImageFileName;
    ULONG Flags = 0;

    /* Check if we haven't yet connected to ourselves */
    if (!SmApiPort)
    {
        /* Connect to ourselves, as a client */
        Status = SmConnectToSm(0, 0, 0, &SmApiPort);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("SMSS: Unable to connect to SM - Status == %lx\n", Status);
            return Status;
        }
    }

    /* Parse the initial command line */
    Status = SmpParseCommandLine(InitialCommand,
                                 &Flags,
                                 &ImageFileName,
                                 &ImageFileDirectory,
                                 &Arguments);
    if (Flags & SMP_INVALID_PATH)
    {
        /* Fail if it doesn't exist */
        DPRINT1("SMSS: Initial command image (%wZ) not found\n", &ImageFileName);
        if (ImageFileName.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, ImageFileName.Buffer);
        return STATUS_OBJECT_NAME_NOT_FOUND;
    }

    /* And fail if any other reason is also true */
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("SMSS: SmpParseCommandLine( %wZ ) failed - Status == %lx\n",
                InitialCommand, Status);
        return Status;
    }

    /* Execute the initial command -- but defer its full execution */
    Status = SmpExecuteImage(&ImageFileName,
                             &ImageFileDirectory,
                             InitialCommand,
                             MuSessionId,
                             SMP_DEFERRED_FLAG,
                             &ProcessInfo);

    /* Free any buffers we had lying around */
    if (ImageFileName.Buffer)
    {
        RtlFreeHeap(RtlGetProcessHeap(), 0, ImageFileName.Buffer);
    }
    if (ImageFileDirectory.Buffer)
    {
        RtlFreeHeap(RtlGetProcessHeap(), 0, ImageFileDirectory.Buffer);
    }
    if (Arguments.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Arguments.Buffer);

    /* Bail out if we couldn't execute the initial command */
    if (!NT_SUCCESS(Status)) return Status;

    /* Now duplicate the handle to this process */
    Status = NtDuplicateObject(NtCurrentProcess(),
                               ProcessInfo.ProcessHandle,
                               NtCurrentProcess(),
                               InitialCommandProcess,
                               PROCESS_ALL_ACCESS,
                               0,
                               0);
    if (!NT_SUCCESS(Status))
    {
        /* Kill it utterly if duplication failed */
        DPRINT1("SMSS: DupObject Failed. Status == %lx\n", Status);
        NtTerminateProcess(ProcessInfo.ProcessHandle, Status);
        NtResumeThread(ProcessInfo.ThreadHandle, NULL);
        NtClose(ProcessInfo.ThreadHandle);
        NtClose(ProcessInfo.ProcessHandle);
        return Status;
    }

    /* Return PID to the caller, and set this as the initial command PID */
    if (ReturnPid) *ReturnPid = ProcessInfo.ClientId.UniqueProcess;
    if (!MuSessionId) SmpInitialCommandProcessId = ProcessInfo.ClientId.UniqueProcess;

    /* Now call our server execution function to wrap up its initialization */
    Status = SmExecPgm(SmApiPort, &ProcessInfo, FALSE);
    if (!NT_SUCCESS(Status)) DPRINT1("SMSS: SmExecPgm Failed. Status == %lx\n", Status);
    return Status;
}
Beispiel #30
0
BOOL GetProcessIdByMutantName(LPCWSTR mutant_name, std::vector<ULONG> &pids)
{
	_NtQuerySystemInformation NtQuerySystemInformation = 
		(_NtQuerySystemInformation)GetLibraryProcAddress(TEXT("ntdll.dll"), "NtQuerySystemInformation");
	_NtDuplicateObject NtDuplicateObject =
		(_NtDuplicateObject)GetLibraryProcAddress(TEXT("ntdll.dll"), "NtDuplicateObject");
	_NtQueryObject NtQueryObject =
		(_NtQueryObject)GetLibraryProcAddress(TEXT("ntdll.dll"), "NtQueryObject");


	if (NtQuerySystemInformation == NULL || NtDuplicateObject == NULL || NtQueryObject == NULL) {
		return FALSE;
	}

	PSYSTEM_HANDLE_INFORMATION handle_info;
	ULONG handle_info_size = 0x10000;

	CHeapPtr<UCHAR> handle_info_buffer;
	handle_info_buffer.Allocate(handle_info_size);

	NTSTATUS ns;
	while ((ns = NtQuerySystemInformation(
		SystemHandleInformation,
		handle_info_buffer.m_pData,
		handle_info_size,
		NULL
		)) == STATUS_INFO_LENGTH_MISMATCH) {

			handle_info_buffer.Reallocate(handle_info_size *= 2);
	}

	if (!NT_SUCCESS(ns)) {
		return FALSE;
	}

	handle_info = (PSYSTEM_HANDLE_INFORMATION)handle_info_buffer.m_pData;

	ULONG process_id = 0;
	HANDLE cur_handle = NULL;
	for (ULONG i = 0; i < handle_info->HandleCount; i++) {

		SYSTEM_HANDLE handle = handle_info->Handles[i];
		ULONG info_size = 0x1000;

		if (handle.GrantedAccess == 0x0012019f) {
			continue;
		}

		if (process_id != handle.ProcessId) {
			process_id = handle.ProcessId;

			if (cur_handle != NULL) {
				CloseHandle(cur_handle);
				cur_handle = NULL;
			}

			if (cur_handle == NULL) {
				cur_handle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, process_id);
			}

			if (cur_handle == NULL) {
				continue;
			}

		}

		HANDLE dup_handle = NULL;
		if (!NT_SUCCESS(NtDuplicateObject(
			cur_handle,
			(HANDLE)handle.Handle,
			GetCurrentProcess(),
			&dup_handle,
			0,
			0,
			0
			))) {

				continue;
		}

		CHandle auto_handle(dup_handle);
		CHeapPtr<UCHAR> obj_type_buffer;
		obj_type_buffer.Allocate(info_size);
		POBJECT_TYPE_INFORMATION obj_type_info = (POBJECT_TYPE_INFORMATION)obj_type_buffer.m_pData;
		if (!NT_SUCCESS(NtQueryObject(
			dup_handle,
			ObjectTypeInformation,
			obj_type_info,
			info_size,
			NULL
			))) {
				continue;
		}

		if (memcmp(obj_type_info->Name.Buffer, L"Mutant", 12) != 0) {
			continue;
		}

		CHeapPtr<UCHAR> obj_name_buffer;
		obj_name_buffer.Allocate(info_size);
		PVOID obj_name_info = obj_name_buffer.m_pData;
		ULONG return_length;
		if (!NT_SUCCESS(NtQueryObject(
			dup_handle,
			ObjectNameInformation,
			obj_name_info,
			info_size,
			&return_length
			))) {
				continue;
		}

		UNICODE_STRING object_name = *(PUNICODE_STRING)obj_name_info;
		if (object_name.Length) {
			CStringW object_name(object_name.Buffer, object_name.Length / 2); 
			if (object_name == mutant_name) {
				pids.push_back(process_id);
			}
			//wprintf(L"%u %s\n", process_id, object_name.GetString());
		}

	}

	if (cur_handle != NULL) {
		CloseHandle(cur_handle);
		cur_handle = NULL;
	}

	return TRUE;
}