본문 바로가기

Research/Windows

프로세스별 핸들 목록 리스팅






Process Explorer 에서 프로세스를 선택하면 출력되는 핸들 리스트 구현하려 한다.



NtQuerySystemInformation 함수에 enumerate 된 SystemExtendedHandleInformation 인자를 패스

define 값은 64


시스템 동작 환경에 따라 NtQuerySystemInformation 에서 요구하는 버퍼 크기가 동적으로 변경된다


크게 두 개의 구조체를 사용하며,

- SYSTEM_EXTENDED_HANDLE_INFORMATION / PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX -


Process Explorer 에서 나오는 인자들의 종류는 크게 Key, Directory, File, WindowStation, Section, Mutant 등이 있다.

일반적인 Process Explorer 에서 기본적으로 출력해주는 컬럼의 매칭

Type - Object Type Index

Name - ??

Handle - Handle Value

Access - Granted Access



핸들은 Enumerate 되었기 때문인지 0x4, 0x8, 0xC, 0x10, 0x14 .. 이런 식으로 순차적으로 번호가 붙으며

데 그 중 일부가 제대로 나타나지 않는다.

이유는 모르겠으나 NtQuerySystemInformation 에서 넘겨준 인자의 차이인 것 같으며

Extended 옵션이 들어있는 인자를 주어서인지, 아래와 같이 작성한 코드에서는 모든 핸들값을 볼 수 있었다.



#define SystemExtendedHandleInformation 64

#define STATUS_INFO_LENGTH_MISMATCH      ((NTSTATUS)0xC0000004L)



typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX

{

PVOID Reserved;

PVOID Object; // move

HANDLE UniqueProcessId;

HANDLE HandleValue;

ACCESS_MASK GrantedAccess;

USHORT CreatorBackTraceIndex;

USHORT ObjectTypeIndex;

ULONG HandleAttributes;



} SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX;


typedef struct _SYSTEM_EXTENDED_HANDLE_INFORMATION

{

ULONG NumberOfHandles;

SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handles[1];

} SYSTEM_EXTENDED_HANDLE_INFORMATION, *PSYSTEM_EXTENDED_HANDLE_INFORMATION;




typedef NTSTATUS (WINAPI* fp_NtQuerySystemInformation)

(

SYSTEM_INFORMATION_CLASS SystemInformationClass,

PVOID SystemInformation,

ULONG SystemInformationLength,

PULONG ReturnLength

);



int main()

{

NTSTATUS status;

CHAR* buffer ;//

ULONG bufferSize = 0x10000;

PSYSTEM_EXTENDED_HANDLE_INFORMATION handles;

PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX pEntry;

ULONG i;

HANDLE savedHandle = 0;

fp_NtQuerySystemInformation _NtQuerySystemInformation;

HINSTANCE hInst = LoadLibraryA("ntdll.dll");

if(NULL == hInst) return -1;


_NtQuerySystemInformation = (fp_NtQuerySystemInformation)GetProcAddress(hInst, "NtQuerySystemInformation");


buffer = (char*) calloc( bufferSize , sizeof(char));


while((status = _NtQuerySystemInformation(

(SYSTEM_INFORMATION_CLASS)SystemExtendedHandleInformation,

buffer,

bufferSize,

NULL)) == STATUS_INFO_LENGTH_MISMATCH)

{

free(buffer);

bufferSize*=2;

buffer = (char*) calloc(bufferSize, sizeof(char));


}

if (!NT_SUCCESS(status))

{

free(buffer);

return -1;

}


handles = (PSYSTEM_EXTENDED_HANDLE_INFORMATION)buffer;



for(i=0; i<handles->NumberOfHandles; i++ )

{

pEntry = &(handles->Handles[i]);


if( (HANDLE)1848 == pEntry->UniqueProcessId)

printf("PID : %d, handle 0x%x, ACCESS : 0x%08x, addrObject : 0x%08x, Index : %x \n", 

pEntry->UniqueProcessId, 

pEntry->HandleValue,

pEntry->GrantedAccess, 

pEntry->Object, 

pEntry->ObjectTypeIndex);

}


return 0;

}



MagicDisc 프로세스에 나타나는 핸들 중 \Device\mcdbus0 의 값을 운영체제별로 뽑아 보았는데,

Process Explorer 에서는 이 핸들 타입이 모두 File 로 출력되고 있다.

실제로 테스트해 보니 xp / 7 에서는 TYPE_KERNEL_OBJECT_FILE (28) 로, 

Server 2008 에서는 TYPE_KERNEL_OBJECT_DEVICE (25) 로 정의가 되어 있다.


이런 식으로 프로그램 개발하는 시점에 핸들을 만들 때

해당 타입에 해당하는 값을 따로 줄 수 있는 것 같다.




 참고 (http://greenfishblog.tistory.com/20)


  1. typedef INT TYPE_KERNEL_OBJECT;  
  2. #define     TYPE_KERNEL_OBJECT_UNKNOWN                  0  
  3. #define     TYPE_KERNEL_OBJECT_TYPE                     1  
  4. #define     TYPE_KERNEL_OBJECT_DIRECTORY                2  
  5. #define     TYPE_KERNEL_OBJECT_SYMBOLICLINK             3  
  6. #define     TYPE_KERNEL_OBJECT_TOKEN                    4  
  7. #define     TYPE_KERNEL_OBJECT_PROCESS                  5  
  8. #define     TYPE_KERNEL_OBJECT_THREAD                   6  
  9. #define     TYPE_KERNEL_OBJECT_JOB                      7  
  10. #define     TYPE_KERNEL_OBJECT_DEBUGOBJECT              8  
  11. #define     TYPE_KERNEL_OBJECT_EVENT                    9  
  12. #define     TYPE_KERNEL_OBJECT_EVENTPAIR                10  
  13. #define     TYPE_KERNEL_OBJECT_MUTANT                   11  
  14. #define     TYPE_KERNEL_OBJECT_CALLBACK                 12  
  15. #define     TYPE_KERNEL_OBJECT_SEMAPHORE                13  
  16. #define     TYPE_KERNEL_OBJECT_TIMER                    14  
  17. #define     TYPE_KERNEL_OBJECT_PROFILE                  15  
  18. #define     TYPE_KERNEL_OBJECT_KEYEDEVENT               16  
  19. #define     TYPE_KERNEL_OBJECT_WINDOWSTATION            17  
  20. #define     TYPE_KERNEL_OBJECT_DESKTOP                  18  
  21. #define     TYPE_KERNEL_OBJECT_SECTION                  19  
  22. #define     TYPE_KERNEL_OBJECT_KEY                      20  
  23. #define     TYPE_KERNEL_OBJECT_PORT                     21  
  24. #define     TYPE_KERNEL_OBJECT_WAITABLEPORT             22  
  25. #define     TYPE_KERNEL_OBJECT_ADAPTER                  23  
  26. #define     TYPE_KERNEL_OBJECT_CONTROLLER               24  
  27. #define     TYPE_KERNEL_OBJECT_DEVICE                   25  
  28. #define     TYPE_KERNEL_OBJECT_DRIVER                   26  
  29. #define     TYPE_KERNEL_OBJECT_IOCOMPLETION             27  
  30. #define     TYPE_KERNEL_OBJECT_FILE                     28  
  31. #define     TYPE_KERNEL_OBJECT_WMIGUID                  29  
  32. #define     TYPE_KERNEL_OBJECT_FILTERCONNECTIONPORT     30  
  33. #define     TYPE_KERNEL_OBJECT_FILTERCOMMUNICATIONPORT  31  
  34. #define     TYPE_KERNEL_OBJECT_OTHER                    32