Windows/DeviceDriver 2021. 4. 20. 01:33

4. 프로세스 강제 종료 방지 연습


이론

  • 프로세스가 생성되면 고유의 Process ID를 갖는다.

    • PsLookupProcessByProcessId 함수를 통해 EPROCESS라는 구조체의 주소를 얻을 수 있다.

      <ntifs.h>

      NTSTATUS
        PsLookupProcessByProcessId(
          IN HANDLE ProcessId,
          OUT PEPROCESS *Process
          );
      • 첫 번째 인자로 PID를 받아서, 두 번째 인자를 역참조하여 EPROCESS의 주소(PEPROCESS)를 넘겨준다.
    • "EPROCESS 구조체의 주소 - 0x15"에 해당하는 주소의 값을 0x14로 변경하면, 다른 프로세스가 종료할 수 없도록 설정된다.


실습

빌드

  • 이전에 작성한 sample.c 파일의 내용을 다음과 같이 수정하여 빌드한다.

    #include <ntifs.h>
    
    NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegistryPath)
    {
      pDrvObj = pDrvObj;
      pRegistryPath = pRegistryPath;
    
      ULONG ProcessId = 0;
      if (ProcessId == 0)
        goto exit;
    
      PEPROCESS pEprocess = NULL;
      PsLookupProcessByProcessId((HANDLE)ProcessId, &pEprocess);
      if (pEprocess)
        *(unsigned char*)((unsigned char*)pEprocess - 0x15) = 0x14;
    
    exit:
      return STATUS_UNSUCCESSFUL;
    }
  • 빌드한 sample.sys 파일을 가상 머신의 C:\sample\ 경로로 이동시킨다.

  • 가상 머신에서 메모장과 작업 관리자를 연 뒤, 세부 정보 탭에서 메모장의 PID를 확인한다.


WinDbg

  • 나는 WinDbg를 켤 때마다 Kernel Debug (Ctrl + K)를 열어서 포트를 수정해줘야 하는데, 이유를 아직 잘 모르겠다.

  • 아무튼 가상 머신과 연결되면, 3장에서처럼 위 함수에 브레이크 포인트를 설정하고, Go를 눌러 다시 진행시킨다.

    bp sample!DriverEntry
  • 가상 머신의 CMD를 관리자 권한으로 열어서, 다음 명령어를 입력하여 드라이버를 로딩한다.

  • WinDbg에서 보면 브레이크 포인트에 걸려서 함수가 나온 것을 볼 수 있다.

    • Step into (F11) 버튼을 눌러 ULONG ProcessId = 0; 명령까지 진행한 뒤, Locals (Alt + 3)을 선택하면 로컬 변수 목록이 나온다.

  • LocalsProcessId 값에 위에서 확인한 notepad.exePID를 입력한다.

  • 그 후 Go를 눌러 가상 머신의 Break를 끝내면, 작업 관리자에서 작업 끝내기를 할 수 없다는 것을 확인할 수 있다.