🧠 Windows Process Creation Cheatsheet

🎯 Visual Process Creation Flowchart

PARENT PROCESS
    |
    +-- CreateProcessA/CreateProcessW/
    |      CreateProcessAsUserA/CreateProcessAsUserW/
    |      CreateProcessWithLogonW/CreateProcessWithTokenW
    |        |
    |        +-- CHILD already loaded with new program
    |
    +-- Parent monitors child (WaitForSingleObject/WaitForMultipleObjects)
    |
    +-- Parent closes handles (CloseHandle)

βœ… Key points:

πŸ—ΊοΈ Logical Flow for Process Management

  1. Create Process: CreateProcessA(), CreateProcessW(), etc.
  2. Wait for Process Completion: WaitForSingleObject(), WaitForMultipleObjects().
  3. Get Exit Code: GetExitCodeProcess().
  4. Clean Up: Close process and thread handles with CloseHandle().

1. πŸ‘Ά Creating a Process (Launching a Child)

Function Purpose Notes
CreateProcessA() Create a process (ANSI version) Traditional method for creating a process
CreateProcessW() Create a process (Unicode version) Use this for wide-character (UTF-16) strings
CreateProcessAsUserA() Create a process as another user (ANSI version) Requires impersonation
CreateProcessAsUserW() Create a process as another user (Unicode version) Requires impersonation
CreateProcessWithLogonW() Create a process with logon credentials Useful for impersonating a user with a password
CreateProcessWithTokenW() Create a process with an access token Used to launch a process under a token

1.1 CreateProcessA()

#include <windows.h>

int main() {
    STARTUPINFO si = {0};
    PROCESS_INFORMATION pi;
    si.cb = sizeof(STARTUPINFO);

    if (CreateProcessA(
        "C:\\Windows\\System32\\notepad.exe", // Program to run
        NULL,                                // Command line arguments
        NULL,                                // Process attributes
        NULL,                                // Thread attributes
        FALSE,                               // Inherit handles?
        0,                                   // Creation flags
        NULL,                                // Environment
        NULL,                                // Current directory
        &si,                                 // Startup info
        &pi                                  // Process info
    )) {
        // Wait for the process to exit
        WaitForSingleObject(pi.hProcess, INFINITE);
        // Get exit code
        DWORD exitCode;
        GetExitCodeProcess(pi.hProcess, &exitCode);
        printf("Exit code: %lu\n", exitCode);
        // Clean up handles
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    }
    return 0;
}

1.2 CreateProcessW()

#include <windows.h>

int main() {
    STARTUPINFO si = {0};
    PROCESS_INFORMATION pi;
    si.cb = sizeof(STARTUPINFO);

    if (CreateProcessW(
        L"C:\\Windows\\System32\\notepad.exe", // Program to run
        NULL,                                 // Command line arguments
        NULL,                                 // Process attributes
        NULL,                                 // Thread attributes
        FALSE,                                // Inherit handles?
        0,                                    // Creation flags
        NULL,                                 // Environment
        NULL,                                 // Current directory
        &si,                                  // Startup info
        &pi                                   // Process info
    )) {
        // Wait for the process to exit
        WaitForSingleObject(pi.hProcess, INFINITE);
        // Get exit code
        DWORD exitCode;
        GetExitCodeProcess(pi.hProcess, &exitCode);
        printf("Exit code: %lu\n", exitCode);
        // Clean up handles
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    }
    return 0;
}

1.3 CreateProcessAsUserA()

#include <windows.h>
#include <userenv.h>

