2014년 2월 4일 화요일

WinDbg :: dg 명령어

오랜만에 분석 할 꺼리가 생겨서 커널코드를 뒤적이다가, 세그먼트 관련 내용을 확인할 일이 생겼습니다.
하도 오랜만에 하는거라 그런지, dg 명령어까지는 생각이났는데, 출력 형태를 헤깔리는 바람에 쓸데없는 삽질을 하게되어 흔적이라도 남겨볼까하고요.

세그먼트 셀렉터는 상위 13비트를 GDT / LDT 인덱스로 사용합니다. 아래 처럼요.

; 15                                                2  1  0
; +----------------------------+-------------------+--+--+--+
; |                          index                 |TI| RPL |
; +----------------------------+-------------------+--+--+--+
;
; index
;   GDT 의 인덱스 값 ( GDT = index * sizeof(GDT Descriptor) )
;
; TI (Table Indicator)
;   0 이면 GDT (Global Descriptor Table)
;   1 이면 LDT (Local Descriptor Table)
;
; RPL (Requestor Privilege Level)

system context 에서 셀렉터와 세그먼트 디스크립터 출력내용입니다.

cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202

0: kd> dg 0 80
                                                    P Si Gr Pr Lo
Sel        Base              Limit          Type    l ze an es ng Flags
---- ----------------- ----------------- ---------- - -- -- -- -- --------
0000 00000000`00000000 00000000`00000000 <reserved> 0 Nb By Np Nl 00000000
0008 00000000`00000000 00000000`00000000 <reserved> 0 Nb By Np Nl 00000000
0010 00000000`00000000 00000000`00000000 Code RE Ac 0 Nb By P  Lo 0000029b
0018 00000000`00000000 00000000`ffffffff Data RW Ac 0 Bg Pg P  Nl 00000c93
0020 00000000`00000000 00000000`ffffffff Code RE    3 Bg Pg P  Nl 00000cfa
0028 00000000`00000000 00000000`ffffffff Data RW Ac 3 Bg Pg P  Nl 00000cf3
0030 00000000`00000000 00000000`00000000 Code RE Ac 3 Nb By P  Lo 000002fb
0038 00000000`00000000 00000000`00000000 <reserved> 0 Nb By Np Nl 00000000
0040 00000000`00b96080 00000000`00000067 TSS32 Busy 0 Nb By P  Nl 0000008b
0048 00000000`0000ffff 00000000`0000f800 <reserved> 0 Nb By Np Nl 00000000
0050 ffffffff`fffe0000 00000000`00003c00 Data RW Ac 3 Bg By P  Nl 000004f3
0058 00000000`00000000 00000000`00000000 <reserved> 0 Nb By Np Nl 00000000
0060 00000000`00000000 00000000`ffffffff Code RE    0 Bg Pg P  Nl 00000c9a
0068 00000000`00000000 00000000`00000000 <reserved> 0 Nb By Np Nl 00000000
0070 00000000`00000000 00000000`00000000 <reserved> 0 Nb By Np Nl 00000000
0078 00000000`00000000 00000000`00000000 <reserved> 0 Nb By Np Nl 00000000
0080 Unable to get descriptor

WinDbg 의 dg 명령어 출력의 Sel 부분은 셀렉터의 RPL 필드를 00 으로 간주한 상태로 셀렉터 값을 출력합니다. 이걸 깜빡하는 바람에...@,.@

따라서 fs 셀렉터 0x53 -> 0x50 으로 치환해서 dg 출력에서 찾아야 합니다.
위에서는 0xffffffff`fffa0000 를 베이스로 하고, 리미트가 0x00003c00 인 GDT 엔트리를 가지는 것을 확인 할 수 있습니다. 다시 말해서 fs:[0] -> 0xffffffff`fffa0000 라는 거죠.

cs = 0x0010 : 00010 0 00 -> r0, gdt, Sel = 0010 0 00 -> 0x10
ss = 0x0018 : 00011 0 00 -> r0, gdt, Sel = 0011 0 00 -> 0x18
fs = 0x0053 : 01010 0 11 -> r3, gdt, Sel = 1010 0 00 -> 0x50
ds,es,gs
   = 0x002b : 00101 0 11 -> r3, gdt, Sel = 0101 0 00 -> 0x28

64 비트는 분석경험이 거의 없다보니, 새롭기도 하고, 어렵기도 하고...
언젠가 64비트 악성코드가 나오기 시작하면 분석가 생활을 접겠다고 하셨던 고XX 책임님이 생각납니다. :-)