<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Recent changes to StructuredExceptionHandling</title><link>https://sourceforge.net/p/valgrind4win/wiki/StructuredExceptionHandling/</link><description>Recent changes to StructuredExceptionHandling</description><atom:link href="https://sourceforge.net/p/valgrind4win/wiki/StructuredExceptionHandling/feed" rel="self"/><language>en</language><lastBuildDate>Fri, 20 Jul 2012 19:59:48 -0000</lastBuildDate><atom:link href="https://sourceforge.net/p/valgrind4win/wiki/StructuredExceptionHandling/feed" rel="self" type="application/rss+xml"/><item><title>WikiPage StructuredExceptionHandling modified by Jiří Hruška</title><link>https://sourceforge.net/p/valgrind4win/wiki/StructuredExceptionHandling/</link><description>&lt;pre&gt;--- v4
+++ v5
@@ -49,6 +49,7 @@
 * C function: VG_(win_sc_user_exception_dispatch) in coregrind/m_windows/win-fault.c
 
 ### WIN32 ###
+&lt;!--
 |          Original `ntdll!KiUserExceptionDispatcher`              |||                     Hooked `ntdll!KiUserExceptionDispatcher`                    |||
 | Offset | Bytes              | Instructions                         | Offset | Bytes              | Instructions                                        |
 | :----: | :----------------- | :----------------------------------- | :----: | :----------------- | :-------------------------------------------------- |
@@ -79,7 +80,73 @@
 | `0043` | `54              ` | `push    esp                       ` | `0043` | `54              ` | `push    esp                                      ` |
 | `0044` | `e8xxxxxxxx      ` | `call    RtlRaiseException         ` | `0044` | `e8xxxxxxxx      ` | `call    RtlRaiseException                        ` |
 | `0049` | `c20800          ` | `retn    8                         ` | `0049` | `c20800          ` | `retn    8                                        ` |
-
+--&gt;
+&lt;table style="width: 96%"&gt;
+&lt;thead&gt;
+&lt;tr&gt;
+&lt;th style="text-align: center; border-right: 1px solid #ddd"&gt;Original ntdll!KiUserExceptionDispatcher&lt;/td&gt;
+&lt;th style="text-align: center"&gt;Hooked ntdll!KiUserExceptionDispatcher&lt;/td&gt;
+&lt;/tr&gt;
+&lt;/thead&gt;
+&lt;tbody&gt;
+&lt;tr&gt;&lt;td style="vertical-align: top; font: 85% Consolas,'Courier New',monospace; padding: 2px; white-space: pre; border-right: 1px solid #ddd"&gt;0000  8b4c2404          mov     ecx, \[esp+4]
+0004  8b1c24            mov     ebx, \[esp]
+0007  51                push    ecx
+0008  53                push    ebx
+0009  e8xxxxxxxx        call    RtlDispatchException
+000e  0ac0              or      al, al
+0010  740c              je      .001e
+0012  5b                pop     ebx
+0013  59                pop     ecx
+0014  6a00              push    0
+0016  51                push    ecx
+0017  e8xxxxxxxx        call    NtContinue
+001c  eb0b              jmps    .0029
+001e  5b                pop     ebx
+001f  59                pop     ecx
+0020  6a00              push    0
+0022  51                push    ecx
+0023  53                push    ebx
+0024  e8xxxxxxxx        call    NtRaiseException
+0029  83c4ec            add     esp, -0x14
+002c  890424            mov     \[esp], eax
+002f  c744240401000000  mov     dword ptr \[esp+4], 1
+0037  895c2408          mov     \[esp+8], ebx
+003b  c744241000000000  mov     \[esp+0x10], 0
+0043  54                push    esp
+0044  e8xxxxxxxx        call    RtlRaiseException
+0049  c20800            retn    8&lt;/td&gt;
+&lt;td style="vertical-align: top; font: 85% Consolas,'Courier New',monospace; padding: 2px; white-space: pre"&gt;0000  ff15xxxxxxxx      call    d,\[user_exception_dispatcher_ptr\]
+0006  90                nop
+0007  51                push    ecx
+0008  53                push    ebx
+0009  e8xxxxxxxx        call    RtlDispatchException
+000e  0ac0              or      al, al
+0010  740c              je      .001e
+0012  5b                pop     ebx
+0013  59                pop     ecx
+0014  6a00              push    0
+0016  51                push    ecx
+0017  e8xxxxxxxx        call    NtContinue
+001c  eb0b              jmps    .0029
+001e  5b                pop     ebx
+001f  59                pop     ecx
+0020  6a00              push    0
+0022  51                push    ecx
+0023  53                push    ebx
+0024  e8xxxxxxxx        call    NtRaiseException
+0029  83c4ec            add     esp, -0x14
+002c  890424            mov     \[esp], eax
+002f  c744240401000000  mov     dword ptr \[esp+4], 1
+0037  895c2408          mov     \[esp+8], ebx
+003b  c744241000000000  mov     \[esp+0x10], 0
+0043  54                push    esp
+0044  e8xxxxxxxx        call    RtlRaiseException
+0049  c20800            retn    8&lt;/td&gt;&lt;/tr&gt;
+&lt;/tbody&gt;
+&lt;/table&gt;
+
+&lt;!--
 |    Stack layout at the entry time of `KiUserExceptionDispatcher`  ||   Stack layout at the entry time of `VG_(win_sc_user_exception_dispatch)` ||
 |    Address | Content                                               |   Address  | Content                                                       |
 | ---------: | :---------------------------------------------------- | ---------- | ------------------------------------------------------------- |
