2008년 04월 01일
프로세스를 다루는 API에 관해서 알아보자[펌]
안녕하십니까. (응?)
오늘은 오랜만에 제가 좋아하는 간단한 주제로 넘어가 볼까 합니다. (어째 말이 이상하다??)
바로 프로세스에 관한 겁니다.
"프로세스" 는 여러분이 작업 관리자에서 보셨듯이, [프로세스] 탭에서 많이 보셨으리라 생각됩니다.
이것은 영어로 "수행하다", "진행" ....
같은 뜻을 담고 있는데요, 그와 마찬가지로 생각하시면 됩니다.
(일을 수행하는 하나의 객체로 보면 되는건가......설명이 좀 애매하군)
자, 그렇다면 이제 프로세스에 관한 간단한 API를 알아 보도록 합시다.
(앞에서 프로세스에 대한 정의도 제대로 하지 않았으면서, 뭘 설명하려는거냐!!!!)
이 글에서 설명하는 API는 이렇습니다.
OpenProcess
CreateProcess
TerminateProcess
ExitProcess
GetPriorityClass
SetPriorityClass
GetCurrentProcess
GetCurrentProcessId
SetProcessAffinityMask
GetExitCodeProcess
Process32First
Process32Next
NtSuspendProcess [Windows XP 이상에서만 동작]
NtResumeProcess [Windows XP 이상에서만 동작]
NtOpenProcess [Windows 2000/NT 이상에서만 동작, NT는 예외]
NtTerminateProcess [Windows 2000/NT 이상에서만 동작, NT는 예외]
NtQueryInformationProcess [Windows 2000/NT 이상에서만 동작, NT는 예외]
NtSetInformationProcess [Windows 2000/NT 이상에서만 동작, NT는 예외]
NtCreateProcess [Windows 2000/NT 이상에서만 동작, NT는 예외]
NtCreateProcessEx [Windows XP 이상에서만 동작]
OpenProcess : 프로세스의 핸들을 얻는다. 프로세스를 다룰 때에는 유저모드에서는 대부분 핸들로 다루고,
커널모드에서는 Process Object(Executive Process:EPROCESS)로 다루나, 여전히 핸들도 같이 쓰인다.
WINBASEAPI
HANDLE
WINAPI
OpenProcess(
IN DWORD dwDesiredAccess,
IN BOOL bInheritHandle,
IN DWORD dwProcessId);
dwDesiredAccess : 프로세스의 핸들을 얻을 때의 설정할 권한.
간단하게 몇개만 설명하자면,
PROCESS_CREATE_THREAD : 프로세스에 쓰레드 생성시에
PROCESS_VM_READ : 프로세스의 메모리를 읽을 시에
PROCESS_VM_WRITE : 프로세스의 메모리를 쓸 시에
PROCESS_TERMINATE : 프로세스를 종료할 시에
PROCESS_QUERY_INFORMATION : 프로세스의 정보를 얻고자 할 시에
PROCESS_ALL_ACCESS (최강) : 이 플래그를 주어서 얻어진 핸들에는 모든 권한이 주어진다.
bInheritHandle : 핸들을 상속할지의 여부. 대부분 FALSE.
dwProcessId : 프로세스를 열 때 필요한 프로세스 아이디. PID라고도 불리며, 프로세스 식별자라고도 한다.
성공시 NULL이 아닌 값을, 실패시 NULL을 반환한다.
이 경우, GetLastError()를 이용해서 오류 코드를 얻을 수 있다.
CreateProcess : 프로세스를 생성한다.
WINBASEAPI
BOOL
WINAPI
CreateProcess(
IN LPCTSTR lpApplicationName,
IN LPTSTR lpCommandLine,
IN LPSECURITY_ATTRIBUTES lpProcessAttributes,
IN LPSECURITY_ATTRIBUTES lpThreadAttributes,
IN BOOL bInheritHandles,
IN DWORD dwCreationFlags,
IN LPVOID lpEnvironment,
IN LPCTSTR lpCurrentDirectory,
IN LPSTARTUPINFO lpStartupInfo,
IN LPPROCESS_INFORMATION lpProcessInformation);
lpApplicationName : 실행 파일의 경로.(Full Path가 아니어도 된다.)
lpCommandLine : 프로세스 실행시 넣어줄 추가적 명령줄.
lpProcessAttributes : 프로세스 생성시의 보안 속성(이라고 보여진다). 대부분 NULL.lpThreadAttributes : 프로세스의 메인 쓰레드 생성시의 보안 속성(이라고 보여진다). 대부분 NULL.
bInheritHandles : 핸들 상속 여부. 대부분 FALSE.
dwCreationFlags : 프로세스 생성시의 추가 플래그.
CREATE_SUSPENDED : 프로세스 생성시에 프로세스를 일시정지 상태로 생성한다.
XXX_PRIORITY_CLASS : 프로세스의 우선 순위. (XXX에는 NORMAL, HIGH 등이 올 수 있다.)
이 외에도 여러가지가 있다.
lpEnvironment : 환경 설정(혹은 변수???)로 여겨진다. 필자는 이것을 NULL이 아닌 값을 주어본 적이 없다.
lpCurrentDirectory : 생성되는 프로세스가 인식할 Current Directory.
lpStartupInfo : 프로세스의 시작 정보. (절대로 NULL이 들어가서는 안된다.)
lpProcessInformation : 프로세스와 메인 쓰레드의 정보. (절대로 NULL이 들어가서는 안된다.)
성공시 1, 실패시 0을 반환한다.
TerminateProcess : 프로세스를 종료한다.
WINBASEAPI
BOOL
WINAPI
TerminateProcess(
IN HANDLE hProcess,
IN DWORD dwExitCode);
hProcess : 프로세스의 핸들.
dwExitCode : 프로세스 종료시에 Set할 종료 코드.
성공시 1, 실패시 0을 반환한다.
※ 주의 : 이 함수는 비동기 함수이다. 때문에 1을 반환한다 할지라도 완전히 종료가 되지 않는 경우가 있다.
ExitProcess : 자기 자신을 종료한다.
WINBASEAPI
VOID
WINAPI
ExitProcess(
IN DWORD ExitCode);
ExitCode : 자기자신 종료시에 Set할 종료 코드.
반환값 없음
GetPriorityClass : 프로세스의 우선순위를 얻어온다.
WINBASEAPI
DWORD
WINAPI
GetPriorityClass(
IN HANDLE hProcess);
hProcess : 프로세스의 핸들.
프로세스의 우선순위값을 반환한다.
SetPriorityClass : 프로세스의 우선순위를 조정한다.
WINBASEAPI
BOOL
WINAPI
SetPriorityClass(
IN HANDLE hProcess,
IN DWORD dwProcessPriorityClass);
hProcess : 프로세스의 핸들.
dwProcessPrioriyClass : 변경할 프로세스의 우선 순위값.
XXX_PRIORITY_CLASS 가 있다. (XXX에는 NORMAL, HIGH 등이 있다.)
성공시 1, 실패시 0을 반환한다.
GetCurrentProcess : 자기자신의 프로세스 핸들을 얻는다.
WINBASEAPI
HANDLE
WINAPI
GetCurrentProcess(
VOID);
필요인자 없음.
자기자신의 프로세스 핸들값을 반환한다. (특히나, Windows 2000/NT/XP/2003/Vista 등은 항상 0xFFFFFFFF를 반환한다.)
GetCurrentProcessId : 자기자신의 프로세스 아이디를 얻는다.
WINBASEAPI
DWORD
WINAPI
GetCurrentProcessId(
VOID);
필요인자 없음.
자기자신의 프로세스 아이디를 반환한다.
SetProcessAffinityMask : 프로세스의 동작 프로세서(Processor)를 지정한다.
WINBASEAPI
BOOL
WINAPI
SetProcessAffinityMask(
IN HANDLE hProcess,
IN DWORD dwProcessAffinityMask);
hProcess : 프로세스의 핸들.
dwProcessAffinityMask : 프로세서의 번호. (1부터 시작한다.)
성공시 1, 실패시 0을 반환한다.
GetExitCodeProcess : 프로세스의 상태코드를 얻어온다.
WINBASEAPI
BOOL
WINAPI
GetExitCodeProcess(
IN HANDLE hProcess,
OUT PDWORD lpdwExitCode);
hProcess : 프로세스의 핸들.
lpdwExitCode : DWORD의 포인터형. 여기로 프로세스의 상태코드가 넘어온다.
성공시 1, 실패시 0을 반환한다.
Process32First : 맨 처음 프로세스 정보를 얻는다.
WINBASEAPI
BOOl
WINAPI
Process32First(
IN HANDLE hSnapshot,
OUT LPPROCESSENTRY32 lpProcessEntry32);
hSnapshot : CreateToolhelp32Snapshot() 으로 얻어진 올바른 스냅샷 핸들.
lpProcessEntry32 : PROCESSENTRY32 구조체의 포인터형. 여기로 프로세스의 정보가 넘어온다.
성공시 1, 실패시 0을 반환한다.
Process32Next : 그 다음의 프로세스 정보를 얻는다.
WINBASEAPI
BOOl
WINAPI
Process32Next(
IN HANDLE hSnapshot,
OUT LPPROCESSENTRY32 lpProcessEntry32);
hSnapshot : CreateToolhelp32Snapshot() 으로 얻어진 올바른 스냅샷 핸들.
lpProcessEntry32 : PROCESSENTRY32 구조체의 포인터형. 여기로 프로세스의 정보가 넘어온다.
성공시 1, 실패시 0을 반환한다.
NT_SUCCESS 매크로. (이것은 보너스.)
리턴값이 NTSTATUS 형인 경우, 이 리턴값이 성공적인지를 확인하는 매크로가 있는데, 이것을 NT_SUCCESS() 라고 한다.
#define NT_SUCCESS(_Status) _Status<=0 ? TRUE : FALSE
NtSuspendProcess : 프로세스를 일시정지시킨다.
NTSYSAPI
NTSTATUS
NTAPI
NtSuspendProcess(
IN HANDLE ProcessHandle);
ProcessHandle : 프로세스의 핸들.
주의할 점 : 성공했다 할지라도, SuspendCount가 0을 넘지 않으면 프로세스는 일시정지되지 않는다.
성공시, 0 이하의 값을 반환한다.
NtResumeProcess : 일시정지된 프로세스를 재개시킨다.
NTSYSAPI
NTSTATUS
NTAPI
NtResumeProcess(
IN HANDLE ProcessHandle);
ProcessHandle : 프로세스의 핸들.
성공시, 0 이하의 값을 반환한다.
NtOpenProcess : 프로세스를 연다. OpenProcess()가 내부적으로 호출하는 함수.
NTSYSAPI
NTSTATUS
NTAPI
NtOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId OPTIONAL);
ProcessHandle : 프로세스의 핸들.
DesiredAccess : 프로세스의 핸들을 얻을 때의 설정할 권한.
간단하게 몇개만 설명하자면,
PROCESS_CREATE_THREAD : 프로세스에 쓰레드 생성시에
PROCESS_VM_READ : 프로세스의 메모리를 읽을 시에
PROCESS_VM_WRITE : 프로세스의 메모리를 쓸 시에
PROCESS_TERMINATE : 프로세스를 종료할 시에
PROCESS_QUERY_INFORMATION : 프로세스의 정보를 얻고자 할 시에
PROCESS_ALL_ACCESS (최강) : 이 플래그를 주어서 얻어진 핸들에는 모든 권한이 주어진다.
ObjectAttributes : 프로세스를 얻을 때의 핸들에 부여할 추가적 속성.
ClientId : 프로세스 아이디가 이 구조체에 들어간다.
성공시, 0 이하의 값을 반환한다.
NtTerminateProcess : 프로세스를 종료한다. TerminateProcess()가 내부적으로 호출하는 함수.
NTSYSAPI
NTSTATUS
NTAPI
NtTerminateProcess(
IN HANDLE hProcess,
IN NTSTATUS ExitStatus);
hProcess : 프로세스의 핸들.
ExitStatus : 프로세스 종료시에 Set할 종료 코드.
이 함수 역시 비동기함수이다.
성공시, 0 이하의 값을 반환한다.
NtQueryInformationProcess : 프로세스의 정보를 가져온다.
GetExitCodeProcess(), GetPriorityClass() 등이 내부적으로 호출하는 함수.
NTSYSAPI
NTSTATUS
NTAPI
NtQueryInformationProcess(
IN HANDLE ProcessHandle,
IN PROCESS_INFORMATION_CLASS ProcessInformationClass,
OUT PVOID ProcessInformationBuffer,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL);
ProcessHandle : 프로세스의 핸들.
ProcessInformationClass : 이 값에 따라서 얻을 수 있는 정보가 달라진다.
typedef enum _PROCESS_INFORMATION_CLASS {
ProcessBasicInformation,
........
} PROCESS_INFORMATION_CLASS, *PPROCESS_INFORMATION_CLASS;
이런 꼴이나, 설명하기에는 너무 길기 때문에 생략하겠다.
ProcessInformationBuffer : ProcessInformationClass로 지정한 값에 따라서 구조체가 달라진다.
ProcessInformationClass이 ProcessBasicInformation인 경우는 PROCESS_BASIC_INFORMATION 의 포인터형이다.
다 설명하자면 너무 길으므로 생략하겠다.
ProcessInformationLength : ProcessInformationClass로 지정한 값에 따라서 크기가 달라진다.
ProcessInformationClass이 ProcessBasicInformation인 경우는 PROCESS_BASIC_INFORMATION 구조체의 크기이다.
ReturnLength : 실패시, 길이가 맞지 않거나 한 경우는 여기로 필요한 길이가 넘어온다.
성공시, 0 이하의 값을 반환한다.
NtSetInformationProcess : 프로세스의 정보를 변경한다. SetPriorityClass() 등이 내부적으로 호출하는 함수.
NTSYSAPI
NTSTATUS
NTAPI
NtSetInformationProcess(
IN HANDLE ProcessHandle,
IN PROCESS_INFORMATION_CLASS ProcessInformationClass,
IN PVOID ProcessInformationBuffer,
IN ULONG ProcessInformationLength);
ProcessHandle : 프로세스의 핸들.
ProcessInformationClass : 이 값에 따라서 얻을 수 있는 정보가 달라진다.
typedef enum _PROCESS_INFORMATION_CLASS {
ProcessBasicInformation,
........
} PROCESS_INFORMATION_CLASS, *PPROCESS_INFORMATION_CLASS;
이런 꼴이나, 설명하기에는 너무 길기 때문에 생략하겠다.
ProcessInformationBuffer : ProcessInformationClass로 지정한 값에 따라서 구조체가 달라진다.
ProcessInformationClass이 ProcessBasicInformation인 경우는 PROCESS_BASIC_INFORMATION 의 포인터형이다.
다 설명하자면 너무 길으므로 생략하겠다.
ProcessInformationLength : ProcessInformationClass로 지정한 값에 따라서 크기가 달라진다.
ProcessInformationClass이 ProcessBasicInformation인 경우는 PROCESS_BASIC_INFORMATION 구조체의 크기이다.
성공시, 0 이하의 값을 반환한다.
NtCreateProcess : 프로세스 객체를 생성한다. CreateProcess()가 내부적으로 호출하는 함수.
NTSYSAPI
NTSTATUS
NTAPI
NtCreateProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ParentProcess,
IN BOOLEAN InheritObjectTable,
IN HANDLE SectionHandle OPTIONAL,
IN HANDLE DebugPort OPTIONAL,
IN HANDLE ExceptionPort OPTIONAL);
DesiredAccess : 프로세스 핸들에 줄 권한.
ObjectAttributes : 프로세스 핸들에 줄 추가적 속성. (핸들 권한 상속여부 등을 결정할 수 있다.)
ParentProcess : 부모 프로세스의 핸들. 필자의 생각으로는 대부분 GetCurrentProcess() 또는 0xFFFFFFFF가 들어갈듯 하다.InheritObjectTable : ???
SectionHandle : 프로세스 생성시 열었던 이미지 파일의 섹션 핸들로 보여진다.
DebugPort : 디버거가 프로세스를 생성할 때에는 이 값이 NULL이 아니다.
ExceptionPort : 잘 모르겠다. 아마도 NtXxxPort()와 연관이 있을듯.
성공시, 0 이하의 값을 반환한다.
NtCreateProcessEx : 프로세스 객체를 생성한다. 아마도 NtCreateProcess()가 내부적으로 호출하는 함수.
NTSYSAPI
NTSTATUS
NTAPI
NtCreateProcessEx(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ParentProcess,
IN BOOLEAN InheritObjectTable,
IN HANDLE SectionHandle OPTIONAL,
IN HANDLE DebugPort OPTIONAL,
IN HANDLE ExceptionPort OPTIONAL,
IN HANDLE UnknownArgument);
ProcessHandle : 생성된 프로세스 객체의 프로세스 핸들.DesiredAccess : 프로세스 핸들에 줄 권한.
ObjectAttributes : 프로세스 핸들에 줄 추가적 속성. (핸들 권한 상속여부 등을 결정할 수 있다.)
ParentProcess : 부모 프로세스의 핸들. 필자의 생각으로는 대부분 GetCurrentProcess() 또는 0xFFFFFFFF가 들어갈듯 하다.
InheritObjectTable : ???
SectionHandle : 프로세스 생성시 열었던 이미지 파일의 섹션 핸들로 보여진다.
DebugPort : 디버거가 프로세스를 생성할 때에는 이 값이 NULL이 아니다.
ExceptionPort : 잘 모르겠다. 아마도 NtXxxPort()와 연관이 있을듯.
UnknownArgument : ???
성공시, 0 이하의 값을 반환한다.
주의점 : NtCreateProcess/NtCreateProcessEx는 완전한 프로세스를 생성시키는 것이 아니라,
프로세스 객체만을 생성시키는 일을 한다. 이 함수를 통해서 생성된 프로세스는 CSRSS.EXE에 등록되어야 하며,
이것은 아직 문서화되지 않았다.
[출처] 프로세스를 다루는 API에 관해서 알아보자.|작성자 wz1054
# by | 2008/04/01 13:42 | 02 윈도우 커널 | 트랙백 | 덧글(1)





☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
#define NT_SUCCESS(_Status) (_Status>=0)
......이 되어야 합니다.
STATUS_UNSUCCESSFUL이 0x00000001로 정의된 줄로 알고 했는데, 알고 보니
0xC0000001이더군요. (이런 안습이 ㅡ,.ㅡ)
다른 NtXxx함수들의 리턴값(반환값) 에 대한 설명도 수정되어야 합니다.
"성공시 0 이상의 값을 반환한다." 라고 말이죠.
죄송합니다. (__)