반응형

Win32 API에서는 이러한 정보를 구하는 방법을 제공하고 있지 않습니다. Windows Native API를 사용해야
해당 정보를 구할 수 있습니다. (ntdll.dll::ZwQueryObject(...))

백문이 불여일견.
해당 정보를 리턴하는 다음 코드를 공유합니다.
(코드가 좀 길어 보여서... "view plain"으로 보시면 수월할 겁니다.)

자료구조를 포함하는 헤더 파일입니다.
  1. #include <winternl.h>   
  2.   
  3. // ntdll::ZwQueryObject(...)의 prototype   
  4. typedef NTSTATUS (__stdcall *LPFN_ZwQueryObject)(IN HANDLE Handle, IN DWORD ObjectInformationClass, OUT PVOID ObjectInformation, IN ULONG ObjectInformationLength, OUT PULONG ReturnLength);   
  5.   
  6. // ntdll::ZwQueryObject(...)에서 쓰임   
  7. typedef struct tagPUBLIC_OBJECT_TYPE_INFORMATION   
  8. {   
  9.     UNICODE_STRING  TypeName;   
  10.     ULONG           Reserved[MAX_PATH];   
  11. } PUBLIC_OBJECT_TYPE_INFORMATION, *PPUBLIC_OBJECT_TYPE_INFORMATION;   
  12.   
  13. // ZwQueryObject를 통한 Kernel Object의 Type   
  14. typedef INT TYPE_KERNEL_OBJECT;   
  15. #define     TYPE_KERNEL_OBJECT_UNKNOWN                  0   
  16. #define     TYPE_KERNEL_OBJECT_TYPE                     1   
  17. #define     TYPE_KERNEL_OBJECT_DIRECTORY                2   
  18. #define     TYPE_KERNEL_OBJECT_SYMBOLICLINK             3   
  19. #define     TYPE_KERNEL_OBJECT_TOKEN                    4   
  20. #define     TYPE_KERNEL_OBJECT_PROCESS                  5   
  21. #define     TYPE_KERNEL_OBJECT_THREAD                   6   
  22. #define     TYPE_KERNEL_OBJECT_JOB                      7   
  23. #define     TYPE_KERNEL_OBJECT_DEBUGOBJECT              8   
  24. #define     TYPE_KERNEL_OBJECT_EVENT                    9   
  25. #define     TYPE_KERNEL_OBJECT_EVENTPAIR                10   
  26. #define     TYPE_KERNEL_OBJECT_MUTANT                   11   
  27. #define     TYPE_KERNEL_OBJECT_CALLBACK                 12   
  28. #define     TYPE_KERNEL_OBJECT_SEMAPHORE                13   
  29. #define     TYPE_KERNEL_OBJECT_TIMER                    14   
  30. #define     TYPE_KERNEL_OBJECT_PROFILE                  15   
  31. #define     TYPE_KERNEL_OBJECT_KEYEDEVENT               16   
  32. #define     TYPE_KERNEL_OBJECT_WINDOWSTATION            17   
  33. #define     TYPE_KERNEL_OBJECT_DESKTOP                  18   
  34. #define     TYPE_KERNEL_OBJECT_SECTION                  19   
  35. #define     TYPE_KERNEL_OBJECT_KEY                      20   
  36. #define     TYPE_KERNEL_OBJECT_PORT                     21   
  37. #define     TYPE_KERNEL_OBJECT_WAITABLEPORT             22   
  38. #define     TYPE_KERNEL_OBJECT_ADAPTER                  23   
  39. #define     TYPE_KERNEL_OBJECT_CONTROLLER               24   
  40. #define     TYPE_KERNEL_OBJECT_DEVICE                   25   
  41. #define     TYPE_KERNEL_OBJECT_DRIVER                   26   
  42. #define     TYPE_KERNEL_OBJECT_IOCOMPLETION             27   
  43. #define     TYPE_KERNEL_OBJECT_FILE                     28   
  44. #define     TYPE_KERNEL_OBJECT_WMIGUID                  29   
  45. #define     TYPE_KERNEL_OBJECT_FILTERCONNECTIONPORT     30   
  46. #define     TYPE_KERNEL_OBJECT_FILTERCOMMUNICATIONPORT  31   
  47. #define     TYPE_KERNEL_OBJECT_OTHER                    32  

