Study/study

SEH, TEB(TIB), PEB์™€ FS ๋ ˆ์ง€์Šคํ„ฐ๋ฅผ ํ†ตํ•ด ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•

์œค์ •_ 2024. 5. 14. 16:34

SEH ํ•จ์ˆ˜

  • ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๊ธฐ๋Š” 4๊ฐœ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ž…๋ ฅ ๋ฐ›๊ณ , ์—ด๊ฑฐํ˜•(enum) EXCEPTION_DISPOSITION์„ ๋ฆฌํ„ด
EXCEPTION_DISPOSITION _except_handler
(
    EXCEPTION_RECORD		        *pRecord,
    EXCEPTION_REGISTRATION_RECORD	*pFrame,
    CONTEXT				*pContext,
    PVOID				pValue
);

 

 

  • SEH ํ•จ์ˆ˜ ์ฒซ ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ EXCEPTION_RECORD
typedef struct _EXCEPTION_RECORD {
    DWORD                    ExceptionCode;	//์˜ˆ์™ธ ์ฝ”๋“œ
    DWORD                    ExceptionFlags;
    struct _EXCEPTION_RECORD *ExceptionRecord;
    PVOID                    ExceptionAddress;	//์˜ˆ์™ธ ๋ฐœ์ƒ ์ฃผ์†Œ
    DWORD                    NumberParameters;
    ULONG_PTR                ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
} EXCEPTION_RECORD;
  • ExceptionCode: ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ์˜ ์ข…๋ฅ˜
  • ExceptionAddress: ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ ์ฝ”๋“œ ์ฃผ์†Œ

 

 

  • SEH ํ•จ์ˆ˜ ์„ธ ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ CONTEXT
typedef struct _WOW64_CONTEXT {
    DWORD                    ContextFlags;
  
    DWORD                    Dr0;
    DWORD                    Dr1;
    DWORD                    Dr2;
    DWORD                    Dr3;
    DWORD                    Dr6;
    DWORD                    Dr7;
  
    WOW64_FLOATING_SAVE_AREA FloatSave;
  
    DWORD                    SegGs;
    DWORD                    SegFs;
    DWORD                    SegEs;
    DWORD                    SegDs;
  
    DWORD                    Edi;
    DWORD                    Esi;
    DWORD                    Ebx;
    DWORD                    Edx;
    DWORD                    Ecx;
    DWORD                    Eax;
  
    DWORD                    Ebp;
    DWORD                    Eip;
    DWORD                    SegCs;
    DWORD                    EFlags;
    DWORD                    Esp;
    DWORD                    SegSs;
  
    BYTE                     ExtendedRegisters[WOW64_MAXIMUM_SUPPORTED_EXTENSION];
} WOW64_CONTEXT;
  • CONTEXT ๊ตฌ์กฐ์ฒด๋Š” CPU ๋ ˆ์ง€์Šคํ„ฐ ๊ฐ’์„ ๋ฐฑ์—…ํ•˜๋Š” ์šฉ๋„๋กœ ์‚ฌ์šฉ
    • ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ ๋•Œ๋ฌธ
    • ์Šค๋ ˆ๋“œ๋Š” ๋‚ด๋ถ€ CONTEXT ๊ตฌ์กฐ์ฒด๋ฅผ ํ•˜๋‚˜์”ฉ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ  CPU๊ฐ€ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ ์‹คํ–‰์„ ์œ„ํ•ด ๋– ๋‚  ๋•Œ ํ˜„์žฌ ์Šค๋ ˆ๋“œ์˜ ๋ ˆ์ง€์Šคํ„ฐ ๊ฐ’์„ CONTEXT์— ๋ฐฑ์—…, ๊ทธ ํ›„ CPU๊ฐ€ ๋‹ค์‹œ ์˜ˆ์ „ ์Šค๋ ˆ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Ÿฌ ์˜ค๋ฉด ๊ทธ ์Šค๋ ˆ๋“œ์˜ CONTEXT์— ์ €์žฅ๋œ ๋ ˆ์ง€์Šคํ„ฐ ๊ฐ’๋“ค์„ ์‹ค์ œ CPU ๋ ˆ์ง€์Šคํ„ฐ์— ๋ฎ์–ด์“ฐ๊ณ  ์‹คํ–‰
  • ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์Šค๋ ˆ๋“œ๋Š” ์‹คํ–‰์ด ์ค‘์ง€๋˜๊ณ  SEH๊ฐ€ ์‹คํ–‰๋˜๋Š”๋ฐ, ์ด๋•Œ OS๋Š” ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๊ธฐ ํŒŒ๋ผ๋ฏธํ„ฐ์— ํ•ด๋‹น ์Šค๋ ˆ๋“œ์˜ CONTEXT ๊ตฌ์กฐ์ฒด ํฌ์ธํ„ฐ๋ฅผ ๋„˜๊ฒจ์คŒ
  • CONTEXT.Eip
    • ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๊ธฐ์—์„œ๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„˜์–ด์˜จ CONTEXT.Eip๋ฅผ ๋‹ค๋ฅธ ์ฃผ์†Œ๋กœ ์„ค์ •ํ•œ ํ›„ ๋ฆฌํ„ด, ์•„๊นŒ ์ค‘์ง€๋œ ์Šค๋ ˆ๋“œ๋Š” ์ƒˆ๋กœ ์„ค์ •๋œ EIP ์ฃผ์†Œ์˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰
      ์•ˆํ‹ฐ ๋””๋ฒ„๊น…์— ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ํŠน์ง•

 

 

  • SEH ํ•จ์ˆ˜ ๋ฆฌํ„ด ๊ฐ’ EXCEPTION_DISPOSITION