@@ -91,9 +158,42 @@
 | `   +0x08` | `EXCEPTION_RECORD`                                    | `   +0x14` | `EXCEPTION_RECORD`                                            |
 | `   +0x58` | `CONTEXT`                                             | `   +0x54` | `CONTEXT`                                                     |
 | `   . . .` | . . .                                                 | `   . . .` |                                                               |
+--&gt;
+
+&lt;table style="width: 96%"&gt;
+&lt;thead&gt;
+&lt;tr&gt;
+&lt;th style="text-align: center; border-right: 1px solid #ddd"&gt;Stack layout at the entry time of&lt;br&gt;KiUserExceptionDispatcher&lt;/td&gt;
+&lt;th style="text-align: center"&gt;Stack layout at the entry time of&lt;br&gt;VG_(win_sc_user_exception_dispatch)&lt;/td&gt;
+&lt;/tr&gt;
+&lt;/thead&gt;
+&lt;tbody&gt;
+&lt;tr&gt;&lt;td style="vertical-align: top; font: 85% Consolas,'Courier New',monospace; padding: 2px; white-space: pre; border-right: 1px solid #ddd"&gt;&amp;nbsp;
+&amp;nbsp;
+&amp;nbsp;
+ESP+0x00  EXCEPTION_RECORD* ExceptionRecord
+   +0x04  CONTEXT* ContextRecord
+   +0x08  EXCEPTION_RECORD
+   +0x58  CONTEXT
+    ...   ...&lt;/td&gt;
+&lt;td style="vertical-align: top; font: 85% Consolas,'Courier New',monospace; padding: 2px; white-space: pre"&gt;ESP+0x00  return address (into VG_(catch_user_exception_dispatcher))
+   +0x04  real sizeof(CONTEXT)
+   +0x08  return address (into original KiUserExceptionDispatcher)
+   +0x0c  EXCEPTION_RECORD* ExceptionRecord
+   +0x10  CONTEXT* ContextRecord
+   +0x14  EXCEPTION_RECORD
+   +0x54  CONTEXT
+    ...   ...&lt;/td&gt;&lt;/tr&gt;
+&lt;/tbody&gt;
+&lt;/table&gt;
+
+&amp;nbsp;
+
 
 ### WOW64 ###
+
 The function is exactly the same, except for one "cld" instruction at the start. For safety reasons, the hook call is patched after this instruction (in the end, it makes the hooking code simpler too).
+&lt;!--
 |           Original `ntdll!KiUserExceptionDispatcher`            |||                      Hooked `ntdll!KiUserExceptionDispatcher`                  |||
 | Offset | Bytes             | Instructions                         | Offset | Bytes             | Instructions                                        |
 | :----: | :---------------- | :----------------------------------- | :----: | :---------------- | :-------------------------------------------------- |
@@ -104,56 +204,29 @@
 | `0009` | `53             ` | `push    ebx                       ` | `0009` | `53             ` | `push    ebx                                      ` |
 | `000a` | `e8xxxxxxxx     ` | `call    ntdll!RtlDispatchException` | `000a` | `e8xxxxxxxx     ` | `call    ntdll!RtlDispatchException               ` |
 |  ...   | ...               | ...                                  |  ...   | ...               | ...                                                 |
-
-&lt;table&gt;
+--&gt;
+&lt;table style="width: 96%"&gt;
 &lt;thead&gt;
 &lt;tr&gt;
