# Through the Window: Exploitation and Countermeasures of the ESP32 Register Window Overflow +
## 4 Exploiting the Window-Overflow Exception Handler  
This register window mechanism is not a security problem itself. The vulnerability comes from the specific implementation of the window exception handlers and the way that register values are saved. For each function call, there are pre-allocated memory areas in the stack. There are two types of areas allocated for each stack frame, namely the Base Save Area (BSA) and the Extra Save Area (ESA). The BSA has a fixed size of 16 bytes, containing values for registers a0-a3. These registers represent the minimal number of registers that move out of the current window. Any potential additional registers are stored in the ESA. The size of an ESA can therefore vary, from 0 bytes up to 32 bytes. The position of these memory areas is critical too. Figure 3 shows the stack for a scenario where the registers of a function call \(i\) are about to be saved onto the stack by an overflow exception. It shows a total of three stack frames--Frame \(i-1\), Frame \(i\), and Frame \(i+1\)--as well as save areas that are relevant for exception handling. Other parts of the stack frames, including ESAs other than ESA \(i\) are only represented by \"...\" for simplicity. The placement of ESA \(i\) is straight forward. It is placed at the highest address of Frame \(i\). Its size depends on the call instructions used inside the function body. This way, the compiler can determine how much space to allocate for the ESA. The BSA \(i\), on the other hand, is in Frame \(i+1\). This is used to be able to backtrack the stack, as the BSA contains register a1, which acts as the stack pointer. When an overflow occurs, the window is rotated to a position where the stack pointers for Frame \(i\) and \(i+1\) are in the register window. For example, during an overflow of eight, Stack Pointer \(i+1\) is in register a9, and Stack Pointer \(i\) is in register a1. The BSA is located at the lowest address part of a stack frame, right below the stack pointer. This allows it to have a fixed offset to the register values in the BSA. Finding the position of ESA \(i\) is a little more complicated. Since stack frame sizes can differ, the offset of ESA \(i\) in relation to Stack Pointer \(i\) is unknown for the exception handler. To reach it, it uses Stack Pointer \(i-1\), which is stored in BSA \(i-1\). Since the size of a BSA is constant, it is possible to address the values in ESA \(i\) using Stack Pointer \(i-1\) with constant offsets. Since BSA \(i-1\) was already written to the stack by a previous window-overflow exception, this is the part where an attacker can use a stack buffer overflow to alter the  
Figure 3: Stack layout and relevant pointers used during a window-overflow exception to save registers into BSA \(i\) and ESA \(i\), including Stack Pointer \(i-1\), which is loaded from the stack and can be manipulated by an attacker to point to an Area of Interest (AoI). Figure 2: Example of two overlapping register windows \(W_{A}\) and \(W_{B}\). value of Stack Pointer \(i-1\), illustrated in Figure 3 by the red arrow. This moves the position of the ESA to any position the attacker chooses, here named the Area of Interest (AoI). This area could contain sensible data that the attacker wants to overwrite, or maybe is used for memory-mapped registers, which would allow the attacker to change the configuration of the IoT device. Another possibility is to target an output buffer to leak the saved register values. For the attack to work, there are few more requirements than just a simple stack buffer overflow vulnerability. This is illustrated in a simple example in Listing 1. The shown function _vulnerable_first copies the _input_ into a local _buffer_. For an attack that targets the return address, this would already be enough. However, widely used defense mechanisms such as Stack Canaries would detect the buffer overflow before the return is executed. Having another function _compute_ or access to a high register can potentially trigger a window-overflow exception.