typedef enum _EXCEPTION_DISPOSITION
{
    ExceptionContinueExecution = 0,	//์˜ˆ์™ธ ์ฝ”๋“œ ์žฌ์‹คํ–‰
    ExceptionContinueSearch = 1,		//๋‹ค์Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๊ธฐ ์‹คํ–‰
    ExceptionNestedException = 2,		//OS ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉ๋จ
    ExceptionCollidedUnwind = 3		//OS ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉ๋จ
} EXCEPTION_DISPOSITION;
  • ExceptionContinueExecution(0): ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ ์ฝ”๋“œ๋ถ€ํ„ฐ ์žฌ์‹คํ–‰
  • ExceptionContinueSearch(1): ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์—†์„ ๋•Œ SEH ์ฒด์ธ์—์„œ ๋‹ค์Œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๊ธฐ์—์„œ ์ฒ˜๋ฆฌํ•˜๋„๋ก ํ•จ

 

 

 

SEH ์ฒด์ธ์— ์ ‘๊ทผ

  • TEB ๊ตฌ์กฐ์ฒด์˜ NtTib ๋ฉค๋ฒ„ ๋”ฐ๋ผ๊ฐ€๊ธฐ
  • TEB๋Š” FS ์„ธ๊ทธ๋จผํŠธ ๋ ˆ์ง€์Šคํ„ฐ๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ์„ธ๊ทธ๋จผํŠธ ๋ฉ”๋ชจ๋ฆฌ์˜ ์‹œ์ž‘ ์ฃผ์†Œ์— ์œ„์น˜
  • TEB.NtTib.ExceptionList = FS:[0]

 

 

TEB, Thread Environment Block

  • ํ”„๋กœ์„ธ์Šค์—์„œ ์‹คํ–‰๋˜๋Š” ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” ๊ตฌ์กฐ์ฒด
  • TIB(Thread Information Block)์ด๋ผ๊ณ ๋„ ํ•จ
  • ์Šค๋ ˆ๋“œ๋ณ„ TEB ๊ตฌ์กฐ์ฒด๊ฐ€ ํ•˜๋‚˜์”ฉ ํ• ๋‹น๋จ
  • TEB ๊ตฌ์กฐ์ฒด (msdn)
