안녕하세요...
먼저 제가 코딩한 부분을 올립니다...
function MyProcessHook(Code : Integer; wParam : WPARAM; lParam : LPARAM) : LongInt; stdcall;
var
Buff : array [0..255] of Char;
hProcess: THandle;
g,f : string;
TermSucc: BOOL;
Process32 : TProcessEntry32;
SHandle : THandle; // the handle of the Windows object
Next : BOOL;
ProcId: DWORD;
begin
//요기부터 시스템후킹을 이용하여 MSN메신저가 시작될려고 할때를 체크...
if HProcessHook = 0 then
ReadData;
if (code = HSHELL_WINDOWCREATED) then
begin
GetClassName(wParam, Buff, SizeOf(Buff)); <= 후킹에서 클래스명을 가지고 오기...
if Buff = 'MSBLWindowClass' then <= 클래스명이 MSN메신저에 해당하면
begin
//여기서부터는 작업관리자에 있는 프로세서를 검색해서 실행파일명이 msnmsgr.exe이면
그 프로세서를 강제종료시키기
process32.dwSize := SizeOf(TProcessEntry32);
SHandle := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if Process32First(SHandle, process32) then
begin// 실행화일명과 process object 저장
repeat
Next := Process32Next(SHandle, process32);
if (Next) and (Process32.szExeFile = 'DWGenie.exe') then
begin
ProcId := DWORD(process32. th32ProcessID);
hProcess := OpenProcess(PROCESS_ALL_ACCESS, TRUE, ProcId);
if hProcess = NULL then
begin
g :='OpenProcess error !';
MessageBox(0,PChar(g),'Hook Message',0);
end;
TermSucc := TerminateProcess(hProcess, 0);
if TermSucc = FALSE then
begin
f :='TerminateProcess error !';
MessageBox(0,PChar(f),'Hook Message',0);
end;
end;
until not Next;
end;
CloseHandle(SHandle); // closes an open object handle
end;
//강제종료끝...
end;
Result := CallNextHookEx(HProcessHook, Code, wParam, lParam);
end;
여기에서 질문이 있는데요...
후킹을 이용해서 해당프로세서의 ProcessID를 알아낼수있는 방법이 없을까요...
만약에 ProcessID만 알아낼수가 있다면 이것보다 더 간단하게 코딩을 할수있을것같은데(OpenProcess와 TerminateProcess을 이용해서)...
도저히 후킹할때 ProcessID를 알아내는 방법을 모르겠습니다...(3일째 고생중~~ㅠㅠ)
만약에 있다면 고수님들의 친절한 답변 기다리고 있겠습니다...
감사합니다...꾸벅~~^^
죽일려고하는 프로세스의 핸들이 되겠지요..
이 hProcess(타켓 프로그램의 핸들) 만 갖고 PID 를 알아내는데는 GetProcessId 라는 커널단의
함수를 쓰면될것 같지만 GetProcessId 함수는 같은 프로세스내에서만 핸들로 프로세스 아이디를
얻어내는 함수이므로 TerminateProcess 가 실행되는 죽이는자(Killer) 의 공간에서 타켓 프로세스의
PID 를 얻어낼 수 없습니다. 이 문제를 해결하려면 hProcess(타켓 프로그램의 핸들) 을 복사해야
합니다. DuplicateHandle 함수로 타켓 프로그램의 핸들을 복사하는데 이때 속성을
PROCESS_QUERY_INFORMATION 으로 주고 복사를 합니다. 코드는 다음과 같습니다.
HANDLE hDup;
if(!DuplicateHandle(GetCurrentProcess(),
hProcess,
GetCurrentProcess(),
&hDup,
PROCESS_QUERY_INFORMATION,
FALSE,
0))
{
return(0xffffffff);
}
이렇게 핸들을 복사하면 그 다음부터는 매우 쉽습니다. NtQueryInformationProcess 함수가
핸들을 갖고 정보를 뽑아오기 때문이죠.. 다음의 코드를 보십시오. 핸들을 통해서
PROCESS_BASIC_INFORMATION 값을 구조체로 받아옵니다.
구조체를 보시면 아시겠지만 pbi.UniqueProcessId 이렇게 구하면 타켓 핸들의 프로세스 아이디를
얻어낼 수 있구요.. pbi.InheritedFromUniqueProcessId 이렇게하면 타켓핸들의 프로세스 아이디뿐만
아니라 그 부모의 프로세스 아이디까지 얻어낼 수 있습니다.. 도움 되셨길..
예제는 powerhacker 사이트에 올려놨습니다. 제가 삽질했던 부분을 물어보시는거 같아서
삽질 덜 하시라고 올려드립니다.. ^^
DWORD WINAPI PowerHacker_GetProcessId(HANDLE hProcess)
{
NTSTATUS status;
PROCESS_BASIC_INFORMATION pbi;
HANDLE hDup;
if(!DuplicateHandle(GetCurrentProcess(),
hProcess,
GetCurrentProcess(),
&hDup,
PROCESS_QUERY_INFORMATION,
FALSE,
0))
{
return(0xffffffff);
}
CREATE_DYNFUNC_5(NtQueryInformationProcess,
NtQueryInformationProcess,
ntdll,
NTSTATUS,
__stdcall,
HANDLE,
PROCESSINFOCLASS,
PVOID,
ULONG,
PULONG
);
status = NtQueryInformationProcess(hDup, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
CloseHandle(hDup);
if(status >= 0) return pbi.UniqueProcessId;
else return(0xffffffff);
}