Example #1
1
/*
 * @implemented
 */
BOOL
WINAPI
EmptyWorkingSet(HANDLE hProcess)
{
    SYSTEM_INFO SystemInfo;
    QUOTA_LIMITS QuotaLimits;
    NTSTATUS Status;

    GetSystemInfo(&SystemInfo);

    /* Query the working set */
    Status = NtQueryInformationProcess(hProcess,
                                       ProcessQuotaLimits,
                                       &QuotaLimits,
                                       sizeof(QuotaLimits),
                                       NULL);

    if (!NT_SUCCESS(Status))
    {
        SetLastError(RtlNtStatusToDosError(Status));
        return FALSE;
    }

    /* Empty the working set */
    QuotaLimits.MinimumWorkingSetSize = -1;
    QuotaLimits.MaximumWorkingSetSize = -1;

    /* Set the working set */
    Status = NtSetInformationProcess(hProcess,
                                     ProcessQuotaLimits,
                                     &QuotaLimits,
                                     sizeof(QuotaLimits));
    if (!NT_SUCCESS(Status) && Status != STATUS_PRIVILEGE_NOT_HELD)
    {
        SetLastError(RtlNtStatusToDosError(Status));
        return FALSE;
    }

    return TRUE;
}
Example #2
0
int
_cdecl
_main(int argc,
      char *argv[],
      char *envp[],
      int DebugFlag)
{
    KPRIORITY BasePriority = (8 + 1) + 4;
    NTSTATUS Status;
    //ULONG Response; // see the #if 0
    UNREFERENCED_PARAMETER(envp);
    UNREFERENCED_PARAMETER(DebugFlag);

    /* Set the Priority */
    NtSetInformationProcess(NtCurrentProcess(),
                            ProcessBasePriority,
                            &BasePriority,
                            sizeof(KPRIORITY));

    /* Give us IOPL so that we can access the VGA registers */
    Status = NtSetInformationProcess(NtCurrentProcess(),
                                     ProcessUserModeIOPL,
                                     NULL,
                                     0);
    if (!NT_SUCCESS(Status))
    {
        /* Raise a hard error */
        DPRINT1("CSRSS: Could not raise IOPL, Status: 0x%08lx\n", Status);
#if 0
        Status = NtRaiseHardError(STATUS_IO_PRIVILEGE_FAILED,
                                  0,
                                  0,
                                  NULL,
                                  OptionOk,
                                  &Response);
#endif
    }

    /* Initialize CSR through CSRSRV */
    Status = CsrServerInitialization(argc, argv);
    if (!NT_SUCCESS(Status))
    {
        /* Kill us */
        DPRINT1("CSRSS: Unable to initialize server, Status: 0x%08lx\n", Status);
        NtTerminateProcess(NtCurrentProcess(), Status);
    }

    /* Disable errors */
    CsrpSetDefaultProcessHardErrorMode();

    /* If this is Session 0, make sure killing us bugchecks the system */
    if (NtCurrentPeb()->SessionId == 0) RtlSetProcessIsCritical(TRUE, NULL, FALSE);

    /* Kill this thread. CSRSRV keeps us going */
    NtTerminateThread(NtCurrentThread(), Status);
    return 0;
}
Example #3
0
/*
 * @implemented
 */
BOOL WINAPI
CreateProcessAsUserA(HANDLE hToken,
                     LPCSTR lpApplicationName,
                     LPSTR lpCommandLine,
                     LPSECURITY_ATTRIBUTES lpProcessAttributes,
                     LPSECURITY_ATTRIBUTES lpThreadAttributes,
                     BOOL bInheritHandles,
                     DWORD dwCreationFlags,
                     LPVOID lpEnvironment,
                     LPCSTR lpCurrentDirectory,
                     LPSTARTUPINFOA lpStartupInfo,
                     LPPROCESS_INFORMATION lpProcessInformation)
{
    PROCESS_ACCESS_TOKEN AccessToken;
    NTSTATUS Status;

    TRACE("%p %s %s %p %p %d 0x%08x %p %s %p %p\n", hToken, debugstr_a(lpApplicationName),
        debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
        dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);

    /* Create the process with a suspended main thread */
    if (!CreateProcessA(lpApplicationName,
                        lpCommandLine,
                        lpProcessAttributes,
                        lpThreadAttributes,
                        bInheritHandles,
                        dwCreationFlags | CREATE_SUSPENDED,
                        lpEnvironment,
                        lpCurrentDirectory,
                        lpStartupInfo,
                        lpProcessInformation))
    {
        ERR("CreateProcessA failed! GLE: %d\n", GetLastError());
        return FALSE;
    }

    AccessToken.Token = hToken;
    AccessToken.Thread = NULL;

    /* Set the new process token */
    Status = NtSetInformationProcess(lpProcessInformation->hProcess,
                                     ProcessAccessToken,
                                     (PVOID)&AccessToken,
                                     sizeof(AccessToken));
    if (!NT_SUCCESS (Status))
    {
        ERR("NtSetInformationProcess failed: 0x%08x\n", Status);
        TerminateProcess(lpProcessInformation->hProcess, Status);
        SetLastError(RtlNtStatusToDosError(Status));
        return FALSE;
    }

    /* Resume the main thread */
    if (!(dwCreationFlags & CREATE_SUSPENDED))
    {
        ResumeThread(lpProcessInformation->hThread);
    }

    return TRUE;
}
Example #4
0
/*
 * @implemented
 */
BOOL
WINAPI
SetPriorityClass(HANDLE hProcess,
                 DWORD dwPriorityClass)
{
    NTSTATUS Status;
    PROCESS_PRIORITY_CLASS PriorityClass;

    switch (dwPriorityClass)
    {
        case IDLE_PRIORITY_CLASS:
            PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_IDLE;
            break;

        case BELOW_NORMAL_PRIORITY_CLASS:
            PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_BELOW_NORMAL;
            break;

        case NORMAL_PRIORITY_CLASS:
            PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL;
            break;

        case ABOVE_NORMAL_PRIORITY_CLASS:
            PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL;
            break;

        case HIGH_PRIORITY_CLASS:
            PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_HIGH;
            break;

        case REALTIME_PRIORITY_CLASS:
            PriorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_REALTIME;
            break;

        default:
            SetLastError(ERROR_INVALID_PARAMETER);
            return FALSE;
    }

    PriorityClass.Foreground = FALSE;

    Status = NtSetInformationProcess(hProcess,
                                     ProcessPriorityClass,
                                     &PriorityClass,
                                     sizeof(PROCESS_PRIORITY_CLASS));
    if (!NT_SUCCESS(Status))
    {
        SetLastErrorByStatus(Status);
        return FALSE;
    }

    return TRUE;
}
Example #5
0
/*++
 * @name CsrSetToNormalPriority
 *
 * The CsrSetToNormalPriority routine sets the current NT Process'
 * priority to the normal priority for CSR Processes.
 *
 * @param None.
 *
 * @return None.
 *
 * @remarks The "Normal" Priority corresponds to the Normal Foreground
 *          Priority (9) plus a boost of 4.
 *
 *--*/
VOID
NTAPI
CsrSetToNormalPriority(VOID)
{
    KPRIORITY BasePriority = (8 + 1) + 4;

    /* Set the Priority */
    NtSetInformationProcess(NtCurrentProcess(),
                            ProcessBasePriority,
                            &BasePriority,
                            sizeof(BasePriority));
}
Example #6
0
VOID
NTAPI
CsrpSetDefaultProcessHardErrorMode(VOID)
{
    ULONG DefaultHardErrorMode = 0;

    /* Disable hard errors */
    NtSetInformationProcess(NtCurrentProcess(),
                            ProcessDefaultHardErrorMode,
                            &DefaultHardErrorMode,
                            sizeof(DefaultHardErrorMode));
}
Example #7
0
/*++
 * @name CsrSetForegroundPriority
 * @implemented NT4
 *
 * The CsrSetForegroundPriority routine sets the priority for the given CSR
 * Process as a Foreground priority.
 *
 * @param CsrProcess
 *        Pointer to the CSR Process whose priority will be modified.
 *
 * @return None.
 *
 * @remarks None.
 *
 *--*/
VOID
NTAPI
CsrSetForegroundPriority(IN PCSR_PROCESS CsrProcess)
{
    PROCESS_FOREGROUND_BACKGROUND ProcessPriority;

    /* Set the Foreground bit on */
    ProcessPriority.Foreground = TRUE;

    /* Set the new priority */
    NtSetInformationProcess(CsrProcess->ProcessHandle,
                            ProcessForegroundInformation,
                            &ProcessPriority,
                            sizeof(ProcessPriority));
}
Example #8
0
/*
 * @implemented
 */