-&lt;td colspan="3" style="text-align: center; font-weight: bold"&gt;Original &lt;code&gt;ntdll!KiUserExceptionDispatcher&lt;/code&gt;&lt;/td&gt;
-&lt;td colspan="3" style="text-align: center; font-weight: bold"&gt;Hooked &lt;code&gt;ntdll!KiUserExceptionDispatcher&lt;/code&gt;&lt;/td&gt;
-&lt;/tr&gt;
-&lt;tr&gt;
-&lt;th align="center"&gt;Offset&lt;/th&gt;&lt;th align="left"&gt;Bytes&lt;/th&gt;&lt;th align="left"&gt;Instructions&lt;/th&gt;
-&lt;th align="center"&gt;Offset&lt;/th&gt;&lt;th align="left"&gt;Bytes&lt;/th&gt;&lt;th align="left"&gt;Instructions&lt;/th&gt;
+&lt;th style="text-align: center; border-right: 1px solid #ddd"&gt;Original ntdll!KiUserExceptionDispatcher&lt;/td&gt;
+&lt;th style="text-align: center"&gt;Hooked ntdll!KiUserExceptionDispatcher&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
-&lt;tr&gt;&lt;td style="vertical-align: top; font: 80% Consolas,Courier New,monotype"&gt;0000&lt;br&gt;
-0001&lt;br&gt;
-0005&lt;br&gt;
-0008&lt;br&gt;
-0009&lt;br&gt;
-000a&lt;br&gt;
-...&lt;/td&gt;&lt;td style="vertical-align: top; font: 80% Consolas,Courier New,monotype"&gt;fc&lt;br&gt;
-8b4c2404&lt;br&gt;
-8b1c24&lt;br&gt;
-51&lt;br&gt;
-53&lt;br&gt;
-e8xxxxxxxx&lt;br&gt;
-...&lt;/td&gt;&lt;td style="vertical-align: top; font: 80% Consolas,Courier New,monotype"&gt;cld&lt;br&gt;
-mov     ecx, [esp+4]&lt;br&gt;
-mov     ebx, [esp]&lt;br&gt;
-push    ecx&lt;br&gt;
-push    ebx&lt;br&gt;
-call    ntdll!RtlDispatchException&lt;br&gt;
-...&lt;/td&gt;&lt;td style="vertical-align: top; font: 80% Consolas,Courier New,monotype"&gt;0000&lt;br&gt;
-0001&lt;br&gt;
-0007&lt;br&gt;
-0008&lt;br&gt;
-0009&lt;br&gt;
-000a&lt;br&gt;
-...&lt;/td&gt;&lt;td style="vertical-align: top; font: 80% Consolas,Courier New,monotype"&gt;fc&lt;br&gt;
-ff15xxxxxxxx&lt;br&gt;
-90&lt;br&gt;
-51&lt;br&gt;
-53&lt;br&gt;
-e8xxxxxxxx&lt;br&gt;
-...&lt;/td&gt;&lt;td style="vertical-align: top; font: 80% Consolas,Courier New,monotype"&gt;cld&lt;br&gt;
-call    dword ptr [user_exception_dispatcher_ptr]&lt;br&gt;
-nop&lt;br&gt;
-push    ecx&lt;br&gt;
-push    ebx&lt;br&gt;
-call    ntdll!RtlDispatchException&lt;br&gt;
-...&lt;/td&gt;&lt;/tr&gt;
+&lt;tr&gt;&lt;td style="vertical-align: top; font: 85% Consolas,'Courier New',monospace; padding: 2px; white-space: pre; border-right: 1px solid #ddd"&gt;0000  fc          cld
+0001  8b4c2404    mov     ecx, \[esp+4]
+0005  8b1c24      mov     ebx, \[esp]
+0008  51          push    ecx
+0009  53          push    ebx
+000a  e8xxxxxxxx  call    RtlDispatchException
+...   ...         ...&lt;/td&gt;
+&lt;td style="vertical-align: top; font: 85% Consolas,'Courier New',monospace; padding: 2px; white-space: pre"&gt;0000  fc            cld
+0001  ff15xxxxxxxx  call    d,\[user_exception_dispatcher_ptr]
+0007  90            nop
+0008  51            push    ecx
+0009  53            push    ebx
+000a  e8xxxxxxxx    call    RtlDispatchException
+...   ...           ...&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;/table&gt;
 
&lt;/pre&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Jiří Hruška</dc:creator><pubDate>Fri, 20 Jul 2012 19:59:48 -0000</pubDate><guid>https://sourceforge.net3b9e40e6da247fdda1189ee2c8bb291a4008c6ee</guid></item><item><title>WikiPage StructuredExceptionHandling modified by Jiří Hruška</title><link>https://sourceforge.net/p/valgrind4win/wiki/StructuredExceptionHandling/</link><description>&lt;pre&gt;--- v3
+++ v4
@@ -105,5 +105,58 @@
 | `000a` | `e8xxxxxxxx     ` | `call    ntdll!RtlDispatchException` | `000a` | `e8xxxxxxxx     ` | `call    ntdll!RtlDispatchException               ` |
 |  ...   | ...               | ...                                  |  ...   | ...               | ...                                                 |
 
+&lt;table&gt;
+&lt;thead&gt;
+&lt;tr&gt;
+&lt;td colspan="3" style="text-align: center; font-weight: bold"&gt;Original &lt;code&gt;ntdll!KiUserExceptionDispatcher&lt;/code&gt;&lt;/td&gt;
+&lt;td colspan="3" style="text-align: center; font-weight: bold"&gt;Hooked &lt;code&gt;ntdll!KiUserExceptionDispatcher&lt;/code&gt;&lt;/td&gt;
+&lt;/tr&gt;
+&lt;tr&gt;
+&lt;th align="center"&gt;Offset&lt;/th&gt;&lt;th align="left"&gt;Bytes&lt;/th&gt;&lt;th align="left"&gt;Instructions&lt;/th&gt;
+&lt;th align="center"&gt;Offset&lt;/th&gt;&lt;th align="left"&gt;Bytes&lt;/th&gt;&lt;th align="left"&gt;Instructions&lt;/th&gt;
+&lt;/tr&gt;
+&lt;/thead&gt;
+&lt;tbody&gt;
+&lt;tr&gt;&lt;td style="vertical-align: top; font: 80% Consolas,Courier New,monotype"&gt;0000&lt;br&gt;
+0001&lt;br&gt;
+0005&lt;br&gt;
+0008&lt;br&gt;
+0009&lt;br&gt;
+000a&lt;br&gt;
+...&lt;/td&gt;&lt;td style="vertical-align: top; font: 80% Consolas,Courier New,monotype"&gt;fc&lt;br&gt;
+8b4c2404&lt;br&gt;
+8b1c24&lt;br&gt;
+51&lt;br&gt;
+53&lt;br&gt;
+e8xxxxxxxx&lt;br&gt;
+...&lt;/td&gt;&lt;td style="vertical-align: top; font: 80% Consolas,Courier New,monotype"&gt;cld&lt;br&gt;
+mov     ecx, [esp+4]&lt;br&gt;
+mov     ebx, [esp]&lt;br&gt;
+push    ecx&lt;br&gt;
+push    ebx&lt;br&gt;
+call    ntdll!RtlDispatchException&lt;br&gt;
+...&lt;/td&gt;&lt;td style="vertical-align: top; font: 80% Consolas,Courier New,monotype"&gt;0000&lt;br&gt;
+0001&lt;br&gt;
+0007&lt;br&gt;
+0008&lt;br&gt;
+0009&lt;br&gt;
+000a&lt;br&gt;
+...&lt;/td&gt;&lt;td style="vertical-align: top; font: 80% Consolas,Courier New,monotype"&gt;fc&lt;br&gt;
+ff15xxxxxxxx&lt;br&gt;
+90&lt;br&gt;
+51&lt;br&gt;
+53&lt;br&gt;
+e8xxxxxxxx&lt;br&gt;
+...&lt;/td&gt;&lt;td style="vertical-align: top; font: 80% Consolas,Courier New,monotype"&gt;cld&lt;br&gt;
+call    dword ptr [user_exception_dispatcher_ptr]&lt;br&gt;
+nop&lt;br&gt;
+push    ecx&lt;br&gt;
+push    ebx&lt;br&gt;
+call    ntdll!RtlDispatchException&lt;br&gt;
+...&lt;/td&gt;&lt;/tr&gt;
+&lt;/tbody&gt;
+&lt;/table&gt;
+
+
 ### WIN64 ###
 TBD
