-
Notifications
You must be signed in to change notification settings - Fork 1
/
SEH.html
92 lines (86 loc) · 9.99 KB
/
SEH.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<!DOCTYPE html>
<html>
<head>
<title>TITLE</title>
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="highlight/styles/stackoverflow-dark.min.css">
<script src="highlight/highlight.min.js"></script>
<script>hljs.highlightAll();</script>
</head>
<body>
<div class="inner-content"><header class="page-header"><h1 class="page-title">Structured Exception Handling (SEH)</h1></header><div class="page-content"><p>The <span style="color: #00ccff;">exception handlers</span> are organized in a <span style="color: #00ccff;">singly-linked list</span> associated with each thread. As a rule, the nodes of that list are allocated on the stack.<br> The head of the list is pointed to by a pointer located at the beginning of the <span style="color: #00ccff;">TEB</span> (<span style="color: #00ccff;">T</span>hread <span style="color: #00ccff;">E</span>nvironment <span style="color: #00ccff;">B</span>lock), so when the code wants to add a new exception handler, a new node is added to the head of the list and the pointer in the <span style="color: #00ccff;">TEB</span> is changed to point to the new node.<br> Each node is of type <span style="color: #00ff00;">_EXCEPTION_REGISTRATION_RECORD</span> and stores the address of the handler and a pointer to the next node of the list. Oddly enough, the “<span style="color: #00ff00;">next pointer</span>” of the last node of the list is not null but equal to <span style="color: #00ff00;">0xffffffff</span>. Here’s the exact definition:</p><pre class="ignore:true">0:000> dt _EXCEPTION_REGISTRATION_RECORD
ntdll!_EXCEPTION_REGISTRATION_RECORD
+0x000 Next : Ptr32 _EXCEPTION_REGISTRATION_RECORD
+0x004 Handler : Ptr32 _EXCEPTION_DISPOSITION</pre><p>The <span style="color: #00ccff;">TEB</span> can also be accessed through the <span style="color: #00ccff;">selector</span> <span style="color: #00ff00;">fs</span>, starting from <span style="color: #00ff00;">fs:[0]</span>, so it’s common to see code like the following:</p>
<pre><code class="language-x86asm">mov eax, dword ptr fs:[00000000h] ; retrieve the head
push eax ; save the old head
lea eax, [ebp-10h]
mov dword ptr fs:[00000000h], eax ; set the new head
.
.
.
mov ecx, dword ptr [ebp-10h] ; get the old head (NEXT field of the current head)
mov dword ptr fs:[00000000h], ecx ; restore the old head</code></pre>
<p>Compilers usually register a single <span style="color: #00ccff;">global handler</span> that knows which area of the program is being executed (relying on a global variable) and behaves accordingly when it’s called.<br> Since each thread has a different <span style="color: #00ccff;">TEB</span>, the operating system makes sure that the segment selected by <span style="color: #00ff00;">fs</span> refers always to the right <span style="color: #00ccff;">TEB</span> (i.e. the one of the current thread). To get the address of the <span style="color: #00ccff;">TEB</span>, read <span style="color: #00ff00;">fs:[18h]</span> which corresponds to the field <span style="color: #00ff00;">Self</span> of the <span style="color: #00ccff;">TEB</span>.</p><p>Let’s display the <span style="color: #00ccff;">TEB</span>:</p><pre class="ignore:true">0:000> !teb
TEB at 7efdd000
ExceptionList: 003ef804 <-----------------------
StackBase: 003f0000
StackLimit: 003ed000
SubSystemTib: 00000000
FiberData: 00001e00
ArbitraryUserPointer: 00000000
Self: 7efdd000
EnvironmentPointer: 00000000
ClientId: 00001644 . 00000914
RpcHandle: 00000000
Tls Storage: 7efdd02c
PEB Address: 7efde000
LastErrorValue: 2
LastStatusValue: c0000034
Count Owned Locks: 0
HardErrorMode: 0</pre><p>Now let’s verify that <span style="color: #00ff00;">fs</span> refers to the <span style="color: #00ccff;">TEB</span>:</p><pre class="ignore:true">0:000> dg fs
P Si Gr Pr Lo
Sel Base Limit Type l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
0053 7efdd000 00000fff Data RW Ac 3 Bg By P Nl 000004f3</pre><p>As we said above, <span style="color: #00ff00;">fs:18h</span> contains the address of the <span style="color: #00ccff;">TEB</span>:</p><pre class="ignore:true">0:000> ? poi(fs:[18])
Evaluate expression: 2130563072 = 7efdd000</pre><p>Remember that <span style="color: #00ff00;">poi</span> dereferences a pointer and ‘<span style="color: #00ff00;">?</span>‘ is used to evaluate an expression.</p><p>Let’s see what’s the name of the structure pointed to by <span style="color: #00ff00;">ExceptionList</span> above:</p><pre class="ignore:true">0:000> dt nt!_NT_TIB ExceptionList
ntdll!_NT_TIB
+0x000 ExceptionList : Ptr32 _EXCEPTION_REGISTRATION_RECORD</pre><p>This means that each node is an instance of <span style="color: #00ff00;">_EXCEPTION_REGISTRATION_RECORD</span>, as we already said.<br> To display the entire list, use <span style="color: #00ff00;">!slist</span>:</p><pre class="ignore:true">0:000> !slist $teb _EXCEPTION_REGISTRATION_RECORD
SLIST HEADER:
+0x000 Alignment : 3f0000003ef804
+0x000 Next : 3ef804
+0x004 Depth : 0
+0x006 Sequence : 3f
SLIST CONTENTS:
003ef804
+0x000 Next : 0x003ef850 _EXCEPTION_REGISTRATION_RECORD
+0x004 Handler : 0x6d5da0d5 _EXCEPTION_DISPOSITION MSVCR120!_except_handler4+0
003ef850
+0x000 Next : 0x003ef89c _EXCEPTION_REGISTRATION_RECORD
+0x004 Handler : 0x00271709 _EXCEPTION_DISPOSITION +0
003ef89c
+0x000 Next : 0xffffffff _EXCEPTION_REGISTRATION_RECORD
+0x004 Handler : 0x77e21985 _EXCEPTION_DISPOSITION ntdll!_except_handler4+0
ffffffff
+0x000 Next : ????
+0x004 Handler : ????
Can't read memory at ffffffff, error 0</pre><p>Remember that <span style="color: #00ff00;">$teb</span> is the address of the <span style="color: #00ccff;">TEB</span>.</p><p>A simpler way to display the exception handler chain is to use</p><pre class="ignore:true">0:000> !exchain
003ef804: MSVCR120!_except_handler4+0 (6d5da0d5)
CRT scope 0, func: MSVCR120!doexit+116 (6d613b3b)
003ef850: exploitme3+1709 (00271709)
003ef89c: ntdll!_except_handler4+0 (77e21985)
CRT scope 0, filter: ntdll!__RtlUserThreadStart+2e (77e21c78)
func: ntdll!__RtlUserThreadStart+63 (77e238cb)</pre><p>We can also examine the exception handler chain manually:</p><pre class="ignore:true ">0:000> dt 003ef804 _EXCEPTION_REGISTRATION_RECORD
MSVCR120!_EXCEPTION_REGISTRATION_RECORD
+0x000 Next : 0x003ef850 _EXCEPTION_REGISTRATION_RECORD
+0x004 Handler : 0x6d5da0d5 _EXCEPTION_DISPOSITION MSVCR120!_except_handler4+0
0:000> dt 0x003ef850 _EXCEPTION_REGISTRATION_RECORD
MSVCR120!_EXCEPTION_REGISTRATION_RECORD
+0x000 Next : 0x003ef89c _EXCEPTION_REGISTRATION_RECORD
+0x004 Handler : 0x00271709 _EXCEPTION_DISPOSITION +0
0:000> dt 0x003ef89c _EXCEPTION_REGISTRATION_RECORD
MSVCR120!_EXCEPTION_REGISTRATION_RECORD
+0x000 Next : 0xffffffff _EXCEPTION_REGISTRATION_RECORD
+0x004 Handler : 0x77e21985 _EXCEPTION_DISPOSITION ntdll!_except_handler4+0</pre> </div></div>
</body>
</html>