BOOL
WINAPI
SetProcessAffinityMask(HANDLE hProcess,
                       DWORD_PTR dwProcessAffinityMask)
{
    NTSTATUS Status;

    Status = NtSetInformationProcess(hProcess,
                                     ProcessAffinityMask,
                                     (PVOID)&dwProcessAffinityMask,
                                     sizeof(DWORD));
    if (!NT_SUCCESS(Status))
    {
        SetLastErrorByStatus(Status);
        return FALSE;
    }

    return TRUE;
}
Example #9
0
/*
 * @implemented
 */
BOOL
WINAPI
SetProcessPriorityBoost(HANDLE hProcess,
                        BOOL bDisablePriorityBoost)
{
    NTSTATUS Status;
    ULONG PriorityBoost = (bDisablePriorityBoost ? TRUE : FALSE); /* prevent setting values other than 1 and 0 */

    Status = NtSetInformationProcess(hProcess,
                                     ProcessPriorityBoost,
                                     &PriorityBoost,
                                     sizeof(ULONG));
    if (!NT_SUCCESS(Status))
    {
        SetLastErrorByStatus(Status);
        return FALSE;
    }

    return TRUE;
}
Example #10
0
/*++
 * @name CsrSetToShutdownPriority
 *
 * The CsrSetToShutdownPriority routine sets the current NT Process'
 * priority to the boosted priority for CSR Processes doing shutdown.
 * Additonally, it acquires the Shutdown Privilege required for shutdown.
 *
 * @param None.
 *
 * @return None.
 *
 * @remarks The "Shutdown" Priority corresponds to the Normal Foreground
 *          Priority (9) plus a boost of 6.
 *
 *--*/
VOID
NTAPI
CsrSetToShutdownPriority(VOID)
{
    KPRIORITY BasePriority = (8 + 1) + 6;
    BOOLEAN Old;

    /* Get the shutdown privilege */
    if (NT_SUCCESS(RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE,
                                      TRUE,
                                      FALSE,
                                      &Old)))
    {
        /* Set the Priority */
        NtSetInformationProcess(NtCurrentProcess(),
                                ProcessBasePriority,
                                &BasePriority,
                                sizeof(BasePriority));
    }
}
Example #11
0
NTSYSAPI
NTSTATUS
STDAPIVCALLTYPE
RtlSetProcessIsCritical(
    IN  BOOLEAN  NewValue,
    OUT PBOOLEAN OldValue OPTIONAL,
    IN  BOOLEAN  CheckFlag
    )
{
    PPEB     Peb;
    ULONG    Enable;
    NTSTATUS Status;

    if ( ARGUMENT_PRESENT(OldValue) ) {
        *OldValue = FALSE;
    }

    Peb = RtlGetCurrentPeb();
    if ( CheckFlag
         && ! (Peb->NtGlobalFlag & FLG_ENABLE_SYSTEM_CRIT_BREAKS) ) {
        return STATUS_UNSUCCESSFUL;
    }
    if ( ARGUMENT_PRESENT(OldValue) ) {
        NtQueryInformationProcess(NtCurrentProcess(),
                                  ProcessBreakOnTermination,
                                  &Enable,
                                  sizeof(Enable),
                                  NULL);

        *OldValue = (BOOLEAN) Enable;
    }

    Enable = NewValue;

    Status = NtSetInformationProcess(NtCurrentProcess(),
                                     ProcessBreakOnTermination,
                                     &Enable,
                                     sizeof(Enable));

    return Status;
}
Example #12
0
NTSTATUS
NTAPI
SmpSetProcessMuSessionId(IN HANDLE ProcessHandle,
                         IN ULONG SessionId)
{
    NTSTATUS Status;

    /* Tell the kernel about the session ID */
    Status = NtSetInformationProcess(ProcessHandle,
                                     ProcessSessionInformation,
                                     &SessionId,
                                     sizeof(SessionId));
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("SMSS: SetProcessMuSessionId, Process=%p, Status=%x\n",
                ProcessHandle, Status);
    }

    /* Return */
    return Status;
}
Example #13
0
/*
 * @implemented
 */
BOOL
WINAPI
SetProcessWorkingSetSize(HANDLE hProcess,
                         SIZE_T dwMinimumWorkingSetSize,
                         SIZE_T dwMaximumWorkingSetSize)
{
    QUOTA_LIMITS QuotaLimits;
    NTSTATUS Status;

    QuotaLimits.MinimumWorkingSetSize = dwMinimumWorkingSetSize;
    QuotaLimits.MaximumWorkingSetSize = dwMaximumWorkingSetSize;

    Status = NtSetInformationProcess(hProcess,
                                     ProcessQuotaLimits,
                                     &QuotaLimits,
                                     sizeof(QUOTA_LIMITS));
    if (!NT_SUCCESS(Status))
    {
        SetLastErrorByStatus(Status);
        return FALSE;
    }

    return TRUE;
}
Example #14
0
/*++
 * @name CsrSbCreateSession
 *
 * The CsrSbCreateSession API is called by the Session Manager whenever a new
 * session is created.
 *
 * @param ApiMessage
 *        Pointer to the Session Manager API Message.
 *
 * @return TRUE in case of success, FALSE otherwise.
 *
 * @remarks The CsrSbCreateSession routine will initialize a new CSR NT
 *          Session and allocate a new CSR Process for the subsystem process.
 *
 *--*/