typedef struct _TEB {
    PVOID Reserved1[12];
    PPEB  ProcessEnvironmentBlock;
    PVOID Reserved2[399];
    BYTE  Reserved3[1952];
    PVOID TlsSlots[64];
    BYTE  Reserved4[8];
    PVOID Reserved5[26];
    PVOID ReservedForOle;
    PVOID Reserved6[4];
    PVOID TlsExpansionSlots;
} TEB, *PTEB;

 

  • TEB ๊ตฌ์กฐ์ฒด - Windows 7 (WinDbg)
+0x000 NtTib				: _NT_TIB
+0x01c EnvironmentPointer		: Ptr32 Void
+0x020 ClientId				: _CLIENT_ID
+0x028 ActiveRpcHandle			: Ptr32 Void
+0x02c ThreadLocalStoragePointer	: Ptr32 _PEB
+0x030 ProcessEnvironmentBlock		: Ptr32 _PEB
			...

 

  • TEB ๊ตฌ์กฐ์ฒด ์ฃผ์š” ๋ฉค๋ฒ„
    • ProcessEnvironmentBlock
      • PEB ๊ตฌ์กฐ์ฒด์˜ ํฌ์ธํ„ฐ
    • NtTib
      • _NT_TIB ๊ตฌ์กฐ์ฒด
        • ExceptionList: _EXCEPTION_REGISTRATION_RECORD ๊ตฌ์กฐ์ฒด ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ์Œ
        • Self: NT_TIB ๊ตฌ์กฐ์ฒด์˜ ์…€ํ”„ ํฌ์ธํ„ฐ. ์ฆ‰, TEB ๊ตฌ์กฐ์ฒด ํฌ์ธํ„ฐ
typedef struct _NT_TIB {
    struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;
    PVOID StackBase;
    PVOID StackLimit;
    PVOID SubSystemTib;
    union {
        PVOID FiberData;
        DWORD Version;
    };
    PVOID ArbitraryUserPointer;
    struct _NT_TIB *Self;
} NT_TIB;
typedef NT_TIB *PNT_TIB;

 

 

 

PEB, Process Environment Block

  • ํ”„๋กœ์„ธ์Šค ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” ๊ตฌ์กฐ์ฒด
  • PEB ๊ตฌ์กฐ์ฒด (msdn)
typedef struct _PEB {
    BYTE                          Reserved1[2];
    BYTE                          BeingDebugged;
    BYTE                          Reserved2[1];
    PVOID                         Reserved3[2];
    PPEB_LDR_DATA                 Ldr;
    PRTL_USER_PROCESS_PARAMETERS  ProcessParameters;
    PVOID                         Reserved4[3];
    PVOID                         AtlThunkSListPtr;
    PVOID                         Reserved5;
    ULONG                         Reserved6;
    PVOID                         Reserved7;
    ULONG                         Reserved8;
    ULONG                         AtlThunkSListPtr32;
    PVOID                         Reserved9[45];
    BYTE                          Reserved10[96];
    PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
    BYTE                          Reserved11[128];
    PVOID                         Reserved12[1];
    ULONG                         SessionId;
} PEB, *PPEB;

 

 

  • PEB ๊ตฌ์กฐ์ฒด - Windows 7 (WinDbg)
+000 InheritedAddressSpace		: UChar
+001 ReadImageFileExecOptions		: Uchar
+002 BeingDebugged			: Uchar
+003 BitField				: UChar
+003 ImageUsesLargePages		: Pos 0, 1 Bit
			...
+008 ImageBaseAddress			: UChar
			...
+00c Ldr				: Ptr32 _PEB_LDR_DATA
			...
+018 ProcessHeap			: Ptr32 Void
			...