&lt;/pre&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Jiří Hruška</dc:creator><pubDate>Thu, 19 Jul 2012 01:52:21 -0000</pubDate><guid>https://sourceforge.netaaac2cf0b8eb0ca30b937516215dee691f00a9ca</guid></item><item><title>WikiPage StructuredExceptionHandling modified by Jiří Hruška</title><link>https://sourceforge.net/p/valgrind4win/wiki/StructuredExceptionHandling/</link><description>&lt;pre&gt;--- v2
+++ v3
@@ -49,62 +49,61 @@
 * C function: VG_(win_sc_user_exception_dispatch) in coregrind/m_windows/win-fault.c
 
 ### WIN32 ###
+|          Original `ntdll!KiUserExceptionDispatcher`              |||                     Hooked `ntdll!KiUserExceptionDispatcher`                    |||
+| Offset | Bytes              | Instructions                         | Offset | Bytes              | Instructions                                        |
+| :----: | :----------------- | :----------------------------------- | :----: | :----------------- | :-------------------------------------------------- |
+| `0000` | `8b4c2404        ` | `mov     ecx, [esp+4]              ` | `0000` | `ff15xxxxxxxx    ` | `call    dword ptr [user_exception_dispatcher_ptr]` |
+| `0004` | `8b1c24          ` | `mov     ebx, [esp]                ` | `0006` | `90              ` | `nop                                              ` |
+| `0007` | `51              ` | `push    ecx                       ` | `0007` | `51              ` | `push    ecx                                      ` |
+| `0008` | `53              ` | `push    ebx                       ` | `0008` | `53              ` | `push    ebx                                      ` |
+| `0009` | `e8xxxxxxxx      ` | `call    ntdll!RtlDispatchException` | `0009` | `e8xxxxxxxx      ` | `call    ntdll!RtlDispatchException               ` |
+| `000e` | `0ac0            ` | `or      al, al                    ` | `000e` | `0ac0            ` | `or      al, al                                   ` |
+| `0010` | `740c            ` | `je      .001e                     ` | `0010` | `740c            ` | `je      .001e                                    ` |
+| `0012` | `5b              ` | `pop     ebx                       ` | `0012` | `5b              ` | `pop     ebx                                      ` |
+| `0013` | `59              ` | `pop     ecx                       ` | `0013` | `59              ` | `pop     ecx                                      ` |
+| `0014` | `6a00            ` | `push    0                         ` | `0014` | `6a00            ` | `push    0                                        ` |
+| `0016` | `51              ` | `push    ecx                       ` | `0016` | `51              ` | `push    ecx                                      ` |
+| `0017` | `e8xxxxxxxx      ` | `call    ntdll!NtContinue          ` | `0017` | `e8xxxxxxxx      ` | `call    ntdll!NtContinue                         ` |
+| `001c` | `eb0b            ` | `jmps    .0029                     ` | `001c` | `eb0b            ` | `jmps    .0029                                    ` |
+| `001e` | `5b              ` | `pop     ebx                       ` | `001e` | `5b              ` | `pop     ebx                                      ` |
+| `001f` | `59              ` | `pop     ecx                       ` | `001f` | `59              ` | `pop     ecx                                      ` |
+| `0020` | `6a00            ` | `push    0                         ` | `0020` | `6a00            ` | `push    0                                        ` |
+| `0022` | `51              ` | `push    ecx                       ` | `0022` | `51              ` | `push    ecx                                      ` |
+| `0023` | `53              ` | `push    ebx                       ` | `0023` | `53              ` | `push    ebx                                      ` |
+| `0024` | `e8xxxxxxxx      ` | `call    ntdll!NtRaiseException    ` | `0024` | `e8xxxxxxxx      ` | `call    ntdll!NtRaiseException                   ` |
+| `0029` | `83c4ec          ` | `add     esp, -0x14                ` | `0029` | `83c4ec          ` | `add     esp, -0x14                               ` |
+| `002c` | `890424          ` | `mov     [esp], eax                ` | `002c` | `890424          ` | `mov     [esp], eax                               ` |
+| `002f` | `c744240401000000` | `mov     dword ptr [esp+4], 1      ` | `002f` | `c744240401000000` | `mov     dword ptr [esp+4], 1                     ` |
+| `0037` | `895c2408        ` | `mov     [esp+8], ebx              ` | `0037` | `895c2408        ` | `mov     [esp+8], ebx                             ` |
+| `003b` | `c744241000000000` | `mov     [esp+0x10], 0             ` | `003b` | `c744241000000000` | `mov     [esp+0x10], 0                            ` |
+| `0043` | `54              ` | `push    esp                       ` | `0043` | `54              ` | `push    esp                                      ` |
+| `0044` | `e8xxxxxxxx      ` | `call    RtlRaiseException         ` | `0044` | `e8xxxxxxxx      ` | `call    RtlRaiseException                        ` |
+| `0049` | `c20800          ` | `retn    8                         ` | `0049` | `c20800          ` | `retn    8                                        ` |
 