BOOLEAN
NTAPI
CsrSbCreateSession(IN PSB_API_MSG ApiMessage)
{
    PSB_CREATE_SESSION_MSG CreateSession = &ApiMessage->CreateSession;
    HANDLE hProcess, hThread;
    PCSR_PROCESS CsrProcess;
    NTSTATUS Status;
    KERNEL_USER_TIMES KernelTimes;
    PCSR_THREAD CsrThread;
    //PVOID ProcessData;
    //ULONG i;

    /* Save the Process and Thread Handles */
    hProcess = CreateSession->ProcessInfo.ProcessHandle;
    hThread = CreateSession->ProcessInfo.ThreadHandle;

    /* Lock the Processes */
    CsrAcquireProcessLock();

    /* Allocate a new process */
    CsrProcess = CsrAllocateProcess();
    if (!CsrProcess)
    {
        /* Fail */
        ApiMessage->ReturnValue = STATUS_NO_MEMORY;
        CsrReleaseProcessLock();
        return TRUE;
    }

    /* Set the exception port */
    Status = NtSetInformationProcess(hProcess,
                                     ProcessExceptionPort,
                                     &CsrApiPort,
                                     sizeof(HANDLE));

    /* Check for success */
    if (!NT_SUCCESS(Status))
    {
        /* Fail the request */
        CsrDeallocateProcess(CsrProcess);
        CsrReleaseProcessLock();

        /* Strange as it seems, NTSTATUSes are actually returned */
        return (BOOLEAN)STATUS_NO_MEMORY;
    }

    /* Get the Create Time */
    Status = NtQueryInformationThread(hThread,
                                      ThreadTimes,
                                      &KernelTimes,
                                      sizeof(KERNEL_USER_TIMES),
                                      NULL);

    /* Check for success */
    if (!NT_SUCCESS(Status))
    {
        /* Fail the request */
        CsrDeallocateProcess(CsrProcess);
        CsrReleaseProcessLock();

        /* Strange as it seems, NTSTATUSes are actually returned */
        return (BOOLEAN)Status;
    }

    /* Allocate a new Thread */
    CsrThread = CsrAllocateThread(CsrProcess);
    if (!CsrThread)
    {
        /* Fail the request */
        CsrDeallocateProcess(CsrProcess);
        CsrReleaseProcessLock();

        ApiMessage->ReturnValue = STATUS_NO_MEMORY;
        return TRUE;
    }

    /* Setup the Thread Object */
    CsrThread->CreateTime = KernelTimes.CreateTime;
    CsrThread->ClientId = CreateSession->ProcessInfo.ClientId;
    CsrThread->ThreadHandle = hThread;
    ProtectHandle(hThread);
    CsrThread->Flags = 0;

    /* Insert it into the Process List */
    CsrInsertThread(CsrProcess, CsrThread);

    /* Setup Process Data */
    CsrProcess->ClientId = CreateSession->ProcessInfo.ClientId;
    CsrProcess->ProcessHandle = hProcess;
    CsrProcess->NtSession = CsrAllocateNtSession(CreateSession->SessionId);

    /* Set the Process Priority */
    CsrSetBackgroundPriority(CsrProcess);
#if 0
    /* Get the first data location */
    ProcessData = &CsrProcess->ServerData[CSR_SERVER_DLL_MAX];

    /* Loop every DLL */
    for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
    {
        /* Check if the DLL is loaded and has Process Data */
        if (CsrLoadedServerDll[i] && CsrLoadedServerDll[i]->SizeOfProcessData)
        {
            /* Write the pointer to the data */
            CsrProcess->ServerData[i] = ProcessData;

            /* Move to the next data location */
            ProcessData = (PVOID)((ULONG_PTR)ProcessData +
                                  CsrLoadedServerDll[i]->SizeOfProcessData);
        }
        else
        {
            /* Nothing for this Process */
            CsrProcess->ServerData[i] = NULL;
        }
    }
#else
    /* HACKZ: should go in BaseSrv part of CreateCallback done in Insert below */
    RtlInitializeCriticalSection(&CsrProcess->HandleTableLock);
#endif
    /* Insert the Process */
    CsrInsertProcess(NULL, NULL, CsrProcess);

    /* Activate the Thread */
    ApiMessage->ReturnValue = NtResumeThread(hThread, NULL);

    /* Release lock and return */
    CsrReleaseProcessLock();
    return TRUE;
}
Example #15
0
INT WINAPI wWinMain(
    _In_ HINSTANCE hInstance,
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ PWSTR lpCmdLine,
    _In_ INT nCmdShow
)
{
    LONG result;
#ifdef DEBUG
    PHP_BASE_THREAD_DBG dbg;
#endif

    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
#ifndef DEBUG
    SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
#endif

    PhInstanceHandle = (HINSTANCE)NtCurrentPeb()->ImageBaseAddress;

    if (!NT_SUCCESS(PhInitializePhLib()))
        return 1;
    if (!PhInitializeAppSystem())
        return 1;

    PhInitializeCommonControls();

    if (PhCurrentTokenQueryHandle)
    {
        PTOKEN_USER tokenUser;

        if (NT_SUCCESS(PhGetTokenUser(PhCurrentTokenQueryHandle, &tokenUser)))
        {
            PhCurrentUserName = PhGetSidFullName(tokenUser->User.Sid, TRUE, NULL);
            PhFree(tokenUser);
        }
    }

    PhLocalSystemName = PhGetSidFullName(&PhSeLocalSystemSid, TRUE, NULL);

    // There has been a report of the above call failing.
    if (!PhLocalSystemName)
        PhLocalSystemName = PhCreateString(L"NT AUTHORITY\\SYSTEM");

    PhApplicationFileName = PhGetApplicationFileName();
    PhApplicationDirectory = PhGetApplicationDirectory();

    // Just in case
    if (!PhApplicationFileName)
        PhApplicationFileName = PhCreateString(L"ProcessHacker.exe");
    if (!PhApplicationDirectory)
        PhApplicationDirectory = PhReferenceEmptyString();

    PhpProcessStartupParameters();
    PhSettingsInitialization();
    PhpEnablePrivileges();

    if (PhStartupParameters.RunAsServiceMode)
    {
        RtlExitUserProcess(PhRunAsServiceStart(PhStartupParameters.RunAsServiceMode));
    }

    PhpInitializeSettings();

    // Activate a previous instance if required.
    if (PhGetIntegerSetting(L"AllowOnlyOneInstance") &&
            !PhStartupParameters.NewInstance &&
            !PhStartupParameters.ShowOptions &&
            !PhStartupParameters.CommandMode &&
            !PhStartupParameters.PhSvc)
    {
        PhActivatePreviousInstance();
    }

    if (PhGetIntegerSetting(L"EnableKph") && !PhStartupParameters.NoKph && !PhIsExecutingInWow64())
        PhInitializeKph();

    if (PhStartupParameters.CommandMode && PhStartupParameters.CommandType && PhStartupParameters.CommandAction)
    {
        NTSTATUS status;

        status = PhCommandModeStart();

        if (!NT_SUCCESS(status) && !PhStartupParameters.Silent)
        {
            PhShowStatus(NULL, L"Unable to execute the command", status, 0);
        }

        RtlExitUserProcess(status);
    }

#ifdef DEBUG
    dbg.ClientId = NtCurrentTeb()->ClientId;
    dbg.StartAddress = wWinMain;
    dbg.Parameter = NULL;
    InsertTailList(&PhDbgThreadListHead, &dbg.ListEntry);
    TlsSetValue(PhDbgThreadDbgTlsIndex, &dbg);
#endif

    PhInitializeAutoPool(&BaseAutoPool);

    PhEmInitialization();
    PhGuiSupportInitialization();
    PhTreeNewInitialization();
    PhGraphControlInitialization();
    PhHexEditInitialization();
    PhColorBoxInitialization();

    PhSmallIconSize.X = GetSystemMetrics(SM_CXSMICON);
    PhSmallIconSize.Y = GetSystemMetrics(SM_CYSMICON);
    PhLargeIconSize.X = GetSystemMetrics(SM_CXICON);
    PhLargeIconSize.Y = GetSystemMetrics(SM_CYICON);

    if (PhStartupParameters.ShowOptions)
    {
        // Elevated options dialog for changing the value of Replace Task Manager with Process Hacker.
        PhShowOptionsDialog(PhStartupParameters.WindowHandle);
        RtlExitUserProcess(STATUS_SUCCESS);
    }

#ifndef DEBUG
    if (PhIsExecutingInWow64() && !PhStartupParameters.PhSvc)
    {
        PhShowWarning(
            NULL,
            L"You are attempting to run the 32-bit version of Process Hacker on 64-bit Windows. "
            L"Most features will not work correctly.\n\n"
            L"Please run the 64-bit version of Process Hacker instead."
        );
    }
#endif

    PhPluginsEnabled = PhGetIntegerSetting(L"EnablePlugins") && !PhStartupParameters.NoPlugins;

    if (PhPluginsEnabled)
    {
        PhPluginsInitialization();
        PhLoadPlugins();
    }

    if (PhStartupParameters.PhSvc)
    {
        MSG message;

        // Turn the feedback cursor off.
        PostMessage(NULL, WM_NULL, 0, 0);
        GetMessage(&message, NULL, 0, 0);

        RtlExitUserProcess(PhSvcMain(NULL, NULL, NULL));
    }

    // Create a mutant for the installer.
    {
        HANDLE mutantHandle;
        OBJECT_ATTRIBUTES oa;
        UNICODE_STRING mutantName;

        RtlInitUnicodeString(&mutantName, L"\\BaseNamedObjects\\ProcessHacker2Mutant");
        InitializeObjectAttributes(
            &oa,
            &mutantName,
            0,
            NULL,
            NULL
        );

        NtCreateMutant(&mutantHandle, MUTANT_ALL_ACCESS, &oa, FALSE);
    }

    // Set priority.
    {
        PROCESS_PRIORITY_CLASS priorityClass;

        priorityClass.Foreground = FALSE;
        priorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_HIGH;

        if (PhStartupParameters.PriorityClass != 0)
            priorityClass.PriorityClass = (UCHAR)PhStartupParameters.PriorityClass;

        NtSetInformationProcess(NtCurrentProcess(), ProcessPriorityClass, &priorityClass, sizeof(PROCESS_PRIORITY_CLASS));
    }

    if (!PhMainWndInitialization(nCmdShow))
    {
        PhShowError(NULL, L"Unable to initialize the main window.");
        return 1;
    }

    PhDrainAutoPool(&BaseAutoPool);

    result = PhMainMessageLoop();
    RtlExitUserProcess(result);
}
Example #16
0
NTSTATUS PhCommandModeStart(
    VOID
    )
{
    static PH_COMMAND_LINE_OPTION options[] =
    {
        { PH_COMMAND_OPTION_HWND, L"hwnd", MandatoryArgumentType }
    };
    NTSTATUS status;
    PPH_STRING commandLine;

    if (!NT_SUCCESS(status = PhGetProcessCommandLine(NtCurrentProcess(), &commandLine)))
        return status;

    PhParseCommandLine(
        &commandLine->sr,
        options,
        sizeof(options) / sizeof(PH_COMMAND_LINE_OPTION),
        PH_COMMAND_LINE_IGNORE_UNKNOWN_OPTIONS,
        PhpCommandModeOptionCallback,
        NULL
        );
    PhDereferenceObject(commandLine);

    if (PhEqualString2(PhStartupParameters.CommandType, L"process", TRUE))
    {
        SIZE_T i;
        SIZE_T processIdLength;
        HANDLE processId;
        HANDLE processHandle;

        if (!PhStartupParameters.CommandObject)
            return STATUS_INVALID_PARAMETER;

        processIdLength = PhStartupParameters.CommandObject->Length / 2;

        for (i = 0; i < processIdLength; i++)
        {
            if (!PhIsDigitCharacter(PhStartupParameters.CommandObject->Buffer[i]))
                break;
        }

        if (i == processIdLength)
        {
            ULONG64 processId64;

            if (!PhStringToInteger64(&PhStartupParameters.CommandObject->sr, 10, &processId64))
                return STATUS_INVALID_PARAMETER;

            processId = (HANDLE)processId64;
        }
        else
        {
            PVOID processes;
            PSYSTEM_PROCESS_INFORMATION process;

            if (!NT_SUCCESS(status = PhEnumProcesses(&processes)))
                return status;

            if (!(process = PhFindProcessInformationByImageName(processes, &PhStartupParameters.CommandObject->sr)))
            {
                PhFree(processes);
                return STATUS_NOT_FOUND;
            }

            processId = process->UniqueProcessId;
            PhFree(processes);
        }

        if (PhEqualString2(PhStartupParameters.CommandAction, L"terminate", TRUE))
        {
            if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_TERMINATE, processId)))
            {
                status = NtTerminateProcess(processHandle, STATUS_SUCCESS);
                NtClose(processHandle);
            }
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"suspend", TRUE))
        {
            if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SUSPEND_RESUME, processId)))
            {
                status = NtSuspendProcess(processHandle);
                NtClose(processHandle);
            }
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"resume", TRUE))
        {
            if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SUSPEND_RESUME, processId)))
            {
                status = NtResumeProcess(processHandle);
                NtClose(processHandle);
            }
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"priority", TRUE))
        {
            UCHAR priority;

            if (!PhStartupParameters.CommandValue)
                return STATUS_INVALID_PARAMETER;

            if (PhEqualString2(PhStartupParameters.CommandValue, L"idle", TRUE))
                priority = PROCESS_PRIORITY_CLASS_IDLE;
            else if (PhEqualString2(PhStartupParameters.CommandValue, L"normal", TRUE))
                priority = PROCESS_PRIORITY_CLASS_NORMAL;
            else if (PhEqualString2(PhStartupParameters.CommandValue, L"high", TRUE))
                priority = PROCESS_PRIORITY_CLASS_HIGH;
            else if (PhEqualString2(PhStartupParameters.CommandValue, L"realtime", TRUE))
                priority = PROCESS_PRIORITY_CLASS_REALTIME;
            else if (PhEqualString2(PhStartupParameters.CommandValue, L"abovenormal", TRUE))
                priority = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL;
            else if (PhEqualString2(PhStartupParameters.CommandValue, L"belownormal", TRUE))
                priority = PROCESS_PRIORITY_CLASS_BELOW_NORMAL;
            else
                return STATUS_INVALID_PARAMETER;

            if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SET_INFORMATION, processId)))
            {
                PROCESS_PRIORITY_CLASS priorityClass;
                priorityClass.Foreground = FALSE;
                priorityClass.PriorityClass = priority;
                status = NtSetInformationProcess(processHandle, ProcessPriorityClass, &priorityClass, sizeof(PROCESS_PRIORITY_CLASS));
                NtClose(processHandle);
            }
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"iopriority", TRUE))
        {
            ULONG ioPriority;

            if (!PhStartupParameters.CommandValue)
                return STATUS_INVALID_PARAMETER;

            if (PhEqualString2(PhStartupParameters.CommandValue, L"verylow", TRUE))
                ioPriority = 0;
            else if (PhEqualString2(PhStartupParameters.CommandValue, L"low", TRUE))
                ioPriority = 1;
            else if (PhEqualString2(PhStartupParameters.CommandValue, L"normal", TRUE))
                ioPriority = 2;
            else if (PhEqualString2(PhStartupParameters.CommandValue, L"high", TRUE))
                ioPriority = 3;
            else
                return STATUS_INVALID_PARAMETER;

            if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SET_INFORMATION, processId)))
            {
                status = PhSetProcessIoPriority(processHandle, ioPriority);
                NtClose(processHandle);
            }
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"pagepriority", TRUE))
        {
            ULONG64 pagePriority64;
            ULONG pagePriority;

            if (!PhStartupParameters.CommandValue)
                return STATUS_INVALID_PARAMETER;

            PhStringToInteger64(&PhStartupParameters.CommandValue->sr, 10, &pagePriority64);
            pagePriority = (ULONG)pagePriority64;

            if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SET_INFORMATION, processId)))
            {
                status = NtSetInformationProcess(
                    processHandle,
                    ProcessPagePriority,
                    &pagePriority,
                    sizeof(ULONG)
                    );
                NtClose(processHandle);
            }
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"injectdll", TRUE))
        {
            if (!PhStartupParameters.CommandValue)
                return STATUS_INVALID_PARAMETER;

            if (NT_SUCCESS(status = PhOpenProcessPublic(
                &processHandle,
                ProcessQueryAccess | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE,
                processId
                )))
            {
                LARGE_INTEGER timeout;

                timeout.QuadPart = -5 * PH_TIMEOUT_SEC;
                status = PhInjectDllProcess(
                    processHandle,
                    PhStartupParameters.CommandValue->Buffer,
                    &timeout
                    );
                NtClose(processHandle);
            }
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"unloaddll", TRUE))
        {
            if (!PhStartupParameters.CommandValue)
                return STATUS_INVALID_PARAMETER;

            if (NT_SUCCESS(status = PhOpenProcessPublic(
                &processHandle,
                ProcessQueryAccess | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE,
                processId
                )))
            {
                PVOID baseAddress;

                if (NT_SUCCESS(status = PhpGetDllBaseRemote(
                    processHandle,
                    &PhStartupParameters.CommandValue->sr,
                    &baseAddress
                    )))
                {
                    LARGE_INTEGER timeout;

                    timeout.QuadPart = -5 * PH_TIMEOUT_SEC;
                    status = PhUnloadDllProcess(
                        processHandle,
                        baseAddress,
                        &timeout
                        );
                }

                NtClose(processHandle);
            }
        }
    }
    else if (PhEqualString2(PhStartupParameters.CommandType, L"service", TRUE))
    {
        SC_HANDLE serviceHandle;
        SERVICE_STATUS serviceStatus;

        if (!PhStartupParameters.CommandObject)
            return STATUS_INVALID_PARAMETER;

        if (PhEqualString2(PhStartupParameters.CommandAction, L"start", TRUE))
        {
            if (!(serviceHandle = PhOpenService(
                PhStartupParameters.CommandObject->Buffer,
                SERVICE_START
                )))
                return PhGetLastWin32ErrorAsNtStatus();

            if (!StartService(serviceHandle, 0, NULL))
                status = PhGetLastWin32ErrorAsNtStatus();

            CloseServiceHandle(serviceHandle);
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"continue", TRUE))
        {
            if (!(serviceHandle = PhOpenService(
                PhStartupParameters.CommandObject->Buffer,
                SERVICE_PAUSE_CONTINUE
                )))
                return PhGetLastWin32ErrorAsNtStatus();

            if (!ControlService(serviceHandle, SERVICE_CONTROL_CONTINUE, &serviceStatus))
                status = PhGetLastWin32ErrorAsNtStatus();

            CloseServiceHandle(serviceHandle);
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"pause", TRUE))
        {
            if (!(serviceHandle = PhOpenService(
                PhStartupParameters.CommandObject->Buffer,
                SERVICE_PAUSE_CONTINUE
                )))
                return PhGetLastWin32ErrorAsNtStatus();

            if (!ControlService(serviceHandle, SERVICE_CONTROL_PAUSE, &serviceStatus))
                status = PhGetLastWin32ErrorAsNtStatus();

            CloseServiceHandle(serviceHandle);
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"stop", TRUE))
        {
            if (!(serviceHandle = PhOpenService(
                PhStartupParameters.CommandObject->Buffer,
                SERVICE_STOP
                )))
                return PhGetLastWin32ErrorAsNtStatus();

            if (!ControlService(serviceHandle, SERVICE_CONTROL_STOP, &serviceStatus))
                status = PhGetLastWin32ErrorAsNtStatus();

            CloseServiceHandle(serviceHandle);
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"delete", TRUE))
        {
            if (!(serviceHandle = PhOpenService(
                PhStartupParameters.CommandObject->Buffer,
                DELETE
                )))
                return PhGetLastWin32ErrorAsNtStatus();

            if (!DeleteService(serviceHandle))
                status = PhGetLastWin32ErrorAsNtStatus();

            CloseServiceHandle(serviceHandle);
        }
    }
    else if (PhEqualString2(PhStartupParameters.CommandType, L"thread", TRUE))
    {
        ULONG64 threadId64;
        HANDLE threadId;
        HANDLE threadHandle;

        if (!PhStartupParameters.CommandObject)
            return STATUS_INVALID_PARAMETER;

        if (!PhStringToInteger64(&PhStartupParameters.CommandObject->sr, 10, &threadId64))
            return STATUS_INVALID_PARAMETER;

        threadId = (HANDLE)threadId64;

        if (PhEqualString2(PhStartupParameters.CommandAction, L"terminate", TRUE))
        {
            if (NT_SUCCESS(status = PhOpenThreadPublic(&threadHandle, THREAD_TERMINATE, threadId)))
            {
                status = NtTerminateThread(threadHandle, STATUS_SUCCESS);
                NtClose(threadHandle);
            }
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"suspend", TRUE))
        {
            if (NT_SUCCESS(status = PhOpenThreadPublic(&threadHandle, THREAD_SUSPEND_RESUME, threadId)))
            {
                status = NtSuspendThread(threadHandle, NULL);
                NtClose(threadHandle);
            }
        }
        else if (PhEqualString2(PhStartupParameters.CommandAction, L"resume", TRUE))
        {
            if (NT_SUCCESS(status = PhOpenThreadPublic(&threadHandle, THREAD_SUSPEND_RESUME, threadId)))
            {
                status = NtResumeThread(threadHandle, NULL);
                NtClose(threadHandle);
            }
        }
    }

    return status;
}
Example #17
0
NTSTATUS
NTAPI
SmpSbCreateSession(IN PVOID Reserved,
                   IN PSMP_SUBSYSTEM OtherSubsystem,
                   IN PRTL_USER_PROCESS_INFORMATION ProcessInformation,
                   IN ULONG MuSessionId,
                   IN PCLIENT_ID DbgClientId)
{
    NTSTATUS Status;
    PSMP_SUBSYSTEM KnownSubsys;
    SB_API_MSG SbApiMsg;
    ULONG SessionId;
    PSB_CREATE_SESSION_MSG CreateSessionMsg;

    /* Write out the create session message including its initial process */
    CreateSessionMsg = &SbApiMsg.CreateSession;
    CreateSessionMsg->ProcessInfo = *ProcessInformation;
    CreateSessionMsg->MuSessionId = MuSessionId;
    if (DbgClientId)
    {
        CreateSessionMsg->ClientId = *DbgClientId;
    }
    else
    {
        CreateSessionMsg->ClientId.UniqueThread = NULL;
        CreateSessionMsg->ClientId.UniqueProcess = NULL;
    }

    /* Find a subsystem responsible for this session */
    SmpGetProcessMuSessionId(ProcessInformation->ProcessHandle, &MuSessionId);
    if (!SmpCheckDuplicateMuSessionId(MuSessionId))
    {
        NtClose(ProcessInformation->ProcessHandle);
        NtClose(ProcessInformation->ThreadHandle);
        DPRINT1("SMSS: CreateSession status=%x\n", STATUS_OBJECT_NAME_NOT_FOUND);
        return STATUS_OBJECT_NAME_NOT_FOUND;
    }

    /* Find the subsystem we have for this initial process */
    KnownSubsys = SmpLocateKnownSubSysByType(MuSessionId,
                                             ProcessInformation->
                                             ImageInformation.SubSystemType);
    if (KnownSubsys)
    {
        /* Duplicate the process handle into the message */
        Status = NtDuplicateObject(NtCurrentProcess(),
                                   ProcessInformation->ProcessHandle,
                                   KnownSubsys->ProcessHandle,
                                   &CreateSessionMsg->ProcessInfo.ProcessHandle,
                                   PROCESS_ALL_ACCESS,
                                   0,
                                   0);
        if (NT_SUCCESS(Status))
        {
            /* Duplicate the thread handle into the message */
            Status = NtDuplicateObject(NtCurrentProcess(),
                                       ProcessInformation->ThreadHandle,
                                       KnownSubsys->ProcessHandle,
                                       &CreateSessionMsg->ProcessInfo.ThreadHandle,
                                       THREAD_ALL_ACCESS,
                                       0,
                                       0);
            if (!NT_SUCCESS(Status))
            {
                /* Close everything on failure */
                NtClose(ProcessInformation->ProcessHandle);
                NtClose(ProcessInformation->ThreadHandle);
                SmpDereferenceSubsystem(KnownSubsys);
                DbgPrint("SmpSbCreateSession: NtDuplicateObject (Thread) Failed %lx\n", Status);
                return Status;
            }

            /* Close the original handles as they are no longer needed */
            NtClose(ProcessInformation->ProcessHandle);
            NtClose(ProcessInformation->ThreadHandle);

            /* Finally, allocate a new SMSS session ID for this session */
            SessionId = SmpAllocateSessionId(KnownSubsys, OtherSubsystem);
            CreateSessionMsg->SessionId = SessionId;

            /* Fill out the LPC message header and send it to the client! */
            SbApiMsg.ApiNumber = SbpCreateSession;
            SbApiMsg.h.u2.ZeroInit = 0;
            SbApiMsg.h.u1.s1.DataLength = sizeof(SB_CREATE_SESSION_MSG) + 8;
            SbApiMsg.h.u1.s1.TotalLength = sizeof(SbApiMsg);
            Status = NtRequestWaitReplyPort(KnownSubsys->SbApiPort,
                                            &SbApiMsg.h,
                                            &SbApiMsg.h);
            if (!NT_SUCCESS(Status))
            {
                /* Bail out */
                DPRINT1("SmpSbCreateSession: NtRequestWaitReply Failed %lx\n", Status);
            }
            else
            {
                /* If the API succeeded, get the result value from the LPC */
                Status = SbApiMsg.ReturnValue;
            }

            /* Delete the session on any kind of failure */
            if (!NT_SUCCESS(Status)) SmpDeleteSession(SessionId);
        }
        else
        {
            /* Close the handles on failure */
            DPRINT1("SmpSbCreateSession: NtDuplicateObject (Process) Failed %lx\n", Status);
            NtClose(ProcessInformation->ProcessHandle);
            NtClose(ProcessInformation->ThreadHandle);
        }

        /* Dereference the subsystem and return the status of the LPC call */
        SmpDereferenceSubsystem(KnownSubsys);
        return Status;
    }

    /* If we don't yet have a subsystem, only native images can be launched */
    if (ProcessInformation->ImageInformation.SubSystemType != IMAGE_SUBSYSTEM_NATIVE)
    {
        /* Fail */
        DPRINT1("SMSS: %s SubSystem has not been started.\n",
                SmpSubSystemNames[ProcessInformation->ImageInformation.SubSystemType]);
        Status = STATUS_UNSUCCESSFUL;
        NtClose(ProcessInformation->ProcessHandle);
        NtClose(ProcessInformation->ThreadHandle);
        return Status;
    }

#if 0
    /* This code handles debug applications, but it seems vestigial... */
    if ((*(ULONGLONG)&CreateSessionMsg.ClientId) && (SmpDbgSsLoaded))
    {
        Process = RtlAllocateHeap(SmpHeap, SmBaseTag, sizeof(SMP_PROCESS));
        if (!Process)
        {
            DPRINT1("Unable to initialize debugging for Native App %lx.%lx -- out of memory\n",
                    ProcessInformation->ClientId.UniqueProcess,
                    ProcessInformation->ClientId.UniqueThread);
            NtClose(ProcessInformation->ProcessHandle);
            NtClose(ProcessInformation->ThreadHandle);
            return STATUS_NO_MEMORY;
        }

        Process->DbgClientId = CreateSessionMsg->ClientId;
        Process->ClientId = ProcessInformation->ClientId;
        InsertHeadList(&NativeProcessList, &Process->Entry);
        DPRINT1("Native Debug App %lx.%lx\n", Process->ClientId.UniqueProcess, Process->ClientId.UniqueThread);

        Status = NtSetInformationProcess(ProcessInformation->ProcessHandle, 7, &SmpDebugPort, 4);
        ASSERT(NT_SUCCESS(Status));
    }
#endif

    /* This is a native application being started as the initial command */
    DPRINT1("Subsystem active, starting thread\n");
    NtClose(ProcessInformation->ProcessHandle);
    NtResumeThread(ProcessInformation->ThreadHandle, NULL);
    NtClose(ProcessInformation->ThreadHandle);
    return STATUS_SUCCESS;
}
Example #18
0
/*++
 * @name CsrCreateProcess
 * @implemented NT4
 *
 * The CsrCreateProcess routine creates a CSR Process object for an NT Process.
 *
 * @param hProcess
 *        Handle to an existing NT Process to which to associate this
 *        CSR Process.
 *
 * @param hThread
 *        Handle to an existing NT Thread to which to create its
 *        corresponding CSR Thread for this CSR Process.
 *
 * @param ClientId
 *        Pointer to the Client ID structure of the NT Process to associate
 *        with this CSR Process.
 *
 * @param NtSession
 * @param Flags
 * @param DebugCid
 *
 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise.
 *
 * @remarks None.
 *
 *--*/
