
Whitepaper
TL;DR: This PoC demonstrates a 3‑stage Structured Exception Handling (SEH) cascade caused by deliberate misaligned execution into raw byte blobs whose first valid instruction is a faulting
div regwith a zero divisor.
Each exception stage installs the next SEH handler, triggers a new misaligned divide‑by‑zero, and executes a benign observable payload before restoring the original SEH chain and terminating cleanly.
MOEW (Misaligned Opcode Exception Waterfall) is a defensive research sample that showcases controlled exception‑driven multi‑stage execution on x86/Wow64 Windows. It demonstrates:
fs:[0]blob1, blob2, blob3)KiUserExceptionDispatcherRtlDispatchExceptionAll payloads are benign:
%TEMP%The PoC is intentionally defanged. No data is encrypted, modified, or destroyed.
div at controlled offsets (ECX/EDX/EBX = 0)ORIGINAL_SEH)The PoC uses nightly‑only features:
#![feature(asm_experimental_arch)]
#![feature(naked_functions)]
Install the necessary components:
rustup toolchain install nightly
rustup target add i686-pc-windows-msvc --toolchain nightly
Since the PoC installs custom SEH handlers that are not present in the SAFESEH table, the linker must be instructed to disable SAFESEH validation.
Create .cargo/config.toml:
[target.i686-pc-windows-msvc]
rustflags = [
"-C", "link-arg=/SAFESEH:NO",
]
Build the binary:
cargo +nightly build --target i686-pc-windows-msvc --release
Output is located at:
target\i686-pc-windows-msvc\release\seh_waterfall.exe
Execute:
seh_waterfall.exe
Expected control‑flow:
Stage 0 → misaligned blob1 → Stage 1 handler
Stage 1 → misaligned blob2 → Stage 2 handler
Stage 2 → misaligned blob3 → Final handler
Final → restore SEH → exit
Visible artifacts:
%TEMP%\moew_stage2.txt is created (Stage 2)On 32‑bit Windows, SEH records form a linked list stored at fs:[0]:
#[repr(C)]
struct SehRec {
next: *mut SehRec,
handler: usize,
}
Each handler uses the standard SEH signature:
extern "system" fn handler(
record: *mut u8,
frame: *mut u8,
context: *mut u8,
dispatcher: *mut u8,
) -> i32
static STAGE_COUNTER: AtomicU32 = AtomicU32::new(0);
static mut ORIGINAL_SEH: *mut SehRec = std::ptr::null_mut();
Used to:
fs:[0] as ORIGINAL_SEH.fs:[0] with this new record.blob1 + 5, which decodes as div ecx (after setting ECX = 0).notepad.exe.blob2 + 3 → div edx (with EDX = 0).%TEMP%\moew_stage2.txt.blob3 + 3 → div ebx (with EBX = 0).calc.exe.ORIGINAL_SEH into fs:[0].process::exit(0).blob1#[unsafe(naked)]
pub extern "C" fn blob1() {
naked_asm! {
".byte 0xB8, 0x10, 0x00, 0x00, 0x00", // mov eax, 0x10
".byte 0xF7, 0xF1", // div ecx
".byte 0xC3", // ret
".byte 0x90, 0x90, 0x90", // nop padding
}
}
mov eax, 0x10; div ecx; ret+5: div ecx (with ECX = 0 → #DE)blob2#[unsafe(naked)]
pub extern "C" fn blob2() {
naked_asm! {
".byte 0x55", // push ebp
".byte 0x8B, 0xEC", // mov ebp, esp
".byte 0xF7, 0xF2", // div edx
".byte 0xC3", // ret
".byte 0x90, 0x90, 0x90", // nop padding
}
}
push ebp; mov ebp, esp; div edx; ret+3: div edx (with EDX = 0 → #DE)blob3#[unsafe(naked)]
pub extern "C" fn blob3() {
naked_asm! {
".byte 0x53", // push ebx
".byte 0x8B, 0xD8", // mov ebx, eax
".byte 0xF7, 0xF3", // div ebx
".byte 0xC3", // ret
".byte 0x90, 0x90, 0x90", // nop padding
}
}
push ebx; mov ebx, eax; div ebx; ret+3: div ebx (with EBX = 0 → #DE)Each faulted stage re‑enters the Windows user‑mode exception pipeline:
KiUserExceptionDispatcher
→ RtlDispatchException
→ SEH chain walk (fs:[0])
→ MOEW handler
Typical debugger view:
seh_waterfall!blobX+offset
ntdll!KiUserExceptionDispatcher
ntdll!RtlDispatchException
seh_waterfall!stageN_handler
The waterfall is entirely driven by genuine hardware faults and SEH dispatch; no synthetic or fake exceptions are used.
The file written in Stage 2 looks like:
MOEW Stage 2 Marker
-------------------
This file was written by the Stage 2 SEH handler
as a benign demonstration payload.
Its presence in %TEMP% serves as a simple, observable proof that Stage 2 executed via the SEH chain.
Potential extensions include:
The complete PoC implementation is available in this repository (see src/main.rs).
This project is intended for defensive research and education. Copyright <2025>