System - Object Table

from Study/API 2007/10/09 17:09 view 18350
출처 : -_-..홈페이지가 폐쇠됨..
// 테이블 3개가 존재한다는 말은 2000 구조같은데... xp는 어떨지...

Win32 개발자들은 핸들이 뭔지는 알고 있을 것이다.

 그리고 이 핸들이 윈도우핸들(HWND)이 아님을 알고 있을것이다. 이 핸들이란건 특정 동작을 하기 위한 핸들링 용도로 쓰이고 있으며 대표적으로 파일을 다루는 WINAPI인 CreateFile(), ReadFile, WriteFile()함수들을 예로 들어 볼 수 있다.
 
 CreateFile()함수 성공시에 리턴값으로 핸들을 받게 되는데 이 핸들은 나중에 특정 파일을 핸들링 하기 위해 그 정보를 유지 해야 하는데 그 정보는 커널영역에 오브젝트 형태로 존재하게 되며 보통은 커널 오브젝트라고 부른다.

그럼 핸들값이 의미하는 숫자는 무엇일까?
이 핸들값은 커널오브젝트를 찾기 위한 일종의 인덱스 역활을 하는 값이다.
밑에 그림을 보도록 하자.



 위 그림은 유저영역에 존재하는 HANDLE을 통해 실제 객체를 나타내는 커널 오브젝트를 찾아가는 그림이다. 그림에선 중간에 HANDLE TALBLE이란게 존재하여 핸들값을 핸들테이블에서 인덱스로 사용하여 커널 오브젝트의 포인터를 찾는다.

자 이제 핸들테이블에 대해 알아보자.

핸들테이블이란?
 현 프로세스에서 생성된 핸들들에 대해서 커널 객체를 찾아가기 위한 인터페이스 역할을 하는 배열 형태로 된 테이블 영역이다. 이 핸들 테이블은 프로세스당 하나가 할당되며 프로세스간 독립적으로 핸들 테이블을 관리하게 되는데 우리가 CreateFile()로 생성된 핸들은 CloseHandle()를 사용하지 않고 프로세스를 죽였을때 운영체제는 이 핸들테이블에서 할당된 정보를 보고 모든 핸들을 반환하게 된다.

밑에 그림은 객체의 포인터를 찾기 위한 핸들테이블 구조를 보여준다.




 핸들테이블은 세개의 영역이 존재하는데 Top, Middle, entry가 존재함을 그림을 통해
알수가있다.
 그럼 위 테이블 구조를 어떤식으로 접근하여 실제 커널 오브젝트를 찾을 것인가? 아까 핸들값이 인덱스 역할을 하는 값이라고 설명하였다. 이 핸들값을 바이트 단위로 3등분 한후 핸들 테이블의 각 레벨의 배열을 인덱스로 사용하고 찾아간다.

밑에 그림은 핸들값이 0x4일때 이걸 세등분 한 후 핸들 테이블을 인덱스 삼아
실제 오브젝트를 찾아가는 그림이다.




 핸들값은 상위 6비트와 하위 2비트는 핸들테이블을 인덱싱하는 부분에선 해당되지 않는 비트이며 중간에 있는 총 3개의 8비트가 우리가 커널 오브젝트를 찾기 위한 핸들테이블을 접근하는 인덱스 번호가 되겠다.

 Table ptr은 Top레벨의 주소를 가리킨다.여기서부터 핸들값의 인덱스가 적용된다. 우리가 보고자 하는 0x4값은 각각 Top:0, Mid:0, Entry:1값을 가진다. 핸들 테이블에 이 값들을 적용하면 Top[0], Mid[0], Entry[1]이 되며. 처음 Top[0]에는 Mid의 첫번째 배열 주소를 가지키며 Mid[0]은 Entry의 주소를 가리키고 있다. 마지막 Entry는 실제 커널 오브젝트를 가리키는 주소를 가지고 있게된다.

코드로 함 살펴보기로 하자.