NTSTATUS
NTAPI
CsrCreateProcess(IN HANDLE hProcess,
                 IN HANDLE hThread,
                 IN PCLIENT_ID ClientId,
                 IN PCSR_NT_SESSION NtSession,
                 IN ULONG Flags,
                 IN PCLIENT_ID DebugCid)
{
    PCSR_THREAD CurrentThread = CsrGetClientThread();
    CLIENT_ID CurrentCid;
    PCSR_PROCESS CurrentProcess;
    PCSR_SERVER_DLL ServerDll;
    PVOID ProcessData;
    ULONG i;
    PCSR_PROCESS CsrProcess;
    NTSTATUS Status;
    PCSR_THREAD CsrThread;
    KERNEL_USER_TIMES KernelTimes;

    /* Get the current CID and lock Processes */
    CurrentCid = CurrentThread->ClientId;
    CsrAcquireProcessLock();

    /* Get the current CSR Thread */
    CurrentThread = CsrLocateThreadByClientId(&CurrentProcess, &CurrentCid);
    if (!CurrentThread)
    {
        /* We've failed to locate the thread */
        CsrReleaseProcessLock();
        return STATUS_THREAD_IS_TERMINATING;
    }

    /* Allocate a new Process Object */
    CsrProcess = CsrAllocateProcess();
    if (!CsrProcess)
    {
        /* Couldn't allocate Process */
        CsrReleaseProcessLock();
        return STATUS_NO_MEMORY;
    }

    /* Inherit the Process Data */
    CurrentProcess = CurrentThread->Process;
    ProcessData = &CsrProcess->ServerData[CSR_SERVER_DLL_MAX];
    for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
    {
        /* Get the current Server */
        ServerDll = CsrLoadedServerDll[i];

        /* Check if the DLL is Loaded and has Per Process Data */
        if (ServerDll && ServerDll->SizeOfProcessData)
        {
            /* Set the pointer */
            CsrProcess->ServerData[i] = ProcessData;

            /* Copy the Data */
            RtlMoveMemory(ProcessData,
                          CurrentProcess->ServerData[i],
                          ServerDll->SizeOfProcessData);

            /* Update next data pointer */
            ProcessData = (PVOID)((ULONG_PTR)ProcessData +
                                  ServerDll->SizeOfProcessData);
        }
        else
        {
            /* No data for this Server */
            CsrProcess->ServerData[i] = NULL;
        }
    }

    /* Set the Exception Port for us */
    Status = NtSetInformationProcess(hProcess,
                                     ProcessExceptionPort,
                                     &CsrApiPort,
                                     sizeof(CsrApiPort));
    if (!NT_SUCCESS(Status))
    {
        /* Failed */
        CsrDeallocateProcess(CsrProcess);
        CsrReleaseProcessLock();
        return STATUS_NO_MEMORY;
    }

    /* Check if CreateProcess got CREATE_NEW_PROCESS_GROUP */
    if (Flags & CsrProcessCreateNewGroup)
    {
        /*
         * We create the process group leader of a new process group, therefore
         * its process group ID and sequence number are its own ones.
         */
        CsrProcess->ProcessGroupId = HandleToUlong(ClientId->UniqueProcess);
        CsrProcess->ProcessGroupSequence = CsrProcess->SequenceNumber;
    }
    else
    {
        /* Inherit the process group ID and sequence number from the current process */
        CsrProcess->ProcessGroupId = CurrentProcess->ProcessGroupId;
        CsrProcess->ProcessGroupSequence = CurrentProcess->ProcessGroupSequence;
    }

    /* Check if this is a console process */
    if (Flags & CsrProcessIsConsoleApp) CsrProcess->Flags |= CsrProcessIsConsoleApp;

    /* Mask out non-debug flags */
    Flags &= ~(CsrProcessIsConsoleApp | CsrProcessCreateNewGroup | CsrProcessPriorityFlags);

    /* Check if every process will be debugged */
    if (!(Flags) && (CurrentProcess->DebugFlags & CsrDebugProcessChildren))
    {
        /* Pass it on to the current process */
        CsrProcess->DebugFlags = CsrDebugProcessChildren;
        CsrProcess->DebugCid = CurrentProcess->DebugCid;
    }

    /* Check if Debugging was used on this process */
    if ((Flags & (CsrDebugOnlyThisProcess | CsrDebugProcessChildren)) && (DebugCid))
    {
        /* Save the debug flag used */
        CsrProcess->DebugFlags = Flags;

        /* Save the CID */
        CsrProcess->DebugCid = *DebugCid;
    }

    /* Check if Debugging is enabled */
    if (CsrProcess->DebugFlags)
    {
        /* Set the Debug Port for us */
        Status = NtSetInformationProcess(hProcess,
                                         ProcessDebugPort,
                                         &CsrApiPort,
                                         sizeof(CsrApiPort));
        ASSERT(NT_SUCCESS(Status));
        if (!NT_SUCCESS(Status))
        {
            /* Failed */
            CsrDeallocateProcess(CsrProcess);
            CsrReleaseProcessLock();
            return STATUS_NO_MEMORY;
        }
    }

    /* Get the Thread Create Time */
    Status = NtQueryInformationThread(hThread,
                                      ThreadTimes,
                                      &KernelTimes,
                                      sizeof(KernelTimes),
                                      NULL);
    if (!NT_SUCCESS(Status))
    {
        /* Failed */
        CsrDeallocateProcess(CsrProcess);
        CsrReleaseProcessLock();
        return STATUS_NO_MEMORY;
    }

    /* Allocate a CSR Thread Structure */
    CsrThread = CsrAllocateThread(CsrProcess);
    if (!CsrThread)
    {
        /* Failed */
        CsrDeallocateProcess(CsrProcess);
        CsrReleaseProcessLock();
        return STATUS_NO_MEMORY;
    }

    /* Save the data we have */
    CsrThread->CreateTime = KernelTimes.CreateTime;
    CsrThread->ClientId = *ClientId;
    CsrThread->ThreadHandle = hThread;
    ProtectHandle(hThread);
    CsrThread->Flags = 0;

    /* Insert the Thread into the Process */
    Status = CsrInsertThread(CsrProcess, CsrThread);
    if (!NT_SUCCESS(Status))
    {
        /* Bail out */
        CsrDeallocateProcess(CsrProcess);
        CsrDeallocateThread(CsrThread);
        CsrReleaseProcessLock();
        return Status;
    }

    /* Reference the session */
    CsrReferenceNtSession(NtSession);
    CsrProcess->NtSession = NtSession;

    /* Setup Process Data */
    CsrProcess->ClientId = *ClientId;
    CsrProcess->ProcessHandle = hProcess;
    CsrProcess->ShutdownLevel = 0x280;

    /* Set the Priority to Background */
    CsrSetBackgroundPriority(CsrProcess);

    /* Insert the Process */
    CsrInsertProcess(CurrentProcess, CsrProcess);

    /* Release lock and return */
    CsrReleaseProcessLock();
    return Status;
}
Example #19
0
INT_PTR CALLBACK EtpWsWatchDlgProc(
    _In_ HWND hwndDlg,
    _In_ UINT uMsg,
    _In_ WPARAM wParam,
    _In_ LPARAM lParam
    )
{
    PWS_WATCH_CONTEXT context;

    if (uMsg == WM_INITDIALOG)
    {
        context = (PWS_WATCH_CONTEXT)lParam;
        SetProp(hwndDlg, L"Context", (HANDLE)context);
    }
    else
    {
        context = (PWS_WATCH_CONTEXT)GetProp(hwndDlg, L"Context");

        if (uMsg == WM_DESTROY)
            RemoveProp(hwndDlg, L"Context");
    }

    if (!context)
        return FALSE;

    switch (uMsg)
    {
    case WM_INITDIALOG:
        {
            HWND lvHandle;

            PhCenterWindow(hwndDlg, GetParent(hwndDlg));

            context->WindowHandle = hwndDlg;
            context->ListViewHandle = lvHandle = GetDlgItem(hwndDlg, IDC_LIST);

            PhSetListViewStyle(lvHandle, FALSE, TRUE);
            PhSetControlTheme(lvHandle, L"explorer");
            PhAddListViewColumn(lvHandle, 0, 0, 0, LVCFMT_LEFT, 340, L"Instruction");
            PhAddListViewColumn(lvHandle, 1, 1, 1, LVCFMT_LEFT, 80, L"Count");
            PhSetExtendedListView(lvHandle);
            ExtendedListView_SetSort(lvHandle, 1, DescendingSortOrder);

            context->Hashtable = PhCreateSimpleHashtable(64);
            context->BufferSize = 0x2000;
            context->Buffer = PhAllocate(context->BufferSize);

            PhInitializeQueuedLock(&context->ResultListLock);
            context->SymbolProvider = PhCreateSymbolProvider(context->ProcessItem->ProcessId);
            PhLoadSymbolProviderOptions(context->SymbolProvider);

            if (!context->SymbolProvider || !context->SymbolProvider->IsRealHandle)
            {
                PhShowError(hwndDlg, L"Unable to open the process.");
                EndDialog(hwndDlg, IDCANCEL);
                break;
            }

            context->ProcessHandle = context->SymbolProvider->ProcessHandle;

            // Load symbols for both process and kernel modules.
            context->LoadingSymbolsForProcessId = context->ProcessItem->ProcessId;
            PhEnumGenericModules(
                NULL,
                context->ProcessHandle,
                0,
                EnumGenericModulesCallback,
                context
                );
            context->LoadingSymbolsForProcessId = SYSTEM_PROCESS_ID;
            PhEnumGenericModules(
                SYSTEM_PROCESS_ID,
                NULL,
                0,
                EnumGenericModulesCallback,
                context
                );

            context->Enabled = EtpUpdateWsWatch(hwndDlg, context);

            if (context->Enabled)
            {
                // WS Watch is already enabled for the process. Enable updating.
                EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE), FALSE);
                ShowWindow(GetDlgItem(hwndDlg, IDC_WSWATCHENABLED), SW_SHOW);
                SetTimer(hwndDlg, 1, 1000, NULL);
            }
            else
            {
                // WS Watch has not yet been enabled for the process.
            }
        }
        break;
    case WM_DESTROY:
        {
            context->Destroying = TRUE;

            PhDereferenceObject(context->Hashtable);

            if (context->Buffer)
            {
                PhFree(context->Buffer);
                context->Buffer = NULL;
            }
        }
        break;
    case WM_COMMAND:
        {
            switch (LOWORD(wParam))
            {
            case IDCANCEL:
            case IDOK:
                EndDialog(hwndDlg, IDOK);
                break;
            case IDC_ENABLE:
                {
                    NTSTATUS status;
                    HANDLE processHandle;

                    if (NT_SUCCESS(status = PhOpenProcess(
                        &processHandle,
                        PROCESS_SET_INFORMATION,
                        context->ProcessItem->ProcessId
                        )))
                    {
                        status = NtSetInformationProcess(
                            processHandle,
                            ProcessWorkingSetWatchEx,
                            NULL,
                            0
                            );
                        NtClose(processHandle);
                    }

                    if (NT_SUCCESS(status))
                    {
                        EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE), FALSE);
                        ShowWindow(GetDlgItem(hwndDlg, IDC_WSWATCHENABLED), SW_SHOW);
                        SetTimer(hwndDlg, 1, 1000, NULL);
                    }
                    else
                    {
                        PhShowStatus(hwndDlg, L"Unable to enable WS watch", status, 0);
                    }
                }
                break;
            }
        }
        break;
    case WM_NOTIFY:
        {
            PhHandleListViewNotifyForCopy(lParam, context->ListViewHandle);
        }
        break;
    case WM_TIMER:
        {
            switch (wParam)
            {
            case 1:
                {
                    EtpUpdateWsWatch(hwndDlg, context);
                }
                break;
            }
        }
        break;
    }

    return FALSE;
}
Example #20
0
VOID NTAPI MenuItemCallback(
    _In_opt_ PVOID Parameter,
    _In_opt_ PVOID Context
    )
{
    PPH_PLUGIN_MENU_ITEM menuItem = Parameter;

    switch (menuItem->Id)
    {
    case CRITICAL_MENU_ITEM:
        {
            NTSTATUS status;
            PPH_PROCESS_ITEM processItem = menuItem->Context;
            HANDLE processHandle;
            ULONG breakOnTermination;

            if (NT_SUCCESS(status = PhOpenProcess(&processHandle, PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION, processItem->ProcessId)))
            {
                if (NT_SUCCESS(status = NtQueryInformationProcess(processHandle, ProcessBreakOnTermination, &breakOnTermination, sizeof(ULONG), NULL)))
                {
                    if (!breakOnTermination && PhShowConfirmMessage(
                        menuItem->OwnerWindow,
                        L"enable",
                        L"critical status on the process",
                        L"If the process ends, the operating system will shut down immediately.",
                        TRUE
                        ))
                    {
                        breakOnTermination = TRUE;
                        status = NtSetInformationProcess(processHandle, ProcessBreakOnTermination, &breakOnTermination, sizeof(ULONG));
                    }
                    else if (breakOnTermination && PhShowConfirmMessage(
                        menuItem->OwnerWindow,
                        L"disable",
                        L"critical status on the process",
                        NULL,
                        FALSE
                        ))
                    {
                        breakOnTermination = FALSE;
                        status = NtSetInformationProcess(processHandle, ProcessBreakOnTermination, &breakOnTermination, sizeof(ULONG));
                    }

                    if (!NT_SUCCESS(status))
                        PhShowStatus(menuItem->OwnerWindow, L"Unable to set critical status", status, 0);
                }
                else
                {
                    PhShowStatus(menuItem->OwnerWindow, L"Unable to query critical status", status, 0);
                }

                NtClose(processHandle);
            }
            else
            {
                PhShowStatus(menuItem->OwnerWindow, L"Unable to open the process", status, 0);
            }
        }
        break;
    }
}
Example #21
0
VOID
ServiceStart (
   DWORD dwArgc,
   LPTSTR *lpszArgv
   )
