반응형
Win32 API에서는 이러한 정보를 구하는 방법을 제공하고 있지 않습니다. Windows Native API를 사용해야
해당 정보를 구할 수 있습니다. (ntdll.dll::ZwQueryObject(...))
백문이 불여일견.
해당 정보를 리턴하는 다음 코드를 공유합니다.
(코드가 좀 길어 보여서... "view plain"으로 보시면 수월할 겁니다.)
자료구조를 포함하는 헤더 파일입니다.
- #include <winternl.h>
- // ntdll::ZwQueryObject(...)의 prototype
- typedef NTSTATUS (__stdcall *LPFN_ZwQueryObject)(IN HANDLE Handle, IN DWORD ObjectInformationClass, OUT PVOID ObjectInformation, IN ULONG ObjectInformationLength, OUT PULONG ReturnLength);
- // ntdll::ZwQueryObject(...)에서 쓰임
- typedef struct tagPUBLIC_OBJECT_TYPE_INFORMATION
- {
- UNICODE_STRING TypeName;
- ULONG Reserved[MAX_PATH];
- } PUBLIC_OBJECT_TYPE_INFORMATION, *PPUBLIC_OBJECT_TYPE_INFORMATION;
- // ZwQueryObject를 통한 Kernel Object의 Type
- typedef INT TYPE_KERNEL_OBJECT;
- #define TYPE_KERNEL_OBJECT_UNKNOWN 0
- #define TYPE_KERNEL_OBJECT_TYPE 1
- #define TYPE_KERNEL_OBJECT_DIRECTORY 2
- #define TYPE_KERNEL_OBJECT_SYMBOLICLINK 3
- #define TYPE_KERNEL_OBJECT_TOKEN 4
- #define TYPE_KERNEL_OBJECT_PROCESS 5
- #define TYPE_KERNEL_OBJECT_THREAD 6
- #define TYPE_KERNEL_OBJECT_JOB 7
- #define TYPE_KERNEL_OBJECT_DEBUGOBJECT 8
- #define TYPE_KERNEL_OBJECT_EVENT 9
- #define TYPE_KERNEL_OBJECT_EVENTPAIR 10
- #define TYPE_KERNEL_OBJECT_MUTANT 11
- #define TYPE_KERNEL_OBJECT_CALLBACK 12
- #define TYPE_KERNEL_OBJECT_SEMAPHORE 13
- #define TYPE_KERNEL_OBJECT_TIMER 14
- #define TYPE_KERNEL_OBJECT_PROFILE 15
- #define TYPE_KERNEL_OBJECT_KEYEDEVENT 16
- #define TYPE_KERNEL_OBJECT_WINDOWSTATION 17
- #define TYPE_KERNEL_OBJECT_DESKTOP 18
- #define TYPE_KERNEL_OBJECT_SECTION 19
- #define TYPE_KERNEL_OBJECT_KEY 20
- #define TYPE_KERNEL_OBJECT_PORT 21
- #define TYPE_KERNEL_OBJECT_WAITABLEPORT 22
- #define TYPE_KERNEL_OBJECT_ADAPTER 23
- #define TYPE_KERNEL_OBJECT_CONTROLLER 24
- #define TYPE_KERNEL_OBJECT_DEVICE 25
- #define TYPE_KERNEL_OBJECT_DRIVER 26
- #define TYPE_KERNEL_OBJECT_IOCOMPLETION 27
- #define TYPE_KERNEL_OBJECT_FILE 28
- #define TYPE_KERNEL_OBJECT_WMIGUID 29
- #define TYPE_KERNEL_OBJECT_FILTERCONNECTIONPORT 30
- #define TYPE_KERNEL_OBJECT_FILTERCOMMUNICATIONPORT 31
- #define TYPE_KERNEL_OBJECT_OTHER 32
Kernel Object Handle의 Type을 구하는 함수입니다.
- NTSTATUS GetHandleType(IN HANDLE hHandle, OUT TYPE_KERNEL_OBJECT *pnObject)
- {
- NTSTATUS nRtnValue = 0;
- HMODULE hModule = NULL;
- LPFN_ZwQueryObject pfn = NULL;
- ULONG nSize = 0;
- LPBYTE pBuf = NULL;
- PPUBLIC_OBJECT_TYPE_INFORMATION pstInfo = NULL;
- PUBLIC_OBJECT_TYPE_INFORMATION stInfo = {0,};
- if (NULL == pnObject)
- {
- nRtnValue = STATUS_INVALID_PARAMETER;
- goto FINAL;
- }
- (*pnObject) = TYPE_KERNEL_OBJECT_UNKNOWN;
- // 만들어 놓은 아래 함수가 없다면,
- // hModule = ::LoadLibraryEx(TEXT("ntdll.dll"), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
- // 를 사용한다.
- hModule = LoadLibraryFromSystem(TEXT("ntdll.dll"));
- if (NULL == hModule)
- {
- nRtnValue = STATUS_OBJECT_PATH_NOT_FOUND;
- goto FINAL;
- }
- pfn = (LPFN_ZwQueryObject)::GetProcAddress(hModule, "ZwQueryObject");
- if (NULL == pfn)
- {
- nRtnValue = STATUS_PROCEDURE_NOT_FOUND;
- goto FINAL;
- }
- pstInfo = &stInfo;
- nRtnValue = (*pfn)(hHandle, 2, pstInfo, sizeof(stInfo), &nSize); // 2 : ObjectTypeInformation
- if (STATUS_INFO_LENGTH_MISMATCH == nRtnValue)
- {
- pBuf = new BYTE[nSize];
- if (NULL == pBuf)
- {
- nRtnValue = STATUS_NO_MEMORY;
- goto FINAL;
- }
- ZeroMemory(pBuf, sizeof(BYTE)*nSize);
- pstInfo = (PPUBLIC_OBJECT_TYPE_INFORMATION)pBuf;
- nRtnValue = (*pfn)(hHandle, 2, pstInfo, nSize, &nSize); // 2 : ObjectTypeInformation
- }
- if (STATUS_SUCCESS != nRtnValue)
- {
- goto FINAL;
- }
- if (NULL == pstInfo->TypeName.Buffer)
- {
- nRtnValue = STATUS_INVALID_PARAMETER;
- goto FINAL;
- }
- // 빈도 많음
- if (0 == _tcsicmp(TEXT("Key"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_KEY;
- else if (0 == _tcsicmp(TEXT("File"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_FILE;
- else if (0 == _tcsicmp(TEXT("Thread"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_THREAD;
- else if (0 == _tcsicmp(TEXT("Directory"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_DIRECTORY;
- else if (0 == _tcsicmp(TEXT("Section"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_SECTION;
- else if (0 == _tcsicmp(TEXT("Event"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_EVENT;
- else if (0 == _tcsicmp(TEXT("Mutant"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_MUTANT;
- else if (0 == _tcsicmp(TEXT("Port"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_PORT;
- // 빈도 적음
- else if (0 == _tcsicmp(TEXT("KeyedEvent"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_KEYEDEVENT;
- else if (0 == _tcsicmp(TEXT("Token"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_TOKEN;
- else if (0 == _tcsicmp(TEXT("WindowStation"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_WINDOWSTATION;
- else if (0 == _tcsicmp(TEXT("Type"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_TYPE;
- else if (0 == _tcsicmp(TEXT("SymbolicLink"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_SYMBOLICLINK;
- else if (0 == _tcsicmp(TEXT("Process"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_PROCESS;
- else if (0 == _tcsicmp(TEXT("Job"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_JOB;
- else if (0 == _tcsicmp(TEXT("DebugObject"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_DEBUGOBJECT;
- else if (0 == _tcsicmp(TEXT("EventPair"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_EVENTPAIR;
- else if (0 == _tcsicmp(TEXT("Callback"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_CALLBACK;
- else if (0 == _tcsicmp(TEXT("Semaphore"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_SEMAPHORE;
- else if (0 == _tcsicmp(TEXT("Timer"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_TIMER;
- else if (0 == _tcsicmp(TEXT("Profile"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_PROFILE;
- else if (0 == _tcsicmp(TEXT("Desktop"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_DESKTOP;
- else if (0 == _tcsicmp(TEXT("WaitablePort"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_WAITABLEPORT;
- else if (0 == _tcsicmp(TEXT("Adapter"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_ADAPTER;
- else if (0 == _tcsicmp(TEXT("Controller"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_CONTROLLER;
- else if (0 == _tcsicmp(TEXT("Device"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_DEVICE;
- else if (0 == _tcsicmp(TEXT("Driver"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_DRIVER;
- else if (0 == _tcsicmp(TEXT("IoCompletion"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_IOCOMPLETION;
- else if (0 == _tcsicmp(TEXT("WmiGuid"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_WMIGUID;
- else if (0 == _tcsicmp(TEXT("FilterConnectionPort"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_FILTERCONNECTIONPORT;
- else if (0 == _tcsicmp(TEXT("FilterCommunicationPort"), pstInfo->TypeName.Buffer))
- (*pnObject) = TYPE_KERNEL_OBJECT_FILTERCOMMUNICATIONPORT;
- else
- (*pnObject) = TYPE_KERNEL_OBJECT_OTHER;
- FINAL:
- if (NULL != pBuf)
- {
- delete [] pBuf;
- pBuf = NULL;
- }
- if (NULL != hModule)
- {
- ::FreeLibrary(hModule);
- hModule = NULL;
- }
- return nRtnValue;
- }
Kernel Object Handle의 Name을 구하는 함수입니다.
- NTSTATUS GetHandleObjectName(IN HANDLE hHandle, OUT LPTSTR lpszName, IN DWORD dwCchName)
- {
- NTSTATUS nRtnValue = 0;
- HMODULE hModule = NULL;
- LPFN_ZwQueryObject pfn = NULL;
- ULONG nSize = 0;
- LPBYTE pBuf = NULL;
- PPUBLIC_OBJECT_TYPE_INFORMATION pstInfo = NULL;
- PUBLIC_OBJECT_TYPE_INFORMATION stInfo = {0,};
- if (NULL == lpszName)
- {
- nRtnValue = STATUS_INVALID_PARAMETER;
- goto FINAL;
- }
- // 만들어 놓은 아래 함수가 없다면,
- // hModule = ::LoadLibraryEx(TEXT("ntdll.dll"), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
- // 를 사용한다.
- hModule = LoadLibraryFromSystem(TEXT("ntdll.dll"));
- if (NULL == hModule)
- {
- nRtnValue = STATUS_OBJECT_PATH_NOT_FOUND;
- goto FINAL;
- }
- pfn = (LPFN_ZwQueryObject)::GetProcAddress(hModule, "ZwQueryObject");
- if (NULL == pfn)
- {
- nRtnValue = STATUS_PROCEDURE_NOT_FOUND;
- goto FINAL;
- }
- pstInfo = &stInfo;
- nRtnValue = (*pfn)(hHandle, 1, pstInfo, sizeof(stInfo), &nSize); // 1 : ObjectNameInformation
- if (STATUS_INFO_LENGTH_MISMATCH == nRtnValue)
- {
- pBuf = new BYTE[nSize];
- if (NULL == pBuf)
- {
- nRtnValue = STATUS_NO_MEMORY;
- goto FINAL;
- }
- ZeroMemory(pBuf, sizeof(BYTE)*nSize);
- pstInfo = (PPUBLIC_OBJECT_TYPE_INFORMATION)pBuf;
- nRtnValue = (*pfn)(hHandle, 1, pstInfo, nSize, &nSize); // 1 : ObjectNameInformation
- }
- if (STATUS_SUCCESS == nRtnValue)
- {
- StringCchCopy(lpszName, dwCchName, pstInfo->TypeName.Buffer);
- }
- FINAL:
- if (NULL != pBuf)
- {
- delete [] pBuf;
- pBuf = NULL;
- }
- if (NULL != hModule)
- {
- ::FreeLibrary(hModule);
- hModule = NULL;
- }
- return nRtnValue;
- }
반응형
'Windows Programming' 카테고리의 다른 글
Detour Library (0) | 2011.03.23 |
---|---|
Dependency Walker(depends.exe) (0) | 2011.03.22 |
Thread별로 관리되는 혹은 초기화 해주어야 하는 것들 (0) | 2010.04.01 |
Shell_NotifyIcon, NOTIFYICONDATA struct Size (1) | 2010.03.03 |
레지스트리 감시 (0) | 2010.02.26 |