Windows_/Windows32_API

Windows :: 프로세스 정보 추출하기

sosal 2014. 7. 24. 01:02
반응형

/*

 * http://sosal.kr/

 * made by so_Sal

 */


이번장에서는 프로세스들의 정보를 순간적으로 가져오는 Snapshot과
정보를 추출, 그 정보를 얻어오는 법을 이 포스트에서 보려고 합니다.

그리고 프로세스 정보를 통해서 어떤일을 할 수 있을까??
프로세스 정보(프로세스 이름 , PID, PPID , ThreadID 등등..)을 통해
프로세스 핸들값을 도출해낼 수 있습니다.
차근차근 위의 일을 수행하는 함수를 보려고 합니다.

다음 헤더파일은 아래 함수들을 포함.
#include<tlhelp32.h>
프로세스들의 정보를 가져오기 위해서 스냅(사진찍기)를 해야한다.
단, 사진 찍는 순간의 프로세스 정보를 가져오기 때문에
100% 신뢰할 수 없는 정보이다. (스냅샷 찍는 함수)

HANDLE
CreateToolhelp32Snapshot(
                DWORD dwFlags, DWORD th32ProcessID);

DWORD dwFlags ::  =================
TH32CS_SNAPPROCESS 모든 프로세스를 스냅
TH32CS_INHERIT // 상속 가능한 핸들을 스냅
TH32CS_SNAPHEAPLIST //Heap 안에 있는 프로세스들을 스냅
TH32CS_SNAPMODULE // 프로세스 모듈정보를 스냅
TH32CS_SNAPTHREAD // 프로세스 스래드 스냅
TH32CS_SNAPALL // 시스템에 있는 모든 프로세스, 모듈, 스레드를 스냅

DWORD th32ProcessID :: 프로세스 ID 스냅

스냅하고자 하는 process의 ID를 넣는다.
0을 매개변수로 전달 시, 현재 실행중인 모든 프로세스를 스냅한다.


프로세스의 정보를 처음 추출할 때 사용하는 함수 2개이다.
BOOL Process32First(
                  HANDLE hSnapshot, LPPROCESSENTRY32W lppe)

hSnapshot :: CreateToolhelp32Snapshot() 함수로부터 리턴되는 핸들
lppe :: PROCESSENTRY32 구조체의 주소가 들어가면 된다.

다음(next) 프로세스의 정보를 추출할 때 사용하는 함수이다.

BOOL Process32Next(
                  HANDLE hSnapshot, LPPROCESSENTRY32W lppe)
(함수 인자는 Process32First와 동일하다.)

PROCESSENTRY32 구조체 :: 프로세스의 정보들이 담겨질 구조체이다.
Process32First, Process32Next 함수를 이용해서 정보를 담으면 된다.

Process32First에 의해 담겨진 PROCESSENTRY32 구조체의 정보는
사용자가 보는 일반적인 프로세스가 아니라 System Process이다.
(프로세스들을 관리)

// 위의 함수들 만으로 나름의 Tasklist 프로그램을 만들어 볼 수 있다.

하지만 프로세스를 직접적으로 다루기 위해서는 HANDLE이 필요하다.
핸들을 얻기 위해 사용하는 함수
HANDLE OpenProcess(
     DWORD dwDesiredAccess,
     BOOL bInheritHandle,
     DWORD dwProcessID
);

DWORD dwDesiredAccess :: 반환되는 핸들의 성격을 결정짓는다.
// PROCESS_ALL_ACCESS    //핸들에 모든 접근을 허용한다.
// PROCESS_QUERY_INFORMATION
// PROCESS_VM_READ

BOOL bInheritHandle :: //TRUE / FALSE로 상속 성격 지정

DWORD dwProcessID :: //원하는 Process의 ID (PID)를 입력한다.

OpenProcess를 이용하여 얻은 HANDLE로 프로세스를 종료시켜보자.
BOOL TerminateProcess(
           HANDLE hProcess, UINT uExitCode)

hProcess :: 종료하기를 원하는 Process Handle
uExitCode :: exit(EXIT_NUMBER) 에서 EXIT_NUMBER 역할을 하는 변수)

=============== 프로세스 정보 가져오기 프로그램 예제 ===============

#include<stdio.h>
#include<stdlib.h>
#include<tchar.h>
#include<windows.h>
#include<tlhelp32.h>

int _tmain(int argc, TCHAR *argv[]){
 HANDLE hProcessSnap =
  CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
  //현재 모든 프로세스들의 상태를 스냅합니다.

 if(hProcessSnap == INVALID_HANDLE_VALUE){
  _tprintf( _T("CreateToolhelp32Snapshot error \n"));
  exit(EXIT_FAILURE);
 }

 PROCESSENTRY32 pe32;
 pe32.dwSize = sizeof(PROCESSENTRY32);
 //프로세스 상태 정보를 담을 구조체를 선언합니다.

 if( !Process32First(hProcessSnap, &pe32)){
  _tprintf( _T("Process32First error ! \n"));
  CloseHandle(hProcessSnap);
  exit(EXIT_FAILURE);  
 }
 //첫번째 프로세스의 정보를 가져오는 경우와 다음 프로세스 정보를
 //가져올 경우에 다른 함수를 쓰게 됩니다. Process32First ,Process32Next
 
 _tprintf(_T("\t[Process name] \t[PID]\t[ThreadID]\t[PPID] \n"));

 do{
  _tprintf(_T("%25s %8d %8d %8d \n"),
   pe32.szExeFile, pe32.th32ProcessID, pe32.cntThreads, pe32.th32ParentProcessID);
 }while(Process32Next(hProcessSnap,&pe32));
 //PROCESSENTRY32 구조체에 위에서 출력한 정보들보다
 // 더 많은 정보들이 저장되어 있습니다. while()을 이용하여 모두 출력 후 종료

 return 0;
}




그럼, 프로세스 목록에서 원하는 프로그램의 정보를 입력받아서
(Process Name 또는 PID, PPID 등 상관없다.)
프로세스를 강제 종료시키는 ( TerminateProcess() )
프로그램을 만들어 보면 좋겠다.

간단하게 제가 만든 소스입니다.
예제 링크 :: LINK_