GuestBook |  PDS  |  WebGame  |  Crypt


이제까지 프로세스 관련 구조체와 프로세스 조작에 관련된 API 함수를 살펴보았다. 또한 어떻게 툴을 이용하여 시스템에서 활동중인 프로세스들의 정보를 살펴보는지도 알아보았다. 그러면 프로세스는 어떻게 시작되고 어떻게 종료되는가? 이 섹션에서는 이러한 Win32 프로세스의 삶을 알아보겠다.


Win32 프로세스는 어플리케이션이 CreateProcess, CreateProcessAsUserCreateProcessWithLogonW와 같은 프로세스 생성 함수를 호출하였을 때 생성된다. Win32 플로세스의 생성은 운영체제의 세 부분에서 수행되는 몇 단계로 이루어진다: Win32 클라이언트 라이브러리 Kernel32.dll, Windows 2000 실행부, Win32 서브시스템 프로세스(Csrss). Windows 2000의 다양한 서브시스템 구조로 인해, Windows 2000 실행부 프로세스 객체의 생성은 Win32 프로세스 생성에 관련된 일과 분리되어 있다.


다음은 Win32 CreateProcess 함수의 프로세스 생성 과정을 요약한 것이다. 각각의 단계는 다음 섹션에서 자세히 다루어진다.




  1. 프로세스 안에서 실행될 이미지 파일(.exe)를 연다.



  2. Windows 2000 실행부 프로세스 객체를 생성한다.



  3. 초기 쓰레드(스택, 컨텍스트, Windows 2000 실행부 쓰레드 객체)를 생성한다.



  4. Notify the Win32 subsystem of the new process so that it can set up for the new process and thread.



  5. 초기 쓰레드의 실행을 시작한다(CREATE_SUSPENDED 플래그가 설정되어 있지 않다면).



  6. 새로운 프로세스와 쓰레드의 컨텍스트에서, DLL 로드와 같은 주소 공간의 초기화를 수행하고 프로그램 실행을 시작하다.


그림 6-5는 프로세스 생성 단계를 보여준다.


Click to view at full size.


그림 6-5  프로세스 생성의 중요 단계


위 단계들을 자세히 설명하기 전에, 먼저 모든 단계에 적용되는 몇 가지 중요한 점을 살펴보자.




  • In CreateProcess, the priority class for the new process is specified as independent bits in the CreationFlags parameter. Thus, you can specify more than one priority class for a single CreateProcess call. Windows 2000 resolves the question of which priority class to assign to the process by choosing the lowest-priority class set.



  • If no priority class is specified for the new process, the priority class defaults to Normal unless the priority class of the process that created it is Idle or Below Normal, in which case the priority class of the new process will have the same priority as the creating class.



  • If a Real-time priority class is specified for the new process and the process's caller doesn't have the Increase Scheduling Priority privilege, the High priority class is used instead. In other words, CreateProcess doesn't fail just because the caller has insufficient privileges to create the process in the Real-time priority class; the new process just won't have as high a priority as Real-time.



  • All windows are associated with desktops, the graphical representation of a workspace. If no desktop is specified in CreateProcess, the process is associated with the caller's current desktop.


이제 배경지식을 알았으니 다음 섹션에서  CreateProcess 처리 단계를 자세히 알아보자.




노트


  CreateProcess 에서의 많은 단계들은 프로세스 가상 주소 공간에서의 설정 작업과 관련되므로 7장 에서 정의한 여러 메모리 관리 용어와 구조체를 참조하라.


1 단계: 실행 이미지 열기


그림 6-6와 같이,  CreateProcess 의 첫 번째 단계는 호출자에 의해 지정된 실행 파일을 실행할 적당한 Win32 이미지를 찾고 나중에 새 프로세스 주소 공간에 매핑될 섹션 객체를 생성하는 것이다. 이미지 이름이 지정되지 않으면 커맨드 라인의 첫 번째 토큰이 이미지 파일이름으로 사용된다.


Click to view at full size.