/*++

Routine Description:

   The code that starts everything, is really the main().

Arguments:

   None.

Return Values:

    None.

--*/
{
    DWORD     dwWait;
    NTSTATUS  Status = STATUS_SUCCESS;
    BOOLEAN   EnableAlignmentFaults = TRUE;
    KPRIORITY BasePriority;

    ///////////////////////////////////////////////////
    //
    // Service initialization
    //

    //
    // Report the status to the service control manager.
    //
    if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000))                 // wait hint
        goto Cleanup;

    //
    // Create the event object. The control handler function signals
    // this event when it receives the "stop" control code.
    //
    hServerStopEvent = CreateEvent(
        NULL,    // no security attributes
        TRUE,    // manual reset event
        FALSE,   // not-signalled
        NULL);   // no name

    if ( hServerStopEvent == NULL)
        goto Cleanup;

    //
    // Report the status to the service control manager.
    //
    if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000))                 // wait hint
        goto Cleanup;


    //
    // Define a top-level exception handler for the entire process.
    //

    (VOID) SetErrorMode( SEM_FAILCRITICALERRORS );

    (VOID) SetUnhandledExceptionFilter( &LLSTopLevelExceptionHandler );

    //
    // Turn on alignment fault fixups.  This is necessary because
    // several structures stored in the registry have qword aligned
    // fields.  They are nicely aligned in our structures, but they
    // end up being forced out of alignment when being stored because
    // the registry api require data to be passed following a wierd
    // length header.
    //

    Status = NtSetInformationProcess(
                        NtCurrentProcess(),
                        ProcessEnableAlignmentFaultFixup,
                        (PVOID) &EnableAlignmentFaults,
                        sizeof(BOOLEAN)
                        );
    ASSERT(NT_SUCCESS(Status));

    //
    // Report the status to the service control manager.
    //
    if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000))                 // wait hint
        goto Cleanup;

    //
    // Run the LLS in the foreground.
    //
    // Several processes which depend on the LLS (like the lanman server)
    // run in the foreground.  If we don't run in the foreground, they'll
    // starve waiting for us.
    //

    BasePriority = FOREGROUND_BASE_PRIORITY;

    Status = NtSetInformationProcess(
                NtCurrentProcess(),
                ProcessBasePriority,
                &BasePriority,
                sizeof(BasePriority)
                );

    //
    // Report the status to the service control manager.
    //
    if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000))                 // wait hint
        goto Cleanup;

    // Initialize the Registry values...
    RegistryInit();

    //
    // Report the status to the service control manager.
    //
    if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000))                 // wait hint
        goto Cleanup;

    // Initialize the Registry values...
    ConfigInfoInit();

    //
    // Report the status to the service control manager.
    //
    if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000))                 // wait hint
        goto Cleanup;

    // Initialize the Service Table
    LicenseListInit();

    //
    // Report the status to the service control manager.
    //
    if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000))                 // wait hint
        goto Cleanup;

    // Initialize the Service Table
    MasterServiceListInit();

    //
    // Report the status to the service control manager.
    //
    if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000))                 // wait hint
        goto Cleanup;

    // Initialize the Service Table
    LocalServiceListInit();

    //
    // Report the status to the service control manager.
    //
    if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000))                 // wait hint
        goto Cleanup;

    // Initialize the Service Table
    ServiceListInit();

    //
    // Report the status to the service control manager.
    //
    if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000))                 // wait hint
        goto Cleanup;

    // Initialize the Service Table
    MappingListInit();

    //
    // Report the status to the service control manager.
    //
    if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000))                 // wait hint
        goto Cleanup;

    // Initialize the Per-Seat Table
    UserListInit();

    //
    // Report the status to the service control manager.
    //
    if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000))                 // wait hint
        goto Cleanup;

    // Initialize the Service Table
    ServerListInit();

    //
    // Report the status to the service control manager.
    //
    if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000))                 // wait hint
        goto Cleanup;

    // Initialize the Certificate Database
    CertDbInit();

    //
    // Report the status to the service control manager - need a bit longer
    // to read in all the data files.
    //
    if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 15000))                 // wait hint
        goto Cleanup;

    // Load data files
    LoadAll();

    //
    // Report the status to the service control manager.
    //
    if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000))                 // wait hint
        goto Cleanup;

    // Initialize RPC Stuff...
    LLSRpcInit();

    //
    // Report the status to the service control manager.
    //
    if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000))                 // wait hint
        goto Cleanup;

    // Initialize Replication...
    ReplicationInit();

    //
    // Report the status to the service control manager.
    //
    if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000))                 // wait hint
        goto Cleanup;

    // Initialize scavenger thread...
    ScavengerInit();

    //
    // Report the status to the service control manager.
    //
    if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 3000))                 // wait hint
        goto Cleanup;

    // Initialize RegistryMonitor thread...
    RegistryStartMonitor();

    //
    // End of initialization
    //
    ////////////////////////////////////////////////////////

    //
    // Tell SCM we are up and running!
    //
    if (!ReportStatusToSCMgr( SERVICE_RUNNING, NO_ERROR, 0))                    // wait hint
        goto Cleanup;

    ////////////////////////////////////////////////////////
    //
    // Service is now running, perform work until shutdown
    //
    dwWait = WaitForSingleObject(hServerStopEvent, INFINITE);

