Black Hat USA 2025 | Breaking Control Flow Integrity by Abusing Modern C++

Black Hat
Black HatMar 10, 2026

Why It Matters

Because coroutines are rapidly adopted in modern C++ applications, the ability to bypass CFI threatens the core guarantees of memory‑safe execution, forcing vendors and developers to redesign protection mechanisms.

Key Takeaways

  • C++ coroutines introduce heap‑allocated frames with indirect calls.
  • These frames create new indirect‑branch targets exploitable against CFI.
  • Existing CFI schemes (IBT, CFG, fine‑grain) rely on static call sites.
  • Attackers can hijack coroutine resume pointers to bypass control flow checks.
  • Proposed mitigations include sealing coroutine frames and validating resume indices.

Summary

The Black Hat talk explains how modern C++ coroutines undermine traditional control‑flow‑integrity (CFI) defenses. While CFI has become standard in operating systems and compilers, the presenter shows that coroutine‑generated frames and indirect resume calls open a novel attack surface.

CFI works by building a static control‑flow graph and instrumenting indirect calls—using mechanisms such as Intel CET’s shadow stack and indirect‑branch‑tracking, Microsoft’s Control‑Flow Guard, or fine‑grain type‑based checks. Coroutines, however, are compiled into three hidden functions (creation, resume, destroy) and a heap‑allocated frame that stores a resume pointer, a destroy pointer, a promise object and a suspension index. Because the resume pointer is an indirect call, it falls outside the static graph that CFI expects.

The speaker demonstrates that by corrupting the coroutine frame—e.g., overwriting the resume pointer or the suspension index—an attacker can redirect execution to arbitrary code while the CFI checks still succeed. He cites concrete examples such as co_await’s await_suspend routine, which can be manipulated to invoke malicious code, and shows that even coarse‑grain schemes like Intel CET cannot detect the misuse.

These findings imply that any software relying on CFI must reconsider the security of coroutine‑heavy codebases, especially in high‑performance servers and libraries adopting C++20 features. Mitigations may include sealing coroutine frames, validating resume indices at runtime, or extending CFI to cover heap‑allocated indirect calls.

Original Description

Control Flow Integrity (CFI) has emerged as the definitive defense against code-reuse attacks, enforcing strict execution flow checks that effectively stop classic exploitation techniques like Return-Oriented Programming (ROP). Today, CFI defenses—such as Intel CET, Control Flow Guard and LLVM CFI—are already present in everyday systems, and their widespread adoption marks a new era where most binary exploitation attacks are significantly mitigated.
In this talk, we will present Coroutine Frame-Oriented Programming (CFOP), a novel exploitation technique that bypasses the leading CFI defenses—including CET, CFG and LLVM CFI—on both Linux and Windows, across all major compilers. CFOP arises from a key insight: while CFI effectively stops well-known attack vectors like return address hijacking, programming languages continue to evolve and introduce new weak points, which CFI is not ready to handle.
Notably, despite rigorous standardization, C++20 coroutines present weaknesses that undermine these CFI defenses. Coroutines are already present in major software projects (such as popular databases), and with CFOP we demonstrate how to practically exploit them in a post-CFI world—highlighting the need for continuously adapting CFI defenses to evolve alongside new programming paradigms.
By:
Marcos Bajo | PhD Student, CISPA Helmholtz Center for Information Security
Christian Rossow
Presentation Materials Available at:

Comments

Want to join the conversation?

Loading comments...