+068 NtGlobalFlag			: Uint4B
			...

 

  • PEB ๊ตฌ์กฐ์ฒด ์ฃผ์š” ๋ฉค๋ฒ„
    • PEB.BeingDebugged
      • ํ˜„์žฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋””๋ฒ„๊น… ๋‹นํ•˜๋Š”์ง€ ํŒ๋‹จ
      • IsDebuggerPresent ํ•จ์ˆ˜๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ์ •๋ณด
      • ๋””๋ฒ„๊น… ์ค‘์ด๋ฉด 1, ์•„๋‹ˆ๋ฉด 0์„ ๋ฆฌํ„ด
      • ์ผ๋ฐ˜ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ ๊ฐœ๋ฐœ์—๋Š” ์ž˜ ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ณ , ์ฃผ๋กœ ์•ˆํ‹ฐ ๋””๋ฒ„๊น…์— ์ด์šฉ
    • PEB.ImageBaseAddress
      • ํ”„๋กœ์„ธ์Šค์˜ ImageBase๋ฅผ ํ‘œ์‹œ
      • GetMoaduleHandle ํ•จ์ˆ˜๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ์ •๋ณด
        * GetMoaduleHandle: ํ”„๋กœ์„ธ์Šค์˜ ImageBase๋ฅผ ์–ป์–ด๋‚ด๋Š” API
    • PEB.Ldr
      • _PEB_LDR_DATA ๊ตฌ์กฐ์ฒด์˜ ํฌ์ธํ„ฐ
      • ํ˜„์žฌ ํ”„๋กœ์„ธ์Šค์—์„œ ๋กœ๋“œ๋œ ๋ชจ๋“ˆ๋“ค์˜ ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ์Œ
      • ํ”„๋กœ์„ธ์Šค์— ๋กœ๋”ฉ๋œ ๋ชจ๋“ˆ(DLL)์˜ ๋กœ๋”ฉ ๋ฒ ์ด์Šค ์ฃผ์†Œ๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ!
        • _PEB_LDR_DATA ๊ตฌ์กฐ์ฒด์˜ _LIST_ENTRY ํƒ€์ž…์˜ ๋ฉค๋ฒ„(InLoadOrderModuleList, InMemoryOrderModuleList, InInitializationOrderModuleList)๋ฅผ ํ†ตํ•ด ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ์Œ
        • _LIST_ENTRY๋Š” ์–‘๋ฐฉํ–ฅ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ œ๊ณตํ•˜๋Š”๋ฐ, ์ด ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์—๋Š” _LDR_DATA_TABLE_ENTRY ๊ตฌ์กฐ์ฒด ์ •๋ณด๊ฐ€ ์ €์žฅ.
        • ํ”„๋กœ์„ธ์Šค์— ๋กœ๋”ฉ๋œ DLL ๋ชจ๋“ˆ๋งˆ๋‹ค _LDR_DATA_TABLE_ENTRY ๊ตฌ์กฐ์ฒด๊ฐ€ ํ•˜๋‚˜์”ฉ ์ƒ์„ฑ๋˜๊ณ , ์ด๋“ค์€ _LIST_ENTRY ์–‘๋ฐฉํ–ฅ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— DLL ๋ชจ๋“ˆ์˜ ๋กœ๋”ฉ ๋ฒ ์ด์Šค ์ฃผ์†Œ๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋จ
    • PEB.ProcessHeap, PEB.NtGlobalFlag
      • ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋””๋ฒ„๊น… ์ค‘์ด๋ผ๋ฉด ํŠน์ •ํ•œ ๊ฐ’์„ ๊ฐ€์ง
      • ์ฃผ๋กœ ์•ˆํ‹ฐ ๋””๋ฒ„๊น…์— ์ด์šฉ

 

 

 

 

