CreateProcessA 함수(processthreadsapi.h)
새 프로세스와 해당 기본 스레드를 만듭니다. 새 프로세스는 호출 프로세스의 보안 컨텍스트에서 실행됩니다.
호출 프로세스가 다른 사용자를 가장하는 경우 새 프로세스는 가장 토큰이 아닌 호출 프로세스에 토큰을 사용합니다. 가장 토큰으로 표시되는 사용자의 보안 컨텍스트에서 새 프로세스를 실행하려면
통사론
BOOL CreateProcessA(
[in, optional] LPCSTR lpApplicationName,
[in, out, optional] LPSTR lpCommandLine,
[in, optional] LPSECURITY_ATTRIBUTES lpProcessAttributes,
[in, optional] LPSECURITY_ATTRIBUTES lpThreadAttributes,
[in] BOOL bInheritHandles,
[in] DWORD dwCreationFlags,
[in, optional] LPVOID lpEnvironment,
[in, optional] LPCSTR lpCurrentDirectory,
[in] LPSTARTUPINFOA lpStartupInfo,
[out] LPPROCESS_INFORMATION lpProcessInformation
);
매개 변수
[in, optional] lpApplicationName
실행할 모듈의 이름입니다. 이 모듈은 Windows 기반 애플리케이션일 수 있습니다. 로컬 컴퓨터에서 적절한 하위 시스템을 사용할 수 있는 경우 다른 유형의 모듈(예: MS-DOS 또는 OS/2)일 수 있습니다.
문자열은 실행할 모듈의 전체 경로 및 파일 이름을 지정하거나 부분 이름을 지정할 수 있습니다. 부분 이름의 경우 함수는 현재 드라이브 및 현재 디렉터리를 사용하여 사양을 완료합니다. 함수는 검색 경로를 사용하지 않습니다. 이 매개 변수는 파일 이름 확장명을 포함해야 합니다. 기본 확장은 가정되지 않습니다.
- c:\program.exe
- c:\program files\sub.exe
- c:\program files\sub dir\program.exe
- c:\program files\sub dir\program name.exe
실행 모듈이 16비트 애플리케이션인 경우
일괄 처리 파일을 실행하려면 명령 인터프리터를 시작해야 합니다. lpApplicationName cmd.exe 설정하고 lpCommandLine 다음 인수로 설정합니다. /c 및 일괄 처리 파일의 이름.
중요하다
MSRC 엔지니어링 팀은 이에 대해 조언합니다. 자세한 내용은 MS14-019 – .cmd 또는 .bat 파일 통해 이진 하이재킹 수정을 참조하세요.
[in, out, optional] lpCommandLine
실행할 명령줄입니다.
이 문자열의 최대 길이는 유니코드 종료 null 문자를 포함하여 32,767자입니다.
CreateProcessW
lpCommandLine 매개 변수는 NULL일 수 있습니다. 이 경우 함수는 lpApplicationName 가리키는 문자열을 명령줄로 사용합니다.
lpApplicationName 및 lpCommandLine 모두NULL경우 lpApplicationName에서 가리키는 null로 끝나는 문자열은 실행할 모듈을 지정하고 lpCommandLine 가리키는 null로 끝나는 문자열은 명령줄을 지정합니다. 새 프로세스는 GetCommandLine 사용하여 전체 명령줄을 검색할 수 있습니다. C로 작성된 콘솔 프로세스는
lpApplicationName NULL이면 명령줄의 첫 번째 공백으로 구분된 토큰이 모듈 이름을 지정합니다. 공백이 포함된 긴 파일 이름을 사용하는 경우 따옴표 붙은 문자열을 사용하여 파일 이름이 끝나고 인수가 시작되는 위치를 나타냅니다(lpApplicationName 매개 변수에 대한 설명 참조). 파일 이름에 확장명을 포함하지 않으면 .exe 추가됩니다. 따라서 파일 이름 확장명을 .com 경우 이 매개 변수에는 .com 확장명을 포함해야 합니다. 파일 이름이 확장명 없이 마침표(.)로 끝나거나 파일 이름에 경로가 포함된 경우 .exe 추가되지 않습니다. 파일 이름에 디렉터리 경로가 없는 경우 시스템은 다음 순서로 실행 파일을 검색합니다.
- 애플리케이션이 로드된 디렉터리입니다.
- 부모 프로세스의 현재 디렉터리입니다.
- 32비트 Windows 시스템 디렉터리입니다. GetSystemDirectoryA 함수 함수를 사용하여 이 디렉터리의 경로를 가져옵니다.
- 16비트 Windows 시스템 디렉터리입니다. 이 디렉터리의 경로를 가져오는 함수는 없지만 검색됩니다. 이 디렉터리의 이름은 System입니다.
- Windows 디렉터리입니다. GetWindowsDirectoryA 함수 사용하여 이 디렉터리의 경로를 가져옵니다.
- PATH 환경 변수에 나열된 디렉터리입니다. 이 함수는 App Paths 레지스트리 키로 지정된 애플리케이션별 경로를 검색하지 않습니다. 이 애플리케이션별 경로를 검색 순서에 포함하려면 ShellExecute 함수사용합니다.
시스템에서 명령줄 문자열에 종료 null 문자를 추가하여 파일 이름을 인수와 구분합니다. 내부 처리를 위해 원래 문자열을 두 문자열로 나눕니다.
[in, optional] lpProcessAttributes
새 프로세스 개체에 반환된 핸들을 자식 프로세스에서 상속할 수 있는지 여부를 결정하는 SECURITY_ATTRIBUTES 구조체에 대한 포인터입니다.
구조체의 lpSecurityDescriptor 멤버는 새 프로세스에 대한 보안 설명자를 지정합니다.
[in, optional] lpThreadAttributes
새 스레드 개체에 반환된 핸들을 자식 프로세스에서 상속할 수 있는지 여부를 결정하는 SECURITY_ATTRIBUTES 구조체에 대한 포인터입니다. lpThreadAttributes NULL이면 핸들을 상속할 수 없습니다.
구조체의 lpSecurityDescriptor 멤버는 주 스레드에 대한 보안 설명자를 지정합니다.
[in] bInheritHandles
이 매개 변수가 TRUE이면 호출 프로세스의 상속 가능한 각 핸들이 새 프로세스에서 상속됩니다. 매개 변수가 FALSE이면 핸들이 상속되지 않습니다. 상속된 핸들은 원래 핸들과 동일한 값 및 액세스 권한을 갖습니다. 상속 가능한 핸들에 대한 자세한 내용은 비고를 참조하세요.
터미널 서비스: 세션 간에 핸들을 상속할 수 없습니다. 또한 이 매개 변수가 TRUE이면 호출자와 동일한 세션에서 프로세스를 만들어야 합니다.
PPL(Protected Process Light) 프로세스: PPL 프로세스가 PPL이 아닌 프로세스에서 PPL 프로세스로 PROCESS_DUP_HANDLE 허용되지 않으므로 PPL 프로세스가 PPL이 아닌 프로세스를 만들 때 제네릭 핸들 상속이 차단됩니다. 프로세스 보안 및 액세스 권한
Windows 7: 매개 변수가 FALSE인 경우에도 STD_INPUT_HANDLE, STD_OUTPUT_HANDLE 및 STD_ERROR_HANDLE 상속됩니다.
[in] dwCreationFlags
우선 순위 클래스 및 프로세스 생성을 제어하는 플래그입니다. 값 목록은 프로세스 만들기 플래그
또한 이 매개 변수는 프로세스 스레드의 예약 우선 순위를 결정하는 데 사용되는 새 프로세스의 우선 순위 클래스를 제어합니다. 값 목록은 GetPriorityClass참조하세요. 우선 순위 클래스 플래그를 지정하지 않으면 만들기 프로세스의 우선 순위 클래스가 IDLE_PRIORITY_CLASS 또는 BELOW_NORMAL_PRIORITY_CLASS않는 한 우선 순위 클래스는 기본적으로 NORMAL_PRIORITY_CLASS. 이 경우 자식 프로세스는 호출 프로세스의 기본 우선 순위 클래스를 받습니다.
dwCreationFlags 매개 변수의 값이 0인 경우:
- 이 프로세스는 호출자의 오류 모드와 부모 콘솔을 모두 상속합니다.
- 새 프로세스에 대한 환경 블록은 ANSI 문자를 포함하는 것으로 간주됩니다(추가 정보는 lpEnvironment 매개 변수 참조).
- 16비트 Windows 기반 애플리케이션은 공유 VDM(Virtual DOS 머신)에서 실행됩니다.
[in, optional] lpEnvironment
새 프로세스에 대한 환경 블록 대한 포인터입니다. 이 매개 변수가 NULL
환경 블록은 null로 끝나는 null 종료 문자열 블록으로 구성됩니다. 각 문자열은 다음과 같은 형식입니다.
이름=값\0
등호는 구분 기호로 사용되므로 환경 변수의 이름에 사용하면 안 됩니다.
환경 블록에는 유니코드 또는 ANSI 문자가 포함될 수 있습니다. lpEnvironment 가리키는 환경 블록에 유니코드 문자가 포함된 경우 dwCreationFlagsCREATE_UNICODE_ENVIRONMENT포함해야 합니다.
프로세스에 대한 환경 블록의 총 크기가 32,767자를 초과하면 이 함수의 ANSI 버전인 createProcessA 실패합니다.
ANSI 환경 블록은 0바이트 2바이트로 종료됩니다. 하나는 마지막 문자열에 대해 하나씩, 다른 하나는 블록을 종료합니다. 유니코드 환경 블록은 0바이트 4바이트로 종료됩니다. 마지막 문자열에는 2바이트, 블록을 종료하려면 2바이트가 더 있습니다.
[in, optional] lpCurrentDirectory
프로세스의 현재 디렉터리에 대한 전체 경로입니다. 문자열은 UNC 경로를 지정할 수도 있습니다.
이 매개 변수가 NULL
[in] lpStartupInfo
STARTUPINFO 또는 STARTUPINFOEX 구조체에 대한 포인터입니다.
확장 특성을 설정하려면 STARTUPINFOEX 구조를 사용하고 dwCreationFlags 매개 변수에 EXTENDED_STARTUPINFO_PRESENT 지정합니다.
STARTUPINFO 또는 STARTUPINFOEX 핸들은 더 이상 필요하지 않은 경우 CloseHandle 사용하여 닫아야 합니다.
중요하다
호출자는 STARTUPINFO의 표준 핸들 필드에 유효한 핸들 값을 포함할 있습니다. 이러한 필드는 dwFlags 멤버가 STARTF_USESTDHANDLES지정하는 경우에도 유효성 검사 없이 자식 프로세스에 변경되지 않고 복사됩니다. 값이 잘못되면 자식 프로세스가 잘못 실행되거나 충돌할 수 있습니다. Application Verifier 런타임 확인 도구를 사용하여 잘못된 핸들을 검색합니다.
[out] lpProcessInformation
새 프로세스에 대한 식별 정보를 수신하는 PROCESS_INFORMATION 구조체에 대한 포인터입니다.
PROCESS_INFORMATION 핸들은 더 이상 필요하지 않은 경우 CloseHandle 사용하여 닫아야 합니다.
반환 값
함수가 성공하면 반환 값은 0이 아닌 값입니다.
함수가 실패하면 반환 값은 0입니다. 확장 오류 정보를 얻으려면 GetLastError호출합니다.
프로세스가 초기화를 완료하기 전에 함수가 반환됩니다. 필요한 DLL을 배치할 수 없거나 초기화에 실패하면 프로세스가 종료됩니다. 프로세스의 종료 상태를 얻으려면 GetExitCodeProcess호출합니다.
발언
프로세스에 프로세스 식별자가 할당됩니다. 식별자는 프로세스가 종료될 때까지 유효합니다. 프로세스를 식별하는 데 사용하거나 OpenProcess 함수에 지정하여 프로세스에 대한 핸들을 열 수 있습니다. 프로세스의 초기 스레드에도 스레드 식별자가 할당됩니다. OpenThread 함수에 지정하여 스레드에 대한 핸들을 열 수 있습니다. 식별자는 스레드가 종료될 때까지 유효하며 시스템 내에서 스레드를 고유하게 식별하는 데 사용할 수 있습니다. 이러한 식별자는 PROCESS_INFORMATION 구조에서 반환됩니다.
운영 체제가 프로세스에 제공하는 명령줄의 실행 파일 이름이 호출 프로세스가 CreateProcess 함수에 제공하는 명령줄의 실행 파일 이름과 반드시 동일하지는 않습니다. 운영 체제는 정규화된 경로 없이 제공되는 실행 파일 이름 앞에 정규화된 경로를 추가할 수 있습니다.
호출 스레드는 WaitForInputIdle 함수를 사용하여 새 프로세스가 초기화를 완료하고 입력이 보류되지 않은 사용자 입력을 대기할 때까지 대기할 수 있습니다. 새 프로세스가 초기화를 완료할 때까지 기다리지 않고 CreateProcess 반환되므로 부모 프로세스와 자식 프로세스 간의 동기화에 유용할 수 있습니다. 예를 들어 만들기 프로세스는 새 프로세스와 연결된 창을 찾기 전에 WaitForInputIdle 사용합니다.
프로세스를 종료하는 기본 방법은 ExitProcess 함수를 사용하는 것입니다. 이 함수는 프로세스에 연결된 모든 DLL에 종료에 접근하는 알림을 보내기 때문입니다. 프로세스를 종료하는 다른 방법은 연결된 DLL에 알리지 않습니다. 스레드가 ExitProcess
부모 프로세스는 프로세스를 만드는 동안 자식 프로세스의 환경 변수를 직접 변경할 수 있습니다. 이는 프로세스가 다른 프로세스의 환경 설정을 직접 변경할 수 있는 유일한 상황입니다. 자세한 내용은 환경 변수 변경
애플리케이션이 환경 블록을 제공하는 경우 시스템 드라이브의 현재 디렉터리 정보는 자동으로 새 프로세스로 전파되지 않습니다. 예를 들어 값이 C 드라이브의 현재 디렉터리인 =C라는 환경 변수가 있습니다. 애플리케이션은 새 프로세스에 현재 디렉터리 정보를 수동으로 전달해야 합니다. 이렇게 하려면 애플리케이션에서 이러한 환경 변수 문자열을 명시적으로 만들고, 사전순으로 정렬하고(시스템에서 정렬된 환경을 사용하기 때문에) 환경 블록에 배치해야 합니다. 일반적으로 환경 블록 정렬 순서로 인해 환경 블록의 맨 앞으로 이동합니다.
드라이브 X에 대한 현재 디렉터리 정보를 가져오는 한 가지 방법은 다음을 호출하는 것입니다. GetFullPathName("X:", ...)
. 따라서 애플리케이션이 환경 블록을 검사하지 않아도 됩니다. 반환된 전체 경로가 X:인 경우 루트 디렉터리가 새 프로세스의 드라이브 X에 대한 기본 현재 디렉터리이므로 해당 값을 환경 데이터로 전달할 필요가 없습니다.
CREATE_NEW_PROCESS_GROUP 지정한 프로세스를 만들면 새 프로세스를 대신하여 SetConsoleCtrlHandler(NULL,TRUE)에 대한 암시적 호출이 수행됩니다. 즉, 새 프로세스에서 Ctrl+C를 사용하지 않도록 설정했습니다. 이를 통해 셸은 Ctrl+C 자체를 처리하고 해당 신호를 하위 프로세스에 선택적으로 전달할 수 있습니다. Ctrl+BREAK는 사용하지 않도록 설정되지 않으며 프로세스/프로세스 그룹을 중단하는 데 사용할 수 있습니다.
기본적으로 truebInheritHandles 매개 변수의 값으로 전달하면 모든 상속 가능한 핸들이 새 프로세스에서 상속됩니다. 이는 여러 스레드에서 동시에 프로세스를 만들면서도 각 프로세스가 서로 다른 핸들을 상속하기를 원하는 애플리케이션에 문제가 될 수 있습니다.
애플리케이션은 PROC_THREAD_ATTRIBUTE_HANDLE_LIST 매개 변수와 함께 UpdateProcThreadAttributeList 함수를 사용하여 특정 프로세스에서 상속할 핸들 목록을 제공할 수 있습니다.
보안 설명
lpApplicationName
LPTSTR szCmdline = _tcsdup(TEXT("C:\\Program Files\\MyApp -L -S"));
CreateProcess(NULL, szCmdline, /* ... */);
악의적인 사용자가 시스템에서 "Program.exe"이라는 애플리케이션을 만드는 경우 Program Files 디렉터리를 사용하여 CreateProcess 잘못 호출하는 프로그램은 의도한 애플리케이션 대신 이 애플리케이션을 실행합니다.
이 문제를 방지하려면 lpApplicationNameNULL 전달하지 마세요. lpApplicationNameNULL 전달하는 경우 아래 예제와 같이 lpCommandLine실행 경로 주위에 따옴표를 사용합니다.
LPTSTR szCmdline[] = _tcsdup(TEXT("\"C:\\Program Files\\MyApp\" -L -S"));
CreateProcess(NULL, szCmdline, /*...*/);
예제
예제는 프로세스 만들기
메모
processthreadsapi.h 헤더는 CREATEProcess를 유니코드 전처리기 상수의 정의에 따라 이 함수의 ANSI 또는 유니코드 버전을 자동으로 선택하는 별칭으로 정의합니다. 인코딩 중립 별칭을 인코딩 중립이 아닌 코드와 혼합하면 컴파일 또는 런타임 오류가 발생하는 불일치가 발생할 수 있습니다. 자세한 내용은 함수 프로토타입대한
요구 사항
요구 | 값 |
---|---|
지원되는 최소 클라이언트 | Windows XP [데스크톱 앱 | UWP 앱] |
지원되는 최소 서버 | Windows Server 2003 [데스크톱 앱 | UWP 앱] |
대상 플랫폼 | Windows |
헤더 | processthreadsapi.h(Windows Server 2003, Windows Vista, Windows 7, Windows Server 2008 Windows Server 2008 R2의 Windows.h 포함) |
라이브러리 | Kernel32.lib |
DLL | Kernel32.dll |
참고 항목
closeHandle
CreateProcessAsUser
CreateProcessWithLogonW
GetCommandLine
GetEnvironmentStrings
GetExitCodeProcess
GetFullPathName
GetStartupInfo
OpenProcess
프로세스 및 스레드 함수
SetErrorMode
waitForInputIdle