하도 오랜만에 하는거라 그런지, 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 책임님이 생각납니다. :-)