그림 6-6  Win32 이미지 선택


실행 파일이 Win32 .exe이라면 바로 사용된다. 그것이 Win32 .exe가 아니라면(예를 들어, 그것이 MS-DOS, Win16, POSIX, OS/2 실행 파일이라면), CreateProcess는 그것을 실행시킬 Win32 지원 이미지를 찾기 위해 몇 단계를 거친다. This process is necessary because non-Win32 applications aren't run directly-Windows 2000 instead uses one of a few special support images that in turn are responsible for actually running the non-Win32 program. For example, if you attempt to run a POSIX application, CreateProcess identifies it as such and changes the image to be run on the Win32 executable file Posix.exe. If you attempt to run an MS-DOS or a Win16 executable, the image to be run becomes the Win32 executable Ntvdm.exe. 즉, 당신은 Win32 프로세스가 아닌 프로세스를 직접적으로 실행시킬 수 없다는 것이다. Windows 2000이 실행 파일을 실행할 적당한 이미지를 찾지 못하면  CreateProcess는 실패한다.




























어플리케이션 종류 실행시킬 이미지 And this will happen
POSIX 실행 파일 Posix.exe CreateProcess restarts Stage 1
OS/2 1.x 이미지 Os2.exe CreateProcess restarts Stage 1
.exe, .com, .pif 확장자를 가진 MS-DOS 어플리케이션 Ntvdm.exe CreateProcess restarts Stage 1
Win16 어플리케이션 Ntvdm.exe CreateProcess restarts Stage 1
.bat, .com 확장자를 가진 커맨트 프로시져 MS-DOS 어플리케이션 Cmd.exe CreateProcess restarts Stage 1