-|          Original ntdll!KiUserExceptionDispatcher            |||                     Hooked ntdll!KiUserExceptionDispatcher                  |||
-| Offset | Bytes            | Instructions                       | Offset | Bytes            | Instructions                                      |
-| ------ | ---------------- | ---------------------------------- | ------ | ---------------- | ------------------------------------------------- |
-|  0000  | 8b4c2404         | mov     ecx, [esp+4]               |  0000  | ff15xxxxxxxx     | call    dword ptr [user_exception_dispatcher_ptr] |
-|  0004  | 8b1c24           | mov     ebx, [esp]                 |  0006  | 90               | nop                                               |
-|  0007  | 51               | push    ecx                        |  0007  | 51               | push    ecx                                       |
-|  0008  | 53               | push    ebx                        |  0008  | 53               | push    ebx                                       |
-|  0009  | e8xxxxxxxx       | call    ntdll!RtlDispatchException |  0009  | e8xxxxxxxx       | call    ntdll!RtlDispatchException                |
-|  000e  | 0ac0             | or      al, al                     |  000e  | 0ac0             | or      al, al                                    |
-|  0010  | 740c             | je      .001e                      |  0010  | 740c             | je      .001e                                     |
-|  0012  | 5b               | pop     ebx                        |  0012  | 5b               | pop     ebx                                       |
-|  0013  | 59               | pop     ecx                        |  0013  | 59               | pop     ecx                                       |
-|  0014  | 6a00             | push    0                          |  0014  | 6a00             | push    0                                         |
-|  0016  | 51               | push    ecx                        |  0016  | 51               | push    ecx                                       |
-|  0017  | e8xxxxxxxx       | call    ntdll!NtContinue           |  0017  | e8xxxxxxxx       | call    ntdll!NtContinue                          |
-|  001c  | eb0b             | jmps    .0029                      |  001c  | eb0b             | jmps    .0029                                     |
-|  001e  | 5b               | pop     ebx                        |  001e  | 5b               | pop     ebx                                       |
-|  001f  | 59               | pop     ecx                        |  001f  | 59               | pop     ecx                                       |
-|  0020  | 6a00             | push    0                          |  0020  | 6a00             | push    0                                         |
-|  0022  | 51               | push    ecx                        |  0022  | 51               | push    ecx                                       |
-|  0023  | 53               | push    ebx                        |  0023  | 53               | push    ebx                                       |
-|  0024  | e8xxxxxxxx       | call    ntdll!NtRaiseException     |  0024  | e8xxxxxxxx       | call    ntdll!NtRaiseException                    |
-|  0029  | 83c4ec           | add     esp, -0x14                 |  0029  | 83c4ec           | add     esp, -0x14                                |
-|  002c  | 890424           | mov     [esp], eax                 |  002c  | 890424           | mov     [esp], eax                                |
-|  002f  | c744240401000000 | mov     dword ptr [esp+4], 1       |  002f  | c744240401000000 | mov     dword ptr [esp+4], 1                      |
-|  0037  | 895c2408         | mov     [esp+8], ebx               |  0037  | 895c2408         | mov     [esp+8], ebx                              |
-|  003b  | c744241000000000 | mov     [esp+0x10], 0              |  003b  | c744241000000000 | mov     [esp+0x10], 0                             |
-|  0043  | 54               | push    esp                        |  0043  | 54               | push    esp                                       |
-|  0044  | e8xxxxxxxx       | call    RtlRaiseException          |  0044  | e8xxxxxxxx       | call    RtlRaiseException                         |
-|  0049  | c20800           | retn    8                          |  0049  | c20800           | retn    8                                         |
-
-|   Stack layout at the entry time of KiUserExceptionDispatcher || Stack layout at the entry time of VG_(win_sc_user_exception_dispatch)   ||
-| Address  | Content                                             | Address  | Content                                                       |
-| -------- | --------------------------------------------------- | -------- | ------------------------------------------------------------- |
-|          |                                                     | ESP+0x00 | return address (into `VG_(catch_user_exception_dispatcher)`)  |
-|          |                                                     |    +0x04 | real sizeof(CONTEXT)                                          |
-|          |                                                     |    +0x08 |      return address (into original KiUserExceptionDispatcher) |
-| ESP+0x00 | EXCEPTION_RECORD* ExceptionRecord                   |    +0x0c | EXCEPTION_RECORD* ExceptionRecord                             |
-|    +0x04 | CONTEXT* ContextRecord                              |    +0x10 | CONTEXT* ContextRecord                                        |
-|    +0x08 | EXCEPTION_RECORD                                    |    +0x14 | EXCEPTION_RECORD                                              |
-|    +0x58 | CONTEXT                                             |    +0x54 | CONTEXT                                                       |
-|    . . . |                                                     |    . . . |                                                               |
+|    Stack layout at the entry time of `KiUserExceptionDispatcher`  ||   Stack layout at the entry time of `VG_(win_sc_user_exception_dispatch)` ||
+|    Address | Content                                               |   Address  | Content                                                       |
+| ---------: | :---------------------------------------------------- | ---------- | ------------------------------------------------------------- |
+|            |                                                       | `ESP+0x00` | return address (into `VG_(catch_user_exception_dispatcher)`)  |
+|            |                                                       | `   +0x04` | real `sizeof(CONTEXT)`                                        |
+|            |                                                       | `   +0x08` | return address (into original `KiUserExceptionDispatcher`)    |
+| `ESP+0x00` | `EXCEPTION_RECORD* ExceptionRecord`                   | `   +0x0c` | `EXCEPTION_RECORD* ExceptionRecord`                           |
+| `   +0x04` | `CONTEXT* ContextRecord`                              | `   +0x10` | `CONTEXT* ContextRecord`                                      |
+| `   +0x08` | `EXCEPTION_RECORD`                                    | `   +0x14` | `EXCEPTION_RECORD`                                            |
+| `   +0x58` | `CONTEXT`                                             | `   +0x54` | `CONTEXT`                                                     |
+| `   . . .` | . . .                                                 | `   . . .` |                                                               |
 
 ### WOW64 ###
 The function is exactly the same, except for one "cld" instruction at the start. For safety reasons, the hook call is patched after this instruction (in the end, it makes the hooking code simpler too).