lkd> dt nt!_EPROCESS
   +0x000 Pcb              : _KPROCESS

   +0x0c4 ObjectTable      : Ptr32 _HANDLE_TABLE

 커널에서 프로세스를 표현하는 EPROCESS에 보면 _HANDLE_TABLE ObjectTable가 존재한다.이 필드는 HANDLE_TABLE이란 구조체의 포인터를 가리키며 이 필드가 실제 핸들 테이블의 정보를 가지고 있는 셈이다. 윈도우 XP에서 ObjectTable의 위치는 0x0c4로 되어있다.

자 이제 HANDLE_TABLE의 구조를 살펴 봐야 한다.

lkd> dt nt!_HANDLE_TABLE
   +0x000 TableCode        : Uint4B
   +0x004 QuotaProcess     : Ptr32 _EPROCESS
   +0x008 UniqueProcessId  : Ptr32 Void
   +0x00c HandleTableLock  : [4] _EX_PUSH_LOCK
   +0x01c HandleTableList  : _LIST_ENTRY
   +0x024 HandleContentionEvent : _EX_PUSH_LOCK
   +0x028 DebugInfo        : Ptr32 _HANDLE_TRACE_DEBUG_INFO
   +0x02c ExtraInfoPages   : Int4B
   +0x030 FirstFree        : Uint4B
   +0x034 LastFree         : Uint4B
   +0x038 NextHandleNeedingPool : Uint4B
   +0x03c HandleCount      : Int4B
   +0x040 Flags            : Uint4B
   +0x040 StrictFIFO       : Pos 0, 1 Bit

 대충 보면 몇몇 필드는 변수명으로 그 의미를 파악할 수 있다. 여기서 HandleCount는 현재 프로세스에 할당된 핸들 총갯수 즉 핸들 테이블에 기록된 핸들의 정보수를 나타낸다.

UniqueProcessId는 이 핸들 테이블을 소유한 프로세스의 ID를 뜻하며 실제적인 핸들 테이블을 나타내는 Table 필드가 우리가 알고자 하는 핸들 테이블을 가리키는 필드이다.

lkd> dt nt!_HANDLE_TABLE_ENTRY
   +0x000 Object           : Ptr32 Void
   +0x000 ObAttributes     : Uint4B
   +0x000 InfoTable        : Ptr32 _HANDLE_TABLE_ENTRY_INFO
   +0x000 Value            : Uint4B
   +0x004 GrantedAccess    : Uint4B
   +0x004 GrantedAccessIndex : Uint2B
   +0x006 CreatorBackTraceIndex : Uint2B
   +0x004 NextFreeTableEntry : Int4B

HANDLE_TABLE_ENTRY 구조체는 커널 오브젝트를 가리키는 Object필드와 핸들테이블 액세스 관련 필드인 GrantedAccess로 구성되어 있으며 Object가 OBJECT_HEADER를 가리키며 OBJECT_HEADER + OBJECT BODY 형태로 되어있다. 구조는 밑에와 같이 생겼으며 Body로 된 부분은 커널 객체마다 다른 구조로 되어 있다.

lkd> dt nt!_OBJECT_HEADER
   +0x000 PointerCount     : Int4B
   +0x004 HandleCount      : Int4B
   +0x004 NextToFree       : Ptr32 Void
   +0x008 Type             : Ptr32 _OBJECT_TYPE
   +0x00c NameInfoOffset   : UChar
   +0x00d HandleInfoOffset : UChar
   +0x00e QuotaInfoOffset  : UChar
   +0x00f Flags            : UChar
   +0x010 ObjectCreateInfo : Ptr32 _OBJECT_CREATE_INFORMATION
   +0x010 QuotaBlockCharged : Ptr32 Void
   +0x014 SecurityDescriptor : Ptr32 Void
   +0x018 Body             : _QUAD

 이 Body부분은 운영체제에 지시한 특정 명령에 동작을 나타내는 정보를 가지고 있는 실제 커널 오브젝트를 뜻한다.
 이 객체는 CreateFile()과 같은 커널에서 수행되어야 될 명령을 오브젝트 형태로 커널에서 관리하기 위해서 만들어진 구조체이며 유저영역에선 핸들을 사용하여 커널 오브젝트에 접근하게 된다.
 커널오브젝트는 스스로 제거될 수 있도록 참조 개수를 유지 하게 되는데. HandleCount, PointerCount란 필드를 통해서 관리된다. HandleCount는 우리가 CreateFile()로 생성되었을때 리턴된 핸들의 갯수를 뜻하며 PointerCount는 핸들이 아닌 직접 객체의 포인터를 얻어왔을때 증가하게된다. 커널에선 ReferenceObjectByPointer(), ObDereferenceObject() 사용시에 PointerCount가 증감된다.