Specifically, the decision tree that CreateProcess goes through to run an image is as follows:




  • If the image is an OS/2 1.x application, the image to be run changes to Os2.exe and CreateProcess restarts at Stage 1.



  • If the image is an MS-DOS application with an .exe, a .com, or a .pif extension, a message is sent to the Win32 subsystem to check whether an MS-DOS support process (Ntvdm.exe, specified in the registry value HKLMSYSTEMCurrentControlSetControlWOWcmdline) has already been created for this session. If a support process has been created, it is used to run the MS-DOS application (the Win32 subsystem sends the message to the VDM [Virtual DOS Machine] process to run the new image) and CreateProcess returns. If a support process hasn't been created, the image to be run changes to Ntvdm.exe and CreateProcess restarts at Stage 1.



  • If the file to run has a .bat or a .cmd extension, the image to be run becomes Cmd.exe, the Windows 2000 command prompt, and CreateProcess restarts at Stage 1. (The name of the batch file is passed as the first parameter to Cmd.exe.)



  • If the image is a Win16 (Windows 3.1) executable, CreateProcess must decide whether a new VDM process must be created to run it or whether it should use the default systemwide shared VDM process (which might not yet have been created). The CreateProcess flags CREATE_SEPARATE_WOW_VDM and CREATE_SHARED_WOW_VDM control this decision. If these flags aren't specified, the registry value HKLMSYSTEMCurrentControlSetControlWOWDefaultSeparateVDM dictates the default behavior. If the application is to be run in a separate VDM, the image to be run changes to the value of HKLMSYSTEMCurrentControlSetControlWOWwowcmdline and CreateProcess restarts at Stage 1. Otherwise, the Win32 subsystem sends a message to see whether the systemwide VDM process exists and can be used. (If the VDM process is running on a different desktop or isn't running under the same security as the caller, it can't be used and a new VDM process must be created.) If a systemwide VDM process can be used, the Win32 subsystem sends a message to it to run the new image and CreateProcess returns. If the VDM process hasn't yet been created (or if it exists but can't be used), the image to be run changes to the VDM support image and CreateProcess restarts at Stage 1.


이 시점에서, CreateProcess 는 성공적으로 유요한 Windows 2000 실행 파일을 열고 섹션 객체를 생성한다. 객체는 열려 있지만 아직 메모리에 매핑되지는 않다. Just because a section object has been successfully created doesn't mean that the file is a valid Win32 image, however; it could be a DLL or a POSIX executable. If the file is a POSIX executable, the image to be run changes to Posix.exe and CreateProcess restarts from the beginning of Stage 1. If the file is a DLL, CreateProcess fails.


Now that CreateProcess has found a valid Win32 executable, it looks in the registry under HKLMSOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Options to see whether a subkey with the filename and extension of the executable image (but without the directory and path information?for example, Image.exe) exists there. If it does, CreateProcess looks for a value named Debugger for that key. If the value isn't null, the image to be run becomes the string in that value and CreateProcess restarts at Stage 1.







You can take advantage of this CreateProcess behavior and debug the startup code of Windows 2000 service processes before they start rather than attach the debugger after starting the service, which doesn't allow you to debug the startup code. If you're feeling mischievous, you can also exploit this behavior to confuse people by causing another file to be run rather than the one they specified.


2 단계: Windows 2000 실행부 프로세스 객체 생성


이 시점에서, CreateProcess는 Win32 실행 파일을 열었고 새 프로세스 주소 공간에 매핑할 섹션 객체를 생성했다. 다음으로 내부 시스템 함수인 NtCreateProcess를 호출함으로써 이미지를 실행하기 위한 Windows 2000 실행부 프로세스 객체를 생성한다. 실행부 프로세스 객체 생성은 다음 하위 단계로 이루어진다:




  1. EPROCESS 블럭 설정



  2. 초기 프로세스 주소 공간 생성



  3. 커널 프로세스 블럭 생성



  4. 프로세스 주소 공간 설정의 마무리



  5. PEB 설정



  6. 실행부 프로세스 객체 설정의 완료




노트


부모 프로세스가 없는 유일한 시간은 시스템 초기화 동안 뿐이다. 그 이후에는, 새 프로세스에 보안 컨텍스트를 제공하기 위해 항상 부모 프로세스가 필요하다.


2A 단계: EPROCESS 블럭 설정


이 단계는 다음 다섯 단계로 이루어진다:




  1. Windows 2000 EPROCESS 블럭을 할당하고 초기화한다.



  2. Set the new process's quota block to the address of its parent process's quota block, and increment the reference count for the parent's quota block.



  3. 새 프로세스 객체의 InheritedFromUniqueProcessId 필드에 부모 프로세스의 프로세스 ID와 세션 ID를 저장한다.



  4. 새 프로세스의 상태를 STATUS_PENDING으로 설정한다.



  5. 프로세스의 primary access token(부모 primary token의 복사본)을 생성한다. 새 프로세스는 부모 프로세스의 security profile을 상속받는다. If the CreateProcessAsUser function is being used to specify a different access token for the new process, the token is then changed appropriately.


2B 단계: 프로세스 기본 주소 공간 생성


초기 프로세스 주소 공간은 다음 세 페이지로 이루어진다:




  • 페이지 디렉토리



  • 하이퍼스페이스 페이지



  • 작업 세트 목록


위 세 페이지를 생성하기 위해 다음 과정이 필요하다:




  1. 페이지 테이블에 세 개의 초기 페이지를 매핑하기 위한 페이지 테이블 엔트리가 생성된다.



  2. 이 세 페이지로 인해, 커널 변수 MmTotalCommittedPages는 3이 감소되고  MmProcessCommit에는 3이 더해진다.



  3. 시스템 전역 기본 프로세스 최소 작업 세트 크기(PsMinimumWorkingSet )는  MmResident-AvailablePages만큼 감소된다.



  4. The page table pages for the nonpaged portion of system space and the system cache are mapped into the process.



  5. 프로세스 최소, 최대 작업 세트 크기는 PsMinimumWorkingSet, PsMaximumWorkingSet값으로 각각 설정된다.


2C 단계: 커널 프로세스 블럭 생성


CreateProcess 의 다음 단계는 커널 쓰레드 목록에 대한 포인터를 가지는 KPROCESS 블럭의 초기화이다. (The kernel has no knowledge of handles, so it bypasses the object table.) 커널 프로세스 블럭은 또한 (프로세스 가상 주소 공간 정보를 유지하기 위한)프로세스 페이지 테이블 디렉토리에 대한 포인터, 프로세스의 쓰레드가 실행된 총 시간, 프로세스의 초기 베이스 스케쥴링 우선순위(which starts as Normal, or 8, unless the parent process was set to Idle or Below Normal, in which case the setting is inherited), 쓰레드의 기본 프로세스 친화도, 시스템 전역 퀀텀 배열의 첫 번째 엔트리인  PspForegroundQuantum[0]로부터 가져오는 프로세스 기본 퀀텀의 초기값 등에 대한 정보를 가진다.




노트


기본 초기 퀀텀은 Windows 2000 Professional과 Windows 2000 Server에서 다르다. 쓰레드 퀀텀에 대한 더 자세한 설명은 "쓰레드 스케쥴링"을 살펴보라.


2D 단계: 프로세스 주소 공간 설정 마무리


새 프로세스를 위한 주소 공간의 설정은 다소 복잡하다, so let's look at what's involved one step at a time. 이 섹션에서 설명하는 대부분을 이해하려면   7장에서 설명하는 Windows 2000 메모리 관리자에 해새 친숙히 알고 있어야 한다.




  1. 가상 메모리 관리자는 프로세스의 마지막 trim 시간을 현재 시간으로 설정한다. The working set manager (which runs in the context of the balance set manager system thread) uses this value to determine when to initiate working set trimming.



  2. The page frame number (PFN) database for the page directory as well as the page directory entry, which maps hyperspace, are initialized.



  3. 메모리 관리자는 프로세스 작업 세트 목록을 초기화한다. 페이지 폴트가 발생할 수 있다.



  4. 메이저, 마이너 버전이 실행 파일에서 EPROCESS 블럭으로 복사된다.



  5. (이미지 파일이 열였을 때 생성된) 섹션이 이제 프로세스 주소 공간에 매핑된고 프로세스 섹션 베이스 주소가 이미지의 베이스 주소고 설정된다.



  6. Ntdll.dll가 process에 매핑된다.



  7. 시스템 전역 national language support (NLS) 테이블이 프로세스 주소 공간에 매핑된다.




NOTE


POSIX processes clone the address space of their parents, so they don't have to go through these steps to create a new address space. In the case of POSIX applications, the new process's section base address is set to that of its parent process and the parent's PEB is cloned for the new process.




  1. 부모 프로세스가 어떤 job에 포함되어 있었다면, 새 프로세스는 그 job에 더해진다.



  2. CreateProcess 는 새 프로세스 블럭을 active 프로세스 목록(PsActiveProcessHead) 끝에 넣는다.


2E 단계: PEB 설정


CreateProcess 는 PEB를 위한 페이지를 할당하고 표6-7과 같이 필드를 초기화한다.


표 6-7 PEB 필드의 초기값




















































필드 초기값
ImageBaseAddress 섹션의 베이스 주소
NumberOfProcessors KeNumberProcessors 커널 변수
NtGlobalFlag NtGlobalFlag 커널 변수
CriticalSectionTimeout MmCriticalSectionTimeout 커널 변수
HeapSegmentReserve MmHeapSegmentReserve 커널 변수
HeapSegmentCommit MmHeapSegmentCommit 커널 변수
HeapDeCommitTotalFreeThreshold MmHeapDeCommitTotalFreeThreshold 커널 변수
HeapDeCommitFreeBlockThreshold MmHeapDeCommitFreeBlockThreshold 커널 변수
NumberOfHeaps 0
MaximumNumberOfHeaps (Size of a page - size of a PEB) / 4
ProcessHeaps First byte after PEB
OSMajorVersion NtMajorVersion 커널 변수
OSMinorVersion NtMinorVersion 커널 변수
OSBuildNumber NtBuildNumber  커널 변수 & 0x3FFF
OSPlatformId 2


If the image file specifies explicit Win32 version values, this information replaces the initial values shown in Table 6-7. The mapping from image version information fields to PEB fields is described in Table 6-8.


표 6-8 Win32 Replacements for Initial PEB Values



















Field Name Value Taken from Image Header
OSMajorVersion OptionalHeader.Win32VersionValue & 0xFF
OSMinorVersion (OptionalHeader.Win32VersionValue >> 8) & 0xFF
OSBuildNumber (OptionalHeader.Win32VersionValue >> 16) & 0x3FFF
OSPlatformId (OptionalHeader.Win32VersionValue >> 30) ^ 0x2


2F 단계: Completing the Setup of the Executive Process Object


Before the handle to the new process can be returned, a few final setup steps must be completed:




  1. The process handle table is initialized; if the inherit handles flag is set for the parent process, any inheritable handles are copied from the parent's object handle table into the new process. (For more information about object handle tables, see Chapter 3.)



  2. If you're running Windows 2000 Professional and the image header specifies IMAGE_FILE_AGGRESIVE_WS_TRIM, the PS_WS_TRIM_FROM_EXE_HEADER flag is set in the process block. This causes the working set manager to aggressively steal pages from the process. If you're running Windows 2000 Professional on a small-memory x86 system, the PS_WS_TRIM_BACKGROUND_ONLY_APP flag is set in the process block, which limits the aggressive trimming to processes that aren't associated with the foreground window. These working set flags are not set for processes created on systems running Windows 2000 Server.



  3. If the image header characteristics IMAGE_FILE_UP_SYSTEM_ONLY flag is set (indicating that the image can run only on a uniprocessor system), a single CPU is chosen for all the threads in this new process to run on. This choosing process is done by simply cycling through the available processors?each time this type of image is run, the next processor is used. In this way, these types of images are spread out across the processors evenly.



  4. If the image specifies an explicit processor affinity mask (for example, a field in the configuration header), this value is copied to the PEB and later set as the default process affinity mask.



  5. If the parent process had an Event Log section in its PEB, the Event Log is copied to the new process and a handle is duplicated to the section for the new process.



  6. If systemwide auditing of processes is enabled (which is accomplished through the Group Policy snap-in), the process's creation is written to the Audit Log.



  7. The process's creation time is set, the handle to the new process is returned to the caller (CreateProcess in Kernel32.dll), and execution returns to the original caller of CreateProcess.


3 단계: 초기 쓰레드와 스택, 컨텍스트를 생성


At this point, the Windows 2000 executive process object is completely set up. It still has no thread, however, so it can't do anything yet. Before the thread can be created, it needs a stack and a context in which to run, so these are set up now. The stack size for the initial thread is taken from the image?there's no way to specify another size.


Now the initial thread can be created, which is done by calling NtCreateThread. (For a detailed description of how a thread is created, see the section "Flow of CreateThread.") The thread parameter (which can't be specified in CreateProcess but can be specified in CreateThread) is the address of the PEB. This parameter will be used by the initialization code that runs in the context of this new thread (as described in Stage 6). However, the thread won't do anything yet?it is created in a suspended state and isn't resumed until the process is completely initialized (as described in Stage 5).


4 단계: Win32 서브시스템에게 새 프로세스를 통지


필요한 모든 실행부 프로세스와 쓰레드 객체가 생성된 후, Kernel32.dll은 Win32 서브시스템에 메시지를 보내 새 프로세스와 쓰레드에 대한 설정을 할 수 있게 한다. 메시지는 다음 정보를 포함한다:




  • 프로세스와 쓰레드 핸들



  • Entries in the creation flags



  • 프로세스 생성자의 ID



  • Flag indicating whether the process belongs to a Win32 application (so that Csrss can determine whether or not to show the startup cursor)


Win32 서브시스템은 이 메시지를 받았을 때 다음 과정을 수행한다:




  1. CreateProcess duplicates a handle for the process and thread. In this step, the usage count of the process and the thread is incremented from 1 (set at creation time) to 2.



  2. If a process priority class isn't specified, CreateProcess sets it according to the algorithm described below.



  3. The Csrss process block is allocated.



  4. The new process's exception port is set to be the general function port for the Win32 subsystem so that the Win32 subsystem will receive a message when an exception occurs in the process. (For further information on exception handling, see Chapter 3.)



  5. If the process is being debugged (that is, if it is attached to a debugger process), the process debug port is set to the Win32 subsystem's general function port. This setting ensures that Windows 2000 will send debug events that occur in the new process (such as thread creation and deletion, exceptions, and so on) as messages to the Win32 subsystem so that it can then dispatch the events to the process that is acting as the new process's debugger.



  6. The Csrss thread block is allocated and initialized.



  7. CreateProcess inserts the thread in the list of threads for the process.



  8. 이 세션의 프로세스 카운트가 증가한다.



  9. The process shutdown level is set to x280 (the default process shutdown level?see SetProcessShutdownParameters in the MSDN Library documentation for more information).



  10. The new process block is inserted into the list of Win32 subsystem-wide processes.



  11. The per-process data structure used by the kernel-mode part of the Win32 subsystem (W32PROCESS structure) is allocated and initialized.



  12. The application start cursor is displayed. This cursor is the familiar arrow with an hourglass attached?the way that Windows 2000 says to the user, "I'm starting something, but you can use the cursor in the meantime." If the process doesn't make a GUI call after 2 seconds, the cursor reverts to the standard pointer. If the process does make a GUI call in the allotted time, CreateProcess waits 5 seconds for the application to show a window. After that time, CreateProcess will reset the cursor again.


5 단계: 초기 쓰레드의 실행 시작


At this point, the process environment has been determined, resources for its threads to use have been allocated, the process has a thread, and the Win32 subsystem knows about the new process. Unless the caller specified the CREATE_SUSPENDED flag, the initial thread is now resumed so that it can start running and perform the remainder of the process initialization work that occurs in the context of the new process (Stage 6).


6 단계: 새 프로세스 컨텍스트에서 초기화 작업 수행


KiInitializeContextThread, which is called by KeInitializeThread, builds the initial context of the thread and the thread's kernel stack. The new thread begins life running the kernel-mode thread startup routine KiThreadStartup. (For a more detailed description of the thread startup steps leading to this, see the section "Flow of CreateThread.") The KiThreadStartup routine performs the following steps:




  1. IRQL 레벨을 DPC/dispatch 레벨에서 APC 레벨로 낮춘다.



  2. Enables working set expansion.



  3. Queues a user-mode APC to the new thread to execute the user-mode thread startup routine LdrInitializeThunk inside Ntdll.dll.



  4. Lowers the IRQL level to 0, causing the APC to fire and LdrInitializeThunk to be called. The LdrInitializeThunk routine initializes the loader, heap manager, NLS tables, thread-local storage (TLS) array, and critical section structures. It then loads any required DLLs and calls the DLL entry points with the DLL_PROCESS_ATTACH function code.



  5. If the process being created is a debuggee, all threads in the process are suspended. (Threads might have been created during step 3.) A create process message is then sent to the process's debug port (the Win32 subsystem function port because this is a Win32 process) so that the subsystem can deliver the process startup debug event (CREATE_PROCESS_DEBUG_INFO) to the appropriate debugger process. KiThreadStartup then waits for the Win32 subsystem to get the reply from the debugger (via the ContinueDebugEvent function). When the Win32 subsystem replies, all the threads are resumed.



  6. 마침내, 이미지는 유저 모드에서 실행을 시작한다. 이것은 이전 모드를 유저 모드로, 리턴 주소를 이미지의 메인 엔트리 포인트로 지정한 트랩 프레임을 생성함으로써 수행된다. Thus, when the trap that caused the thread to start execution in kernel mode is dismissed, the program begins running in user mode at the right place.

트랙백 주소 :: http://dual5651.hacktizen.com/tt/trackback/2

댓글을 달아 주세요