Cleanup:

    if (hServerStopEvent)
        CloseHandle(hServerStopEvent);

    if (sshStatusHandle)
       ReportStatusToSCMgr( SERVICE_STOPPED, NO_ERROR, 0);

} // ServiceStart
Example #22
0
NTSTATUS
_main(IN INT argc,
      IN PCHAR argv[],
      IN PCHAR envp[],
      IN ULONG DebugFlag)
{
    NTSTATUS Status;
    KPRIORITY SetBasePriority;
    ULONG_PTR Parameters[4];
    HANDLE Handles[2];
    PVOID State;
    ULONG Flags;
    PROCESS_BASIC_INFORMATION ProcessInfo;
    UNICODE_STRING DbgString, InitialCommand;

    /* Make us critical */
    RtlSetProcessIsCritical(TRUE, NULL, FALSE);
    RtlSetThreadIsCritical(TRUE, NULL, FALSE);

    /* Raise our priority */
    SetBasePriority = 11;
    Status = NtSetInformationProcess(NtCurrentProcess(),
                                     ProcessBasePriority,
                                     (PVOID)&SetBasePriority,
                                     sizeof(SetBasePriority));
    ASSERT(NT_SUCCESS(Status));

    /* Save the debug flag if it was passed */
    if (DebugFlag) SmpDebug = DebugFlag != 0;

    /* Build the hard error parameters */
    Parameters[0] = (ULONG_PTR)&DbgString;
    Parameters[1] = Parameters[2] = Parameters[3] = 0;

    /* Enter SEH so we can terminate correctly if anything goes wrong */
    _SEH2_TRY
    {
        /* Initialize SMSS */
        Status = SmpInit(&InitialCommand, Handles);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("SMSS: SmpInit return failure - Status == %x\n", Status);
            RtlInitUnicodeString(&DbgString, L"Session Manager Initialization");
            Parameters[1] = Status;
            _SEH2_LEAVE;
        }

        /* Get the global flags */
        Status = NtQuerySystemInformation(SystemFlagsInformation,
                                          &Flags,
                                          sizeof(Flags),
                                          NULL);
        ASSERT(NT_SUCCESS(Status));

        /* Before executing the initial command check if the debug flag is on */
        if (Flags & (FLG_DEBUG_INITIAL_COMMAND | FLG_DEBUG_INITIAL_COMMAND_EX))
        {
            /* SMSS should launch ntsd with a few parameters at this point */
            DPRINT1("Global Flags Set to SMSS Debugging: Not yet supported\n");
        }

        /* Execute the initial command (Winlogon.exe) */
        Status = SmpExecuteInitialCommand(0, &InitialCommand, &Handles[1], NULL);
        if (!NT_SUCCESS(Status))
        {
            /* Fail and raise a hard error */
            DPRINT1("SMSS: Execute Initial Command failed\n");
            RtlInitUnicodeString(&DbgString,
                                 L"Session Manager ExecuteInitialCommand");
            Parameters[1] = Status;
            _SEH2_LEAVE;
        }

        /*  Check if we're already attached to a session */
        Status = SmpAcquirePrivilege(SE_LOAD_DRIVER_PRIVILEGE, &State);
        if (AttachedSessionId != -1)
        {
            /* Detach from it, we should be in no session right now */
            Status = NtSetSystemInformation(SystemSessionDetach,
                                            &AttachedSessionId,
                                            sizeof(AttachedSessionId));
            ASSERT(NT_SUCCESS(Status));
            AttachedSessionId = -1;
        }
        SmpReleasePrivilege(State);

        /* Wait on either CSRSS or Winlogon to die */
        Status = NtWaitForMultipleObjects(RTL_NUMBER_OF(Handles),
                                          Handles,
                                          WaitAny,
                                          FALSE,
                                          NULL);
        if (Status == STATUS_WAIT_0)
        {
            /* CSRSS is dead, get exit code and prepare for the hard error */
            RtlInitUnicodeString(&DbgString, L"Windows SubSystem");
            Status = NtQueryInformationProcess(Handles[0],
                                               ProcessBasicInformation,
                                               &ProcessInfo,
                                               sizeof(ProcessInfo),
                                               NULL);
            DPRINT1("SMSS: Windows subsystem terminated when it wasn't supposed to.\n");
        }
        else
        {
            /* The initial command is dead or we have another failure */
            RtlInitUnicodeString(&DbgString, L"Windows Logon Process");
            if (Status == STATUS_WAIT_1)
            {
                /* Winlogon.exe got terminated, get its exit code */
                Status = NtQueryInformationProcess(Handles[1],
                                                   ProcessBasicInformation,
                                                   &ProcessInfo,
                                                   sizeof(ProcessInfo),
                                                   NULL);
            }
            else
            {
                /* Something else satisfied our wait, so set the wait status */
                ProcessInfo.ExitStatus = Status;
                Status = STATUS_SUCCESS;
            }
            DPRINT1("SMSS: Initial command '%wZ' terminated when it wasn't supposed to.\n",
                    &InitialCommand);
        }

        /* Check if NtQueryInformationProcess was successful */
        if (NT_SUCCESS(Status))
        {
            /* Then we must have a valid exit status in the structure, use it */
            Parameters[1] = ProcessInfo.ExitStatus;
        }
        else
        {
            /* We really don't know what happened, so set a generic error */
            Parameters[1] = STATUS_UNSUCCESSFUL;
        }
    }
    _SEH2_EXCEPT(SmpUnhandledExceptionFilter(_SEH2_GetExceptionInformation()))
    {
        /* The filter should never return here */
        ASSERT(FALSE);
    }
    _SEH2_END;

    /* Something in the init loop failed, terminate SMSS */
    return SmpTerminate(Parameters, 1, RTL_NUMBER_OF(Parameters));
}
Example #23
0
VOID
SuspendedProcessTest (
    VOID
    )