int main() {
    HANDLE hToken;
    STARTUPINFO si = {0};
    PROCESS_INFORMATION pi;
    si.cb = sizeof(STARTUPINFO);

    // Assume the token is already opened as hToken
    if (CreateProcessAsUserA(
        hToken,                             // Access token for impersonation
        "C:\\Windows\\System32\\notepad.exe", // Program to run
        NULL,                                // Command line arguments
        NULL,                                // Process attributes
        NULL,                                // Thread attributes
        FALSE,                               // Inherit handles?
        0,                                   // Creation flags
        NULL,                                // Environment
        NULL,                                // Current directory
        &si,                                 // Startup info
        &pi                                  // Process info
    )) {
        // Wait for the process to exit
        WaitForSingleObject(pi.hProcess, INFINITE);
        // Clean up handles
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    }
    return 0;
}

1.4 CreateProcessWithLogonW()

#include <windows.h>

int main() {
    if (CreateProcessWithLogonW(
        L"user",                            // User name
        NULL,                               // Domain (NULL for local machine)
        L"password",                        // Password
        LOGON_NETCREDENTIALS_ONLY,          // Logon flags
        L"C:\\Windows\\System32\\notepad.exe", // Program to run
        NULL,                               // Command line arguments
        0,                                  // Creation flags
        NULL,                               // Environment
        NULL,                               // Current directory
        NULL,                               // Startup info
        NULL                                // Process information
    )) {
        printf("Process created successfully.\n");
    }
    return 0;
}

1.5 CreateProcessWithTokenW()

#include <windows.h>

int main() {
    HANDLE hToken;
    // Assume hToken is obtained through OpenProcessToken, etc.
    if (CreateProcessWithTokenW(
        hToken,                             // Access token
        LOGON_WITH_PROFILE,                  // Logon flags
        NULL,                               // Application name
        L"C:\\Windows\\System32\\notepad.exe", // Program to run
        0,                                  // Creation flags
        NULL,                               // Environment
        NULL,                               // Current directory
        NULL,                               // Startup info
        NULL                                // Process information
    )) {
        printf("Process created with token.\n");
    }
    return 0;
}

2. πŸ”„ Wait for a Process to Exit

Function Purpose Notes
WaitForSingleObject() Wait for a single process to finish Blocks until the specified process exits
WaitForMultipleObjects() Wait for multiple processes to finish Blocks until one or more processes finish
GetExitCodeProcess() Retrieve the exit code of a process Retrieves the termination status of a process

2.1 WaitForSingleObject()

#include <windows.h>

int main() {
    HANDLE hProcess = OpenProcess(SYNCHRONIZE, FALSE, pid); // Get process handle
    WaitForSingleObject(hProcess, INFINITE); // Wait until process exits
    DWORD exitCode;
    GetExitCodeProcess(hProcess, &exitCode); // Retrieve the exit code
    CloseHandle(hProcess); // Close handle
    printf("Exit code: %lu\n", exitCode);
    return 0;
}

2.2 WaitForMultipleObjects()

#include <windows.h>

int main() {
    HANDLE hProcesses[2];
    hProcesses[0] = OpenProcess(SYNCHRONIZE, FALSE, pid1);
    hProcesses[1] = OpenProcess(SYNCHRONIZE, FALSE, pid2);

    DWORD result = WaitForMultipleObjects(2, hProcesses, TRUE, INFINITE);  // Wait for all processes

    if (result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + 2) {
        DWORD exitCode;
        for (int i = 0; i < 2; ++i) {
            GetExitCodeProcess(hProcesses[i], &exitCode);
            printf("Process %d exit code: %lu\n", i, exitCode);
        }
    }
    CloseHandle(hProcesses[0]);
    CloseHandle(hProcesses[1]);
    return 0;
}

2.3 GetExitCodeProcess()

#include <windows.h>

int main() {
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
    DWORD exitCode;
    if (GetExitCodeProcess(hProcess, &exitCode)) {
        printf("Exit Code: %lu\n", exitCode);
    }
    CloseHandle(hProcess);
    return 0;
}

3. 🧹 Cleaning Up Resources

After creating processes and waiting for them, always ensure you clean up by closing handles. This includes process and thread handles created by CreateProcess*() functions.

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
Logo
buildsoftwaresystems.com