Memory corruption attacks such as return-oriented programming are a powerful exploitation technique to compromise software on a wide range of architectures. These attacks generate malicious computation based on existing code (so-called gadgets) residing in linked libraries. Both academia and industry have recently proposed defense techniques to mitigate return-oriented programming attacks. However, a continuous arms race has evolved between attacks and defenses. In this talk, we will elaborate on the evolution of memory corruption attacks. In particular, we explore prominent defense techniques such as control-flow integrity (CFI) enforcement, code randomization, and remote attestation. In addition, we investigate memory corruption attacks that exploit hardware faults to induce dangerous bit flips in memory. These attacks undermine memory access control mechanisms without requiring any software vulnerability. Specifically, we elaborate on the evolution of Rowhammer attacks and defenses.