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 등이 있다.
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)
- 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
'Research > Windows' 카테고리의 다른 글
C++ constructor 생성자 호출 방식 (0) | 2014.10.10 |
---|---|
calling convention, name mangling, C/C++ DLL Export 에 대해. (0) | 2014.09.19 |
LPTHREAD_START_ROUTINE 은 stdcall 이어야만 하는가 (0) | 2014.08.20 |
스크랩 - C++상에서 발생하는 name mangling에 관한 내용 (0) | 2014.08.14 |
NTSTATUS (1) | 2014.08.12 |