Tag |

cmd 에 대한 스레드.

from Info/Tools 2007/10/08 19:03 view 4548
1. 시작/실행에서의 내부 명령어 실행하기
Tag |

재배포 문제

from Study/Error 2007/10/07 10:09 view 25812

1. 방법 : XCopy를 사용하여 배포.
   요약 : C:\Program Files\Microsoft Visual Studio 8\VC\redist\x86 안의 맞는 폴더를 포함하여 배포-_-..

2. VS2005에서 제작한 .exe이 같은 에러가 나올 때.

응용 프로그램 구성이 올바르지 않기 때문에 이 응용 프로그램을 시작하지 못했습니다.
이 문제를 해결하려면 응용 프로그램을 다시 설치하십시오.

more..

Tag | ,

ncb 요거 용량 드럽게 먹네.

from 잡담 2007/10/06 12:05 view 20980
지워 ~ 지워~ search 해서 모두 지워버려~ 2기가 늘어난다.-_-....

NCB -- Parser information file:

This file contains information generated by the parser used by the class view and component gallery. If the file is accidentally or deliberately deleted, it is automatically regenerated.
Tag |

세균전(컴퓨터VS사람)

from -_-.. 2007/10/06 11:41 view 24678

3일간 각고의 노력끝에 했지만 막판 체력부족으로 졸작이 되버린 과제.. 그래도 노력했다.ㅠ_ㅠ.
참고로 마우스 커서를 Window의 ani 커서를 사용했으므로 없으면 안보임..

구조

more..

설명

more..

Tag | , ,

소스코드를 html로 변환하기(C,C++)

from -_-.. 2007/10/06 10:38 view 23572




떠돌아다니는 자료에다가 조금 덧붙임..-_-.. 소스코드가 2줄 안붙으니깐 좋다.. 더 개작해야지..

버그.ㅜ_ㅜ..

more..


테스트~

more..


사용법

more..


Tag | ,

GetPrivateProfileString Function (ini 읽기)

from Study/API 2007/10/05 21:04 view 35363
아나 감동의 쓰나미.. .ini 에서 등록한 키워드 읽어오기 굳이 ini아니라도 되지만..-_-..
참고 : http://msdn2.microsoft.com/en-us/library/ms724353.aspx 

// ini 파일
[section]
key = string

ex)
[C/C++]
KEYWORD = const,for,if


1. MFC에서 CMapStringToString 클래스를 사용하여 읽어오기

more..



2. CIniFile 클래스를 사용해서 읽어오기 ( 래핑 클래스 )

more..

Tag | , ,

(Tip) 관리자 모드 접속

from Info/Web 2007/10/05 19:33 view 23715
-_-..내PC에서만 하기!!

http://dblab.co.kr/login?loginid=aaa@aaa.com&password=12345
Tag |

map 에서 랜덤 돌리는 함수

from Study/C++ 2007/10/01 23:58 view 26429
흠.. 어떻게 할까 고민하다가 iterator를 쓰기로 했다. 

more..

Tag | , ,

네이버 툴바-_-..

from 잡담 2007/09/21 12:34 view 18415

주소창 가는 단축키를 ALT+D 를 ALT+N 으로 바꿔놨네.. 시퐁...

Tag |