-|          Original ntdll!KiUserExceptionDispatcher            |||                     Hooked ntdll!KiUserExceptionDispatcher                  |||
-| Offset | Bytes            | Instructions                       | Offset | Bytes            | Instructions                                      |
-| ------ | ---------------- | ---------------------------------- | ------ | ---------------- | ------------------------------------------------- |
-|  0000  | fc               | cld                                |  0000  | fc               | cld                                               |
-|  0001  | 8b4c2404         | mov     ecx, [esp+4]               |  0001  | ff15xxxxxxxx     | call    dword ptr [user_exception_dispatcher_ptr] |
-|  0005  | 8b1c24           | mov     ebx, [esp]                 |  0007  | 90               | nop                                               |
-|  0008  | 51               | push    ecx                        |  0008  | 51               | push    ecx                                       |
-|  0009  | 53               | push    ebx                        |  0009  | 53               | push    ebx                                       |
-|  000a  | e8xxxxxxxx       | call    ntdll!RtlDispatchException |  000a  | e8xxxxxxxx       | call    ntdll!RtlDispatchException                |
-|  ...   | ...              | ...                                |  ...   | ...              | ...                                               |
+|           Original `ntdll!KiUserExceptionDispatcher`            |||                      Hooked `ntdll!KiUserExceptionDispatcher`                  |||
+| Offset | Bytes             | Instructions                         | Offset | Bytes             | Instructions                                        |
+| :----: | :---------------- | :----------------------------------- | :----: | :---------------- | :-------------------------------------------------- |
+| `0000` | `fc             ` | `cld                               ` | `0000` | `fc             ` | `cld                                              ` |
+| `0001` | `8b4c2404       ` | `mov     ecx, [esp+4]              ` | `0001` | `ff15xxxxxxxx   ` | `call    dword ptr [user_exception_dispatcher_ptr]` |
+| `0005` | `8b1c24         ` | `mov     ebx, [esp]                ` | `0007` | `90             ` | `nop                                              ` |
+| `0008` | `51             ` | `push    ecx                       ` | `0008` | `51             ` | `push    ecx                                      ` |
+| `0009` | `53             ` | `push    ebx                       ` | `0009` | `53             ` | `push    ebx                                      ` |
+| `000a` | `e8xxxxxxxx     ` | `call    ntdll!RtlDispatchException` | `000a` | `e8xxxxxxxx     ` | `call    ntdll!RtlDispatchException               ` |
+|  ...   | ...               | ...                                  |  ...   | ...               | ...                                                 |
 
 ### WIN64 ###
 TBD
&lt;/pre&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Jiří Hruška</dc:creator><pubDate>Thu, 19 Jul 2012 01:16:45 -0000</pubDate><guid>https://sourceforge.netff4cbafbe3b656e4d7ef3bbfb46b8a28b79c4ee5</guid></item><item><title>WikiPage StructuredExceptionHandling modified by Jiří Hruška</title><link>https://sourceforge.net/p/valgrind4win/wiki/StructuredExceptionHandling/</link><description>&lt;pre&gt;--- v1
+++ v2
@@ -1,8 +1,110 @@
 ## Structured Exception Handling ##
-In order to catch unhanded exceptions, an unhanded exception filter must be registered using SetUnhandledExceptionFilter(). To get back from any guest code being executed, the Valgrind's usual longjmp back to scheduler is used. This allows it to process the exception like it does with fatal signals under UNIX.
 
-VG_(win_set_seh)(NULL) sets the default V exception handler and is called from guest win-main.c. It will probably have to be reinstated again during user callbacks, as they are known to eat any exceptions, even access violations etc., which Valgrind should help to catch.
 
-The syscall stack needed to be changed due to longjmp being used now.
+## Exception handling on Win32/WOW64 ##
 
