[WinDbg] TIB(TEB)를 통해서 PEB를 얻는다

TIB는 Win32 API 호출없이도 프로세스에 대한 많은 정보를 얻는데 사용될수 있다.
FS는 TDB(thread data base)로 알려진 데이터 블럭에 내포되어 있는 TIB와 연결된다.
TIB는 스레드 지정 예외 핸들링과 TLS 포인터를 포함한다. 여기서 TLS는 C 지역 변수와 같지는 않다.

TIB 얻어오는 방법
TIB는 세그먼트 레지스터 FS의 옵셋으로 접근될 수 있다. FS:[0]의 옵셋으로 TIB 필드를 접근하는 것이 일반적이지는 않다. 오히려 FS:[0x18]에 저장된 포인터를 얻는것이 일반적이다.
AT&T style inline assemly
void* getTIB()
{
   void* pTib;
   __asm__("movl %%fs:0x18, %0" : "=r" (pTib) : :);
   return pTib;
}

// MS c
void* getTIB()
{
   void* pTib;
   __asm__ {
      mov EAX, FS:[18h]
      mov [pTib], EAX
   }
   return pTib;
}

최신의 MS 컴파일러는 예약어로 다음을 포함한다.
__readfsword
위는 인라인 어셈블리 필요없이 FS 세그먼트를 접근하는데 사용될 수 있다.


일단 TIB를 얻어오면 PEB를 얻어올 수 있는데 그 구조는 아래와 같다.
0:000> dt _TEB @$teb
ntdll!_TEB
   +0x000 NtTib            : _NT_TIB
   +0x01c EnvironmentPointer : (null) 
   +0x020 ClientId         : _CLIENT_ID
   +0x028 ActiveRpcHandle  : (null) 
   +0x02c ThreadLocalStoragePointer : (null) 
   +0x030 ProcessEnvironmentBlock : 0x7ffd6000 _PEB
...
...

보통 TIB -> PEB를 통해서 정보를 가져오는 함수중에 대표적인 것으로는 GetProcessHeap이 있다.
0:000> u kernel32!GetProcessHeap
kernel32!GetProcessHeap:
7c80abd1 64a118000000    mov     eax,dword ptr fs:[00000018h] ; TIB주소
7c80abd7 8b4030          mov     eax,dword ptr [eax+30h] ; PEB주소
7c80abda 8b4018          mov     eax,dword ptr [eax+18h] ; ProcessHeap멤버의미
7c80abdd c3              ret

댓글

댓글 쓰기

이 블로그의 인기 게시물

[WinAPI] 모달리스 다이얼로그 설명

[WinDbg] Debugging a stack overflow

[WinDbg] first-chance, second-chance Exception