Process Creation

Introduction

This document details the mechanisms and APIs involved in creating new processes within the Windows operating system kernel. Understanding process creation is fundamental to comprehending how applications and system services are launched and managed.

A process represents an instance of a running program. It comprises one or more threads, an address space, system resources (like handles to files, registry keys), and security context.

Core APIs for Process Creation

CreateProcess / CreateProcessAsUser

The primary Win32 API functions for creating a new process are CreateProcess and CreateProcessAsUser. These functions provide a high-level interface for initiating a new process and its primary thread.

Key parameters include:

  • lpApplicationName: The name of the executable module to be run.
  • lpCommandLine: The command line used to start the application.
  • lpProcessAttributes, lpThreadAttributes: Security descriptors for the process and thread.
  • bInheritHandles: A flag indicating whether the new process inherits handles from the parent.
  • dwCreationFlags: Flags that control the priority class, process creation, and the window style of the main window.
  • lpEnvironment: A pointer to a block of memory that contains a new environment for the child process.
  • lpCurrentDirectory: The full path to the current directory for the new process.
  • lpStartupInfo: A pointer to a STARTUPINFO structure that specifies the window station, desktop, standard handles, and appearance of the main window for the new process.
  • lpProcessInformation: A pointer to a PROCESS_INFORMATION structure that receives identification and handle information for the new process and its primary thread.
BOOL CreateProcess(
  LPCSTR lpApplicationName,
  LPSTR lpCommandLine,
  LPSECURITY_ATTRIBUTES lpProcessAttributes,
  LPSECURITY_ATTRIBUTES lpThreadAttributes,
  BOOL bInheritHandles,
  DWORD dwCreationFlags,
  LPVOID lpEnvironment,
  LPCSTR lpCurrentDirectory,
  LPSTARTUPINFO lpStartupInfo,
  LPPROCESS_INFORMATION lpProcessInformation
);

The CreateProcessAsUser function is similar but allows the caller to specify the security context (user token) under which the new process will run, which is crucial for impersonation or running processes as different users.

Kernel-Level Internals

NtCreateUserProcess

The Win32 APIs like CreateProcess ultimately call the native kernel API NtCreateUserProcess (or variations thereof). This function is responsible for the core kernel operations involved in process creation.

NtCreateUserProcess performs the following key tasks:

  • Allocates a process kernel object (EPROCESS).
  • Creates a virtual address space for the new process.
  • Loads the specified executable image into the address space.
  • Creates the initial thread for the process.
  • Initializes process-specific data structures, including the handle table, process control block (EPROCESS), and thread control block (ETHREAD).
  • Sets up the initial execution context for the thread.

The interaction between user-mode APIs and kernel-mode functions is a fundamental aspect of Windows system architecture, ensuring a robust and secure environment for process management.

Security Considerations

When creating processes, especially with elevated privileges or user-specified executables, it's critical to validate inputs and ensure appropriate security contexts are applied. Improper handling can lead to privilege escalation vulnerabilities.

Process Attributes and Flags

Several flags and attributes significantly influence how a process is created:

  • dwCreationFlags:
    • CREATE_SUSPENDED: Creates the process in a suspended state, allowing its context to be modified before execution begins.
    • DETACHED_PROCESS: Creates a process that is detached from the console of the calling process.
    • CREATE_NEW_CONSOLE: Creates a new console window for the process.
    • HIGH_PRIORITY_CLASS, REALTIME_PRIORITY_CLASS: Sets the priority level of the process.
  • Security Attributes: The lpProcessAttributes and lpThreadAttributes parameters allow fine-grained control over the security descriptor of the new process and its initial thread, controlling access for other processes and users.
  • Handle Inheritance: The bInheritHandles flag determines whether the child process inherits open handles from the parent. This is often used for inter-process communication or passing file access.

Advanced Scenarios

Process Forks (fork-like behavior)

Unlike Unix-like systems, Windows does not have a direct fork() system call that duplicates a parent process. Instead, the functionality is emulated using CreateProcess with specific parameters to create a child process that resembles the parent's environment. Tools like GNU utilities on Windows may implement fork via CreateProcess and environment duplication.

CreateProcessW vs CreateProcessA

The W (wide character/Unicode) versions of the Win32 APIs are generally preferred for modern Windows development to ensure proper handling of international characters and avoid issues related to multi-byte character sets.

Best Practice

Always use the Unicode versions of Win32 APIs (ending with 'W') when possible, and ensure your application is compiled with Unicode support enabled.

Related Kernel Objects

When a process is created, several kernel objects are involved:

  • EPROCESS: The executive process block, a kernel data structure representing a process.
  • ETHREAD: The executive thread block, representing a thread within a process.
  • Handle Table: A data structure associated with each process that maps handles to kernel objects (files, events, mutexes, etc.).
  • Virtual Address Space: A memory map defining the addressable memory for the process.

These objects are managed by the Windows Executive (part of the kernel) and provide the foundation for process execution and resource management.

Summary

Process creation in Windows is a complex yet well-defined operation, primarily orchestrated through the CreateProcess family of Win32 APIs, which internally leverage native kernel functions like NtCreateUserProcess. Understanding the parameters, flags, and underlying kernel objects is crucial for developing robust and secure Windows applications.