-Testing: memcheck/tests/windows/hello_no_crt.exe with its deliberate access to a NULL pointer.
+The following diagram shows a high-level picture how exceptions work on 32-bit Windows:
+[[img src="seh-win32.png" alt="SEH on Win32/WOW64"]]
+
+### Hardware exceptions in client code ###
+If something bad happens, e.g. an invalid memory access, the hardware exception is caught by the kernel, which resumes user level execution in `ntdll!KiUserExceptionDispatcher`. This function is hooked by Valgrind, so the exception can be analyzed etc. The rest of the dispatcher is then ran on the emulated CPU (necessary mostly because `RtlDispatchException()` can call application code), which is done by longjumping back to the scheduler with updated `EIP` and stack.
+
+Then, if a viable exception handler has been found, `NtContinue` syscall is issued and caught by Valgrind, which copies the updated context values to the VEX context structures and executes the syscall with a dummy `CONTEXT` structure in order to call it, but effectively just return to the syscall PRE-wrapper, which sets `SsComplere` and `SfDontWriteResult` and the scheduler resumes at the updated location.
+
+If no useful exception handler could be found, the syscall issued is `NtRaiseException`, with the `FirstChance` argument set to `FALSE`. This is intercepted by Valgrind and the process is terminated, as that would happen if the syscall was passed to the kernel anyway. (To be precise, `UnhandledExceptionFilter` would be called. Maybe we should call it too if the application uses its own routine?)
+
+### Software exceptions in client code ###
+The client code can call `RaiseException()` to throw an exception at any time. This is used by MSVS C++ exceptions, internally by `OutputDebugString()` etc. In this case, the process is exactly the same, except the exception does not originate from generated code but by stopping emulation and calling a syscall `NtRaiseException`.
+
+The syscall is let through, so after kernel does its job, the execution gets to the hooked `KiUserExceptionDispatcher` again.
+
+### Exceptions in Valgrind/tool code ###
+Although Valgrind itself does not use exceptions and will not throw any through the `RaiseException()` API, there is a possibility of crash in V/tool code because of bugs. Such exceptions will take the same route as hardware exceptions originating from client code, with the difference that `VG_(in_generated_code)` will be false in the `KiUserExceptionDispatcher` hook. So this case can be easily discerned and a helpful report about bug in Valgrind shown to the user instead. Then the process is terminated.
+
+`SetUnhandledExceptionFilter()` is also called early during startup to catch similarly any problems during initialization.
+
+### Valgrind's handling of Win32/WOW64 exceptions ###
+[[img src="seh-win32-v.png" alt="Valgrind's SEH processing on Win32/WOW64"]]
+
+
+## Exception handling on Win64 ##
+TBD
+
+
+## Hooks ##
+There are two entry points in ntdll.dll, which the kernel uses when dealing with exceptions -- `KiUserExceptionDispatcher` and `KiRaiseUserExceptionDispatcher`. The latter is used only when kernel wants to raise an exception and essentially just calls `RtlRaiseException()`, which is not very interesting. `KiUserExceptionDispatcher` is much more useful, as it is the function called when an exception has occurred and needs to be handled.
+
+This section describes how Valgrind for Windows intercepts `KiUserExceptionDispatcher`. In general:
+
+* Valgrind modifies (overwrites a part of) the `ntdll!!KiUserExceptionDispatcher` code to call an assembler stub.
+* The assembler stub calls a C function for further handling with all necessary information passed in its arguments.
+* The C function
+    * for first-chance exceptions from client code: sets up the client state and transfers control to the virtual CPU in order to dispatch the exception,
+    * for second-chance exceptions and those originating from Valgrind itself: prints some helpful messages and terminates.
+ 
+Related files:
+
+* assembler stub (WIN32/WOW64): VGASM_(catch_user_exception_dispatcher) in coregrind/m_syswrap/syscall-x86-windows.S
+* assembler stub (WIN64): VGASM_(catch_user_exception_dispatcher) in coregrind/m_syswrap/syscall-amd64-windows.S
+* C function: VG_(win_sc_user_exception_dispatch) in coregrind/m_windows/win-fault.c
+
+### WIN32 ###
+
+|          Original ntdll!KiUserExceptionDispatcher            |||                     Hooked ntdll!KiUserExceptionDispatcher                  |||
+| Offset | Bytes            | Instructions                       | Offset | Bytes            | Instructions                                      |
+| ------ | ---------------- | ---------------------------------- | ------ | ---------------- | ------------------------------------------------- |
+|  0000  | 8b4c2404         | mov     ecx, [esp+4]               |  0000  | ff15xxxxxxxx     | call    dword ptr [user_exception_dispatcher_ptr] |
+|  0004  | 8b1c24           | mov     ebx, [esp]                 |  0006  | 90               | nop                                               |
+|  0007  | 51               | push    ecx                        |  0007  | 51               | push    ecx                                       |
+|  0008  | 53               | push    ebx                        |  0008  | 53               | push    ebx                                       |
+|  0009  | e8xxxxxxxx       | call    ntdll!RtlDispatchException |  0009  | e8xxxxxxxx       | call    ntdll!RtlDispatchException                |
+|  000e  | 0ac0             | or      al, al                     |  000e  | 0ac0             | or      al, al                                    |
+|  0010  | 740c             | je      .001e                      |  0010  | 740c             | je      .001e                                     |
+|  0012  | 5b               | pop     ebx                        |  0012  | 5b               | pop     ebx                                       |
+|  0013  | 59               | pop     ecx                        |  0013  | 59               | pop     ecx                                       |
+|  0014  | 6a00             | push    0                          |  0014  | 6a00             | push    0                                         |
+|  0016  | 51               | push    ecx                        |  0016  | 51               | push    ecx                                       |
+|  0017  | e8xxxxxxxx       | call    ntdll!NtContinue           |  0017  | e8xxxxxxxx       | call    ntdll!NtContinue                          |
+|  001c  | eb0b             | jmps    .0029                      |  001c  | eb0b             | jmps    .0029                                     |
+|  001e  | 5b               | pop     ebx                        |  001e  | 5b               | pop     ebx                                       |
+|  001f  | 59               | pop     ecx                        |  001f  | 59               | pop     ecx                                       |
+|  0020  | 6a00             | push    0                          |  0020  | 6a00             | push    0                                         |
+|  0022  | 51               | push    ecx                        |  0022  | 51               | push    ecx                                       |
+|  0023  | 53               | push    ebx                        |  0023  | 53               | push    ebx                                       |
+|  0024  | e8xxxxxxxx       | call    ntdll!NtRaiseException     |  0024  | e8xxxxxxxx       | call    ntdll!NtRaiseException                    |
+|  0029  | 83c4ec           | add     esp, -0x14                 |  0029  | 83c4ec           | add     esp, -0x14                                |
+|  002c  | 890424           | mov     [esp], eax                 |  002c  | 890424           | mov     [esp], eax                                |
+|  002f  | c744240401000000 | mov     dword ptr [esp+4], 1       |  002f  | c744240401000000 | mov     dword ptr [esp+4], 1                      |
+|  0037  | 895c2408         | mov     [esp+8], ebx               |  0037  | 895c2408         | mov     [esp+8], ebx                              |
+|  003b  | c744241000000000 | mov     [esp+0x10], 0              |  003b  | c744241000000000 | mov     [esp+0x10], 0                             |
+|  0043  | 54               | push    esp                        |  0043  | 54               | push    esp                                       |
+|  0044  | e8xxxxxxxx       | call    RtlRaiseException          |  0044  | e8xxxxxxxx       | call    RtlRaiseException                         |
+|  0049  | c20800           | retn    8                          |  0049  | c20800           | retn    8                                         |
+
+|   Stack layout at the entry time of KiUserExceptionDispatcher || Stack layout at the entry time of VG_(win_sc_user_exception_dispatch)   ||
+| Address  | Content                                             | Address  | Content                                                       |
+| -------- | --------------------------------------------------- | -------- | ------------------------------------------------------------- |
+|          |                                                     | ESP+0x00 | return address (into `VG_(catch_user_exception_dispatcher)`)  |
+|          |                                                     |    +0x04 | real sizeof(CONTEXT)                                          |
+|          |                                                     |    +0x08 |      return address (into original KiUserExceptionDispatcher) |
+| ESP+0x00 | EXCEPTION_RECORD* ExceptionRecord                   |    +0x0c | EXCEPTION_RECORD* ExceptionRecord                             |
+|    +0x04 | CONTEXT* ContextRecord                              |    +0x10 | CONTEXT* ContextRecord                                        |
+|    +0x08 | EXCEPTION_RECORD                                    |    +0x14 | EXCEPTION_RECORD                                              |
+|    +0x58 | CONTEXT                                             |    +0x54 | CONTEXT                                                       |
+|    . . . |                                                     |    . . . |                                                               |
+
+### WOW64 ###
+The function is exactly the same, except for one "cld" instruction at the start. For safety reasons, the hook call is patched after this instruction (in the end, it makes the hooking code simpler too).
+|          Original ntdll!KiUserExceptionDispatcher            |||                     Hooked ntdll!KiUserExceptionDispatcher                  |||
+| Offset | Bytes            | Instructions                       | Offset | Bytes            | Instructions                                      |
+| ------ | ---------------- | ---------------------------------- | ------ | ---------------- | ------------------------------------------------- |
+|  0000  | fc               | cld                                |  0000  | fc               | cld                                               |
+|  0001  | 8b4c2404         | mov     ecx, [esp+4]               |  0001  | ff15xxxxxxxx     | call    dword ptr [user_exception_dispatcher_ptr] |
+|  0005  | 8b1c24           | mov     ebx, [esp]                 |  0007  | 90               | nop                                               |
+|  0008  | 51               | push    ecx                        |  0008  | 51               | push    ecx                                       |
+|  0009  | 53               | push    ebx                        |  0009  | 53               | push    ebx                                       |
+|  000a  | e8xxxxxxxx       | call    ntdll!RtlDispatchException |  000a  | e8xxxxxxxx       | call    ntdll!RtlDispatchException                |
+|  ...   | ...              | ...                                |  ...   | ...              | ...                                               |
+
+### WIN64 ###
+TBD
&lt;/pre&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Jiří Hruška</dc:creator><pubDate>Thu, 19 Jul 2012 01:09:10 -0000</pubDate><guid>https://sourceforge.net161261c697c31129e51548dd732bc1d7853a5229</guid></item><item><title>WikiPage StructuredExceptionHandling modified by Christoph Schwarz</title><link>https://sourceforge.net/p/valgrind4win/wiki/StructuredExceptionHandling/</link><description>## Structured Exception Handling ##
In order to catch unhanded exceptions, an unhanded exception filter must be registered using SetUnhandledExceptionFilter(). To get back from any guest code being executed, the Valgrind's usual longjmp back to scheduler is used. This allows it to process the exception like it does with fatal signals under UNIX.

VG_(win_set_seh)(NULL) sets the default V exception handler and is called from guest win-main.c. It will probably have to be reinstated again during user callbacks, as they are known to eat any exceptions, even access violations etc., which Valgrind should help to catch.

The syscall stack needed to be changed due to longjmp being used now.

Testing: memcheck/tests/windows/hello_no_crt.exe with its deliberate access to a NULL pointer.
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Christoph Schwarz</dc:creator><pubDate>Fri, 13 Jul 2012 00:12:51 -0000</pubDate><guid>https://sourceforge.net180ccc5ba869d623049e6032103505fa5d361da3</guid></item></channel></rss>