FS ๋ ˆ์ง€์Šคํ„ฐ๋ฅผ ํ†ตํ•œ TEB, PEB, SEH ์‹œ์ž‘ ์ฃผ์†Œ

  • FS ์„ธ๊ทธ๋จผํŠธ ๋ ˆ์ง€์Šคํ„ฐ: ํ˜„์žฌ ์Šค๋ ˆ๋“œ์˜ TEB๋ฅผ ์ง€์‹œ
  • FS ๋ ˆ์ง€์Šคํ„ฐ์˜ ํฌ๊ธฐ: 16๋น„ํŠธ
    • ์‚ฌ์‹ค, IA32 ์‹œ์Šคํ…œ์˜ ํ”„๋กœ์„ธ์Šค ๊ฐ€์ƒ ๋ฉ”๋ชจ๋ฆฌ ํฌ๊ธฐ๋Š” 4GB์ด๋ฏ€๋กœ 32๋น„ํŠธ ํฌ๊ธฐ์˜ ํฌ์ธํ„ฐ๋ฅผ ์ด์šฉํ•ด์•ผ ์ „์ฒด ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์— ์ ‘๊ทผ ๊ฐ€๋Šฅ
    • ๊ทธ๋Ÿฌ๋‚˜ FS ๋ ˆ์ง€์Šคํ„ฐ๋Š” ์ง์ ‘ TEB ์ฃผ์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ์‹ค์ œ TEB ์ฃผ์†Œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” Segment Descriptor Table์˜ Index ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์žˆ์Œ
      (Segment Descriptor Table์€ ์ปค๋„ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์— ์กด์žฌํ•˜๋ฉฐ, ๊ทธ ์ฃผ์†Œ๋Š” ํŠน์ˆ˜ ๋ ˆ์ง€์Šคํ„ฐ GDTR(Global Descriptor Table Register)์— ์ €์žฅ๋˜์–ด ์žˆ์Œ)
    • ๊ทธ๋ž˜์„œ "Segment Selector"๋ผ๊ณ ๋„ ํ•œ๋‹ค.
  • TEB ์‹œ์ž‘ ์ฃผ์†Œ
    • FS:[0x18] = TEB.NtTib.Self = address of TEB(TIB) = FS:0
    • Self์˜ ์œ„์น˜๊ฐ€ TEB ๊ตฌ์กฐ์ฒด ์‹œ์ž‘์œผ๋กœ๋ถ€ํ„ฐ 018 ์˜ต์…‹ ๋–จ์–ด์ง„ ์œ„์น˜์ž„
    • Self ํฌ์ธํ„ฐ ๋ณ€์ˆ˜: _NT_TIB ๊ตฌ์กฐ์ฒด ์‹œ์ž‘ ์œ„์น˜ = TEB ์‹œ์ž‘ ์œ„์น˜
  • PEB ์‹œ์ž‘ ์ฃผ์†Œ
    • FS:[0x30] = TEB.ProcessEnvironmentBlock = address of PEB
    • ์ฃผ๋กœ ์•ˆํ‹ฐ ๋””๋ฒ„๊น…์—์„œ ๋งŽ์ด ์‚ฌ์šฉ
  • SEH ์‹œ์ž‘ ์ฃผ์†Œ
    • FS:[0] = TEB.NtTib.ExceptionList = address of SEH
    • ์ฃผ๋กœ ์•ˆํ‹ฐ ๋””๋ฒ„๊น…์—์„œ ๋งŽ์ด ์‚ฌ์šฉ
    • ์–ด์…ˆ๋ธ”๋ฆฌ ์ฝ”๋“œ๋กœ ์ ‘๊ทผ
      1)  ๋ฐ”๋กœ PEB ์ฃผ์†Œ ๊ตฌํ•˜๊ธฐ
      mov eax, dword ptr fs:[30]

      2) TEB ์ฃผ์†Œ๋ฅผ ๊ตฌํ•˜๊ณ  ProcessEnvironmentBlock ๋ฉค๋ฒ„(+30 ์˜ต์…‹)๋ฅผ ์ด์šฉ (์ •์„!)
      mov eax, dword ptr fs:[18]
      mov, dword ptr ds:[eax+30]

 

 

 

 

 

 

 

 

 

 

 

 

 

Ref.

[1] ์ด์Šน์›, "๋ฆฌ๋ฒ„์‹ฑ ํ•ต์‹ฌ์›๋ฆฌ"

[2] Learn Microsoft, "EXCEPTION_RECORD (winnt.h)"

[3] Learn Microsoft,  "WOW64_CONTEXT structure  (winnt.h)"

[4] NirSoft, "EXCEPTION_DISPOSITION"

[5] Learn Microsoft,  " TEB structure (winternl.h)"

[6] Learn Microsoft,  "PEB structure (winternl.h)"