Kernel Object Handle의 Type을 구하는 함수입니다.
  1. NTSTATUS GetHandleType(IN HANDLE hHandle, OUT TYPE_KERNEL_OBJECT *pnObject)   
  2. {   
  3.     NTSTATUS                        nRtnValue   = 0;   
  4.     HMODULE                         hModule     = NULL;   
  5.     LPFN_ZwQueryObject              pfn         = NULL;   
  6.     ULONG                           nSize       = 0;   
  7.     LPBYTE                          pBuf        = NULL;   
  8.     PPUBLIC_OBJECT_TYPE_INFORMATION pstInfo     = NULL;   
  9.     PUBLIC_OBJECT_TYPE_INFORMATION  stInfo      = {0,};   
  10.   
  11.     if (NULL == pnObject)   
  12.     {   
  13.         nRtnValue = STATUS_INVALID_PARAMETER;   
  14.         goto FINAL;   
  15.     }   
  16.   
  17.     (*pnObject) = TYPE_KERNEL_OBJECT_UNKNOWN;   
  18.   
  19.     // 만들어 놓은 아래 함수가 없다면,   
  20.     // hModule = ::LoadLibraryEx(TEXT("ntdll.dll"), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);   
  21.     // 를 사용한다.   
  22.     hModule = LoadLibraryFromSystem(TEXT("ntdll.dll"));   
  23.     if (NULL == hModule)   
  24.     {   
  25.         nRtnValue = STATUS_OBJECT_PATH_NOT_FOUND;   
  26.         goto FINAL;   
  27.     }   
  28.   
  29.     pfn = (LPFN_ZwQueryObject)::GetProcAddress(hModule, "ZwQueryObject");   
  30.     if (NULL == pfn)   
  31.     {   
  32.         nRtnValue = STATUS_PROCEDURE_NOT_FOUND;   
  33.         goto FINAL;   
  34.     }   
  35.   
  36.     pstInfo = &stInfo;   
  37.     nRtnValue = (*pfn)(hHandle, 2, pstInfo, sizeof(stInfo), &nSize);    // 2 : ObjectTypeInformation   
  38.     if (STATUS_INFO_LENGTH_MISMATCH == nRtnValue)   
  39.     {   
  40.         pBuf = new BYTE[nSize];   
  41.         if (NULL == pBuf)   
  42.         {   
  43.             nRtnValue = STATUS_NO_MEMORY;   
  44.             goto FINAL;   
  45.         }   
  46.   
  47.         ZeroMemory(pBuf, sizeof(BYTE)*nSize);   
  48.         pstInfo = (PPUBLIC_OBJECT_TYPE_INFORMATION)pBuf;   
  49.   
  50.         nRtnValue = (*pfn)(hHandle, 2, pstInfo, nSize, &nSize);         // 2 : ObjectTypeInformation   
  51.     }   
  52.   
  53.     if (STATUS_SUCCESS != nRtnValue)   
  54.     {   
  55.         goto FINAL;   
  56.     }   
  57.   
  58.     if (NULL == pstInfo->TypeName.Buffer)   
  59.     {   
  60.         nRtnValue = STATUS_INVALID_PARAMETER;   
  61.         goto FINAL;   
  62.     }   
  63.   
  64.     // 빈도 많음   
  65.     if (0 == _tcsicmp(TEXT("Key"), pstInfo->TypeName.Buffer))   
  66.         (*pnObject) = TYPE_KERNEL_OBJECT_KEY;   
  67.     else if (0 == _tcsicmp(TEXT("File"), pstInfo->TypeName.Buffer))   
  68.         (*pnObject) = TYPE_KERNEL_OBJECT_FILE;   
  69.     else if (0 == _tcsicmp(TEXT("Thread"), pstInfo->TypeName.Buffer))   
  70.         (*pnObject) = TYPE_KERNEL_OBJECT_THREAD;   
  71.     else if (0 == _tcsicmp(TEXT("Directory"), pstInfo->TypeName.Buffer))   
  72.         (*pnObject) = TYPE_KERNEL_OBJECT_DIRECTORY;   
  73.     else if (0 == _tcsicmp(TEXT("Section"), pstInfo->TypeName.Buffer))   
  74.         (*pnObject) = TYPE_KERNEL_OBJECT_SECTION;   
  75.     else if (0 == _tcsicmp(TEXT("Event"), pstInfo->TypeName.Buffer))   
  76.         (*pnObject) = TYPE_KERNEL_OBJECT_EVENT;   
  77.     else if (0 == _tcsicmp(TEXT("Mutant"), pstInfo->TypeName.Buffer))   
  78.         (*pnObject) = TYPE_KERNEL_OBJECT_MUTANT;   
  79.     else if (0 == _tcsicmp(TEXT("Port"), pstInfo->TypeName.Buffer))   
  80.         (*pnObject) = TYPE_KERNEL_OBJECT_PORT;   
  81.     // 빈도 적음   
  82.     else if (0 == _tcsicmp(TEXT("KeyedEvent"), pstInfo->TypeName.Buffer))   
  83.         (*pnObject) = TYPE_KERNEL_OBJECT_KEYEDEVENT;   
  84.     else if (0 == _tcsicmp(TEXT("Token"), pstInfo->TypeName.Buffer))   
  85.         (*pnObject) = TYPE_KERNEL_OBJECT_TOKEN;   
  86.     else if (0 == _tcsicmp(TEXT("WindowStation"), pstInfo->TypeName.Buffer))   
  87.         (*pnObject) = TYPE_KERNEL_OBJECT_WINDOWSTATION;   
  88.     else if (0 == _tcsicmp(TEXT("Type"), pstInfo->TypeName.Buffer))   
  89.         (*pnObject) = TYPE_KERNEL_OBJECT_TYPE;   
  90.     else if (0 == _tcsicmp(TEXT("SymbolicLink"), pstInfo->TypeName.Buffer))   
  91.         (*pnObject) = TYPE_KERNEL_OBJECT_SYMBOLICLINK;   
  92.     else if (0 == _tcsicmp(TEXT("Process"), pstInfo->TypeName.Buffer))   
  93.         (*pnObject) = TYPE_KERNEL_OBJECT_PROCESS;   
  94.     else if (0 == _tcsicmp(TEXT("Job"), pstInfo->TypeName.Buffer))   
  95.         (*pnObject) = TYPE_KERNEL_OBJECT_JOB;   
  96.     else if (0 == _tcsicmp(TEXT("DebugObject"), pstInfo->TypeName.Buffer))   
  97.         (*pnObject) = TYPE_KERNEL_OBJECT_DEBUGOBJECT;   
  98.     else if (0 == _tcsicmp(TEXT("EventPair"), pstInfo->TypeName.Buffer))   
  99.         (*pnObject) = TYPE_KERNEL_OBJECT_EVENTPAIR;   
  100.     else if (0 == _tcsicmp(TEXT("Callback"), pstInfo->TypeName.Buffer))   
  101.         (*pnObject) = TYPE_KERNEL_OBJECT_CALLBACK;   
  102.     else if (0 == _tcsicmp(TEXT("Semaphore"), pstInfo->TypeName.Buffer))   
  103.         (*pnObject) = TYPE_KERNEL_OBJECT_SEMAPHORE;   
  104.     else if (0 == _tcsicmp(TEXT("Timer"), pstInfo->TypeName.Buffer))   
  105.         (*pnObject) = TYPE_KERNEL_OBJECT_TIMER;   
  106.     else if (0 == _tcsicmp(TEXT("Profile"), pstInfo->TypeName.Buffer))   
  107.         (*pnObject) = TYPE_KERNEL_OBJECT_PROFILE;   
  108.     else if (0 == _tcsicmp(TEXT("Desktop"), pstInfo->TypeName.Buffer))   
  109.         (*pnObject) = TYPE_KERNEL_OBJECT_DESKTOP;   
  110.     else if (0 == _tcsicmp(TEXT("WaitablePort"), pstInfo->TypeName.Buffer))   
  111.         (*pnObject) = TYPE_KERNEL_OBJECT_WAITABLEPORT;   
  112.     else if (0 == _tcsicmp(TEXT("Adapter"), pstInfo->TypeName.Buffer))   
  113.         (*pnObject) = TYPE_KERNEL_OBJECT_ADAPTER;   
  114.     else if (0 == _tcsicmp(TEXT("Controller"), pstInfo->TypeName.Buffer))   
  115.         (*pnObject) = TYPE_KERNEL_OBJECT_CONTROLLER;   
  116.     else if (0 == _tcsicmp(TEXT("Device"), pstInfo->TypeName.Buffer))   
  117.         (*pnObject) = TYPE_KERNEL_OBJECT_DEVICE;   
  118.     else if (0 == _tcsicmp(TEXT("Driver"), pstInfo->TypeName.Buffer))   
  119.         (*pnObject) = TYPE_KERNEL_OBJECT_DRIVER;   
  120.     else if (0 == _tcsicmp(TEXT("IoCompletion"), pstInfo->TypeName.Buffer))   
  121.         (*pnObject) = TYPE_KERNEL_OBJECT_IOCOMPLETION;   
  122.     else if (0 == _tcsicmp(TEXT("WmiGuid"), pstInfo->TypeName.Buffer))   
  123.         (*pnObject) = TYPE_KERNEL_OBJECT_WMIGUID;   
  124.     else if (0 == _tcsicmp(TEXT("FilterConnectionPort"), pstInfo->TypeName.Buffer))   
  125.         (*pnObject) = TYPE_KERNEL_OBJECT_FILTERCONNECTIONPORT;   
  126.     else if (0 == _tcsicmp(TEXT("FilterCommunicationPort"), pstInfo->TypeName.Buffer))   
  127.         (*pnObject) = TYPE_KERNEL_OBJECT_FILTERCOMMUNICATIONPORT;   
  128.     else  
  129.         (*pnObject) = TYPE_KERNEL_OBJECT_OTHER;   
  130.   
  131. FINAL:   
  132.   
  133.     if (NULL != pBuf)   
  134.     {   
  135.         delete [] pBuf;   
  136.         pBuf = NULL;   
  137.     }   
  138.   
  139.     if (NULL != hModule)   
  140.     {   
  141.         ::FreeLibrary(hModule);   
  142.         hModule = NULL;   
  143.     }   
  144.   
  145.     return nRtnValue;   
  146. }  


