Exceptions are an important control flow mechanism used in many modern programming languages. They allow for control flow to be diverted directly to an exception handler, and are generally used for handling error conditions. It is hard to reverse engineer binaries containing exception handling since the control flow transitions are not obvious and hidden behind layers of indirection. While some off-the-shelf reverse engineering frameworks support automated recovery of exception information, this process is generally not well-understood and documentation about this process is spread out over multiple standards and varies between implementations. In this talk, we will approach reverse engineering exceptions from scratch. After a primer on the Intel Itanium C++ ABI, which specifies how language runtimes implement exceptions on different architectures, we will focus on the exception handling data emitted by the compiler. We will show how to parse and understand the call frame information used for unwinding the stack and restoring register state, which will lead to a small journey into DWARF internals. Similarly, we dissect the Language Specific Data Areas (LSDA) encoding not only the locations of exception handlers but also provide information on which exceptions they can handle. Lastly, we will also shine light on the exception handlers themselves, and discuss different calling conventions and assumed architectural state on handler entry. While the main focus of the talk will be on x86_64 ELF binaries, we will briefly highlight the differences in Windows C++ exception handling and Apple’s Compact Unwind information used in Mach-O binaries. To provide practical examples of decoding the exception metadata, we will release and discuss an open-source Binary Ninja plugin applying the techniques discussed in this talk. This plugin decodes and displays the corresponding structures and aims to ease the identification and reverse engineering of exception handlers.