1. 프로세스 생성과 CloseHandle의 이유 ( 자식을 정말 죽이자~!! )
2. 다른 프로세스의 오브젝트 테이블을 복사 해 오기~!! ( a.txt에 B프로세스가 hello를 쓴다. )
3. 마우스 캡쳐한곳의 윈도우창을 강제종료 시키기( pid를 얻어오는것이 관건 )
more..
// 프로세스를 생성하는 간단한 방법들
int main()
{
//system( "calc.exe" ); // 자식 프로세스가 종료 될때 까지 Blocking 된다.
WinExec( "calc.exe", SW_SHOW ); // non - Blocking
cout << "프로그램 계속 실행" << endl;
}
int main()
{
PROCESS_INFORMATION pi;
STARTUPINFO si = { 0 };
si.cb = sizeof(si);
// 버퍼가 아니라 "calc.exe"(문자열은 const) 로 넘기면
// 유니코드 환경(내부적으로변경)에서 상수변경 에러 뜬다.
char name[256] = _T("C:\\windows\\system32\\calc.exe"); // 실행할 프로세스
BOOL b = CreateProcess(
0, // App Name - 절대경로
name, // Command Line Arg..
0,0, // PKO, TKO 보안
FALSE, // Object Table 상속여부
NORMAL_PRIORITY_CLASS, // 우선순위 | Flag
0, 0, // 환경변수, 현재 디렉토리
&si, // 시작정보구조체
&pi // 자식 프로세스의 ID와 핸들을 담을 변수
);
// 이때 자식프로세스의 참조계수는 2이다.
cout << "자식프로세스에 접근하기 위한 핸들" << (void*)pi.hProcess << endl;
cout << "자식프로세스의 스레드에 접근하기 위한 핸들" << (void*)pi.hThread << endl;
// 자식의 핸들을 닫는 것이 중요한다.
// 닫지 않으면 자식이 종료된 후에도 계속 메모리에 PKO, TKO가 남아 있다.
// 핸들이 필요 없다면 즉시 닫아라.
//if ( b )
//{
// // 자식의 핸들을 닫는것이 중요한다.
// CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
//}
// 이때 자식프로세스의 참조계수는 1이다.
//////////////////////////////////////////////////////////////////////////
int cmd;
while( 1 )
{
cin >> cmd;
if ( cmd == 2 )
{
// 자식 프로세스를 강제로 종료되게 한다. - 그리고 종료 코드를 채운다.
TerminateProcess( pi.hProcess, 100 );
// TermainateProcee는 비동기 함수 이다. 아직 자식이 죽었다고 장담못한다.
// 모든 프로세스는 죽을때 KO가 signal 된다.
// 특정 KO가 signal 될 때 까지 대기한다.
WaitForSingleObject( pi.hProcess, INFINITE );
// 이제 자식은 정말 죽었다.
cmd = 1; // 자식이 정말 죽었는지 확인한다.!!!
}
if ( cmd == 1 )
{
// 자식 프로세스의 종료 코드를 구한다.
DWORD code;
GetExitCodeProcess( pi.hProcess, &code );
if( code == STILL_ACTIVE ) // 0x103
cout << "아직 자식이 살아 있습니다." << endl;
else
{
cout << "자식 종료 : " << code << endl;
CloseHandle( pi.hProcess ); // 더이상 핸들이 필요 없으면..
}
}
}
return 0;
}
int main()
{
//system( "calc.exe" ); // 자식 프로세스가 종료 될때 까지 Blocking 된다.
WinExec( "calc.exe", SW_SHOW ); // non - Blocking
cout << "프로그램 계속 실행" << endl;
}
int main()
{
PROCESS_INFORMATION pi;
STARTUPINFO si = { 0 };
si.cb = sizeof(si);
// 버퍼가 아니라 "calc.exe"(문자열은 const) 로 넘기면
// 유니코드 환경(내부적으로변경)에서 상수변경 에러 뜬다.
char name[256] = _T("C:\\windows\\system32\\calc.exe"); // 실행할 프로세스
BOOL b = CreateProcess(
0, // App Name - 절대경로
name, // Command Line Arg..
0,0, // PKO, TKO 보안
FALSE, // Object Table 상속여부
NORMAL_PRIORITY_CLASS, // 우선순위 | Flag
0, 0, // 환경변수, 현재 디렉토리
&si, // 시작정보구조체
&pi // 자식 프로세스의 ID와 핸들을 담을 변수
);
// 이때 자식프로세스의 참조계수는 2이다.
cout << "자식프로세스에 접근하기 위한 핸들" << (void*)pi.hProcess << endl;
cout << "자식프로세스의 스레드에 접근하기 위한 핸들" << (void*)pi.hThread << endl;
// 자식의 핸들을 닫는 것이 중요한다.
// 닫지 않으면 자식이 종료된 후에도 계속 메모리에 PKO, TKO가 남아 있다.
// 핸들이 필요 없다면 즉시 닫아라.
//if ( b )
//{
// // 자식의 핸들을 닫는것이 중요한다.
// CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
//}
// 이때 자식프로세스의 참조계수는 1이다.
//////////////////////////////////////////////////////////////////////////
int cmd;
while( 1 )
{
cin >> cmd;
if ( cmd == 2 )
{
// 자식 프로세스를 강제로 종료되게 한다. - 그리고 종료 코드를 채운다.
TerminateProcess( pi.hProcess, 100 );
// TermainateProcee는 비동기 함수 이다. 아직 자식이 죽었다고 장담못한다.
// 모든 프로세스는 죽을때 KO가 signal 된다.
// 특정 KO가 signal 될 때 까지 대기한다.
WaitForSingleObject( pi.hProcess, INFINITE );
// 이제 자식은 정말 죽었다.
cmd = 1; // 자식이 정말 죽었는지 확인한다.!!!
}
if ( cmd == 1 )
{
// 자식 프로세스의 종료 코드를 구한다.
DWORD code;
GetExitCodeProcess( pi.hProcess, &code );
if( code == STILL_ACTIVE ) // 0x103
cout << "아직 자식이 살아 있습니다." << endl;
else
{
cout << "자식 종료 : " << code << endl;
CloseHandle( pi.hProcess ); // 더이상 핸들이 필요 없으면..
}
}
}
return 0;
}
2. 다른 프로세스의 오브젝트 테이블을 복사 해 오기~!! ( a.txt에 B프로세스가 hello를 쓴다. )
more..
int main()
{
HANDLE hFile = CreateFile(
"a.txt", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
0, // 보안속성
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
0
);
cout << "생성된 파일의 핸들 : " << (void*)hFile << endl;
// 다른 프로세스에 전달한다.
HWND hwnd = FindWindow( 0, "B" );
// 윈도우 핸들로 프로세스 ID를 구한다.
DWORD pid;
DWORD tid = GetWindowThreadProcessId( hwnd, &pid );
// 프로세스 ID를 가지고 프로세스 핸들을 얻는다.
HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, 0, pid );
// Object Table의 항목을 복사 해준다.
HANDLE hDest;
DuplicateHandle(
GetCurrentProcess(), hFile, // source
hProcess, &hDest, // Target
0, 0, DUPLICATE_SAME_ACCESS // option
);
cout << "복사된 항목의 핸들 : " << (void*)hDest << endl;
/////////////////////////////////////////////////////////
SendMessage( hwnd, WM_USER+100, 0, (LPARAM)hDest );
CloseHandle( hFile ); // 1. if (--(fFile.참조개수) == 0 ) Delete KO
// 2. Object Table에서 항목을 제거한다.
}
// 윈도우 캡션이 "B"인 윈도우App 하나 만들기
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch( msg )
{
case WM_USER+100:
{
char s1[256] = "hello";
char s2[256];
HANDLE hFile = (HANDLE)lParam;
DWORD len;
BOOL b = WriteFile( hFile, s1, 256, &len, 0 );
if( b )
MessageBox( 0, "성공", "", MB_OK );
else
{
// 에러의 원인을 알아낸다.
wsprintf( s2, "실패 : %d", GetLastError() );
MessageBox( 0, s2, "", MB_OK );
}
}
return 0;
// B을 먼저 실행하세요. 그리고 A을 실행 하세요.
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
{
HANDLE hFile = CreateFile(
"a.txt", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
0, // 보안속성
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
0
);
cout << "생성된 파일의 핸들 : " << (void*)hFile << endl;
// 다른 프로세스에 전달한다.
HWND hwnd = FindWindow( 0, "B" );
// 윈도우 핸들로 프로세스 ID를 구한다.
DWORD pid;
DWORD tid = GetWindowThreadProcessId( hwnd, &pid );
// 프로세스 ID를 가지고 프로세스 핸들을 얻는다.
HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, 0, pid );
// Object Table의 항목을 복사 해준다.
HANDLE hDest;
DuplicateHandle(
GetCurrentProcess(), hFile, // source
hProcess, &hDest, // Target
0, 0, DUPLICATE_SAME_ACCESS // option
);
cout << "복사된 항목의 핸들 : " << (void*)hDest << endl;
/////////////////////////////////////////////////////////
SendMessage( hwnd, WM_USER+100, 0, (LPARAM)hDest );
CloseHandle( hFile ); // 1. if (--(fFile.참조개수) == 0 ) Delete KO
// 2. Object Table에서 항목을 제거한다.
}
// 윈도우 캡션이 "B"인 윈도우App 하나 만들기
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch( msg )
{
case WM_USER+100:
{
char s1[256] = "hello";
char s2[256];
HANDLE hFile = (HANDLE)lParam;
DWORD len;
BOOL b = WriteFile( hFile, s1, 256, &len, 0 );
if( b )
MessageBox( 0, "성공", "", MB_OK );
else
{
// 에러의 원인을 알아낸다.
wsprintf( s2, "실패 : %d", GetLastError() );
MessageBox( 0, s2, "", MB_OK );
}
}
return 0;
// B을 먼저 실행하세요. 그리고 A을 실행 하세요.
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
3. 마우스 캡쳐한곳의 윈도우창을 강제종료 시키기( pid를 얻어오는것이 관건 )
more..
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch( msg )
{
case WM_LBUTTONDOWN:
SetCapture( hwnd );
return 0;
case WM_LBUTTONUP:
if( GetCapture() == hwnd )
{
ReleaseCapture();
POINT pt;
GetCursorPos( &pt ); // 커서의 좌표를 스크린 좌표로 구한다.
HWND h = WindowFromPoint( pt );
// 해당 윈도우를 만든 프로세스ID, 스레드 ID를 구한다.
DWORD pid;
DWORD tid = GetWindowThreadProcessId( h, &pid );
// 프로세스 ID를 가지고 해당 프로세스에 접근하기 위한 핸들을 얻는다.
// (Table에 항목을 만드는 것이다. ************)
// HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, 0, pid );
// ALL은 너무 많은 권한
// 최소 요구의 원칙 - 필요한 권한만 요구하자.****꼭 필요한것만 요구하자.
HANDLE hProcess = OpenProcess(
PROCESS_TERMINATE | SYNCHRONIZE, // 죽이고 | wait 할수 있는 권한
0,
pid
);
// 이제 핸들을 사용한다.
TerminateProcess( hProcess, INFINITE );
DWORD ret = WaitForSingleObject( hProcess, 5000 );
if( ret == WAIT_OBJECT_0 ) // 숫자 0
{
// 강제종료 성공 - KO가 signal 되었다.
}
else if( ret == WAIT_TIMEOUT )
{
MessageBox( 0, "프로세스를 죽일 수 없습니다.", "", MB_OK );
}
else if( ret == WAIT_FAILED )
{
// 핸들이 잘못된 경우
}
CloseHandle( hProcess );
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}
{
switch( msg )
{
case WM_LBUTTONDOWN:
SetCapture( hwnd );
return 0;
case WM_LBUTTONUP:
if( GetCapture() == hwnd )
{
ReleaseCapture();
POINT pt;
GetCursorPos( &pt ); // 커서의 좌표를 스크린 좌표로 구한다.
HWND h = WindowFromPoint( pt );
// 해당 윈도우를 만든 프로세스ID, 스레드 ID를 구한다.
DWORD pid;
DWORD tid = GetWindowThreadProcessId( h, &pid );
// 프로세스 ID를 가지고 해당 프로세스에 접근하기 위한 핸들을 얻는다.
// (Table에 항목을 만드는 것이다. ************)
// HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, 0, pid );
// ALL은 너무 많은 권한
// 최소 요구의 원칙 - 필요한 권한만 요구하자.****꼭 필요한것만 요구하자.
HANDLE hProcess = OpenProcess(
PROCESS_TERMINATE | SYNCHRONIZE, // 죽이고 | wait 할수 있는 권한
0,
pid
);
// 이제 핸들을 사용한다.
TerminateProcess( hProcess, INFINITE );
DWORD ret = WaitForSingleObject( hProcess, 5000 );
if( ret == WAIT_OBJECT_0 ) // 숫자 0
{
// 강제종료 성공 - KO가 signal 되었다.
}
else if( ret == WAIT_TIMEOUT )
{
MessageBox( 0, "프로세스를 죽일 수 없습니다.", "", MB_OK );
}
else if( ret == WAIT_FAILED )
{
// 핸들이 잘못된 경우
}
CloseHandle( hProcess );
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hwnd, msg, wParam, lParam);
}