Kernel Object Handle의 Name을 구하는 함수입니다.
  1. NTSTATUS GetHandleObjectName(IN HANDLE hHandle, OUT LPTSTR lpszName, IN DWORD dwCchName)   
  2. {   
  3.     NTSTATUS                        nRtnValue   = 0;   
  4.     HMODULE                         hModule     = NULL;   
  5.     LPFN_ZwQueryObject              pfn         = NULL;   
  6.     ULONG                           nSize       = 0;   
  7.     LPBYTE                          pBuf        = NULL;   
  8.     PPUBLIC_OBJECT_TYPE_INFORMATION pstInfo     = NULL;   
  9.     PUBLIC_OBJECT_TYPE_INFORMATION  stInfo      = {0,};   
  10.   
  11.     if (NULL == lpszName)   
  12.     {   
  13.         nRtnValue = STATUS_INVALID_PARAMETER;   
  14.         goto FINAL;   
  15.     }   
  16.   
  17.     // 만들어 놓은 아래 함수가 없다면,   
  18.     // hModule = ::LoadLibraryEx(TEXT("ntdll.dll"), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);   
  19.     // 를 사용한다.   
  20.     hModule = LoadLibraryFromSystem(TEXT("ntdll.dll"));   
  21.     if (NULL == hModule)   
  22.     {   
  23.         nRtnValue = STATUS_OBJECT_PATH_NOT_FOUND;   
  24.         goto FINAL;   
  25.     }   
  26.   
  27.     pfn = (LPFN_ZwQueryObject)::GetProcAddress(hModule, "ZwQueryObject");   
  28.     if (NULL == pfn)   
  29.     {   
  30.         nRtnValue = STATUS_PROCEDURE_NOT_FOUND;   
  31.         goto FINAL;   
  32.     }   
  33.   
  34.     pstInfo = &stInfo;   
  35.     nRtnValue = (*pfn)(hHandle, 1, pstInfo, sizeof(stInfo), &nSize);    // 1 : ObjectNameInformation   
  36.     if (STATUS_INFO_LENGTH_MISMATCH == nRtnValue)   
  37.     {   
  38.         pBuf = new BYTE[nSize];   
  39.         if (NULL == pBuf)   
  40.         {   
  41.             nRtnValue = STATUS_NO_MEMORY;   
  42.             goto FINAL;   
  43.         }   
  44.   
  45.         ZeroMemory(pBuf, sizeof(BYTE)*nSize);   
  46.         pstInfo = (PPUBLIC_OBJECT_TYPE_INFORMATION)pBuf;   
  47.   
  48.         nRtnValue = (*pfn)(hHandle, 1, pstInfo, nSize, &nSize);         // 1 : ObjectNameInformation   
  49.     }   
  50.   
  51.     if (STATUS_SUCCESS == nRtnValue)   
  52.     {   
  53.         StringCchCopy(lpszName, dwCchName, pstInfo->TypeName.Buffer);   
  54.     }   
  55.   
  56. FINAL:   
  57.   
  58.     if (NULL != pBuf)   
  59.     {   
  60.         delete [] pBuf;   
  61.         pBuf = NULL;   
  62.     }   
  63.   
  64.     if (NULL != hModule)   
  65.     {   
  66.         ::FreeLibrary(hModule);   
  67.         hModule = NULL;   
  68.     }   
  69.   
  70.     return nRtnValue;   
  71. }  


반응형

+ Recent posts