Q&A

  • 후킹시 ProcessID알수있는 방법좀~~
안녕하세요...
먼저 제가 코딩한 부분을 올립니다...
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일째 고생중~~ㅠㅠ)
만약에 있다면 고수님들의 친절한 답변 기다리고 있겠습니다...
감사합니다...꾸벅~~^^
1  COMMENTS
  • Profile
    박영호 2007.05.24 02:13
    후킹할때 TerminateProcess 같은 것을 후킹하면 hProcess 를 가로챌 수 있습니다.

    죽일려고하는 프로세스의 핸들이 되겠지요..

    이 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);
    }