{

    PERFINFO PerfInfo;
    STARTUPINFO si;
    PROCESS_INFORMATION pi[SPD_PROCESS_ITERATIONS];
    BOOL b;
    int Index;
    CHAR Buffer[256];
    KPRIORITY Base;

    GetModuleFileName(0,Buffer,256);

    RtlZeroMemory(&si,sizeof(si));
    si.cb = sizeof(si);

    Base = 13;
    NtSetInformationProcess(
        NtCurrentProcess(),
        ProcessBasePriority,
        (PVOID) &Base,
        sizeof(Base)
        );
//    SetPriorityClass(GetCurrentProcess(),HIGH_PRIORITY_CLASS);
    StartBenchMark("Suspended Process Creation Benchmark)",
                   SPD_PROCESS_ITERATIONS,
                   &PerfInfo);

    for (Index = 0; Index < SPD_PROCESS_ITERATIONS; Index += 1) {
        b = CreateProcess(
                Buffer,
                "just exit",
                NULL,
                NULL,
                TRUE,
                CREATE_SUSPENDED,
                NULL,
                NULL,
                &si,
                &pi[Index]
                );
        if ( !b ) {
            printf("failed %ld\n",Index);
            }
        }
    //
    // Print out performance statistics.
    //

    FinishBenchMark(&PerfInfo);
//    SetPriorityClass(GetCurrentProcess(),NORMAL_PRIORITY_CLASS);

    StartBenchMark("Process Startup/Exit Benchmark)",
                   SPD_PROCESS_ITERATIONS,
                   &PerfInfo);
    for (Index = 0; Index < SPD_PROCESS_ITERATIONS; Index += 1) {
        ResumeThread(pi[Index].hThread);
        CloseHandle(pi[Index].hThread);
        WaitForSingleObject(pi[Index].hProcess,-1);
        CloseHandle(pi[Index].hProcess);
        }
    FinishBenchMark(&PerfInfo);

    //
    // End of event1 context switch test.
    //

    return;
}