Created
May 26, 2025 19:56
-
-
Save pavel-kirienko/f04058defcb21a9f20391e2faa5681d5 to your computer and use it in GitHub Desktop.
Revisions
-
pavel-kirienko created this gist
May 26, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,66 @@ #include <cassert> #include <cstdint> #include <cstdlib> namespace stack_canary { /// Do not use this directly; see the StackCanary definition below. template <std::size_t n_bytes, std::uint8_t seed = 0xC9> class StackCanary_Impl final { public: constexpr StackCanary_Impl() noexcept { for (std::size_t i = 0; i < n_bytes; ++i) { data_[i] = reference(i); } ensure(); } StackCanary_Impl(const StackCanary_Impl&) = delete; StackCanary_Impl& operator=(const StackCanary_Impl&) = delete; StackCanary_Impl(StackCanary_Impl&&) = delete; StackCanary_Impl& operator=(StackCanary_Impl&&) = delete; ~StackCanary_Impl() { ensure(); } explicit operator bool() const volatile noexcept { for (std::size_t i = 0; i < n_bytes; ++i) { if (data_[i] != reference(i)) { return false; } } return true; } private: void ensure() const volatile noexcept { if (!*this) { assert(false); std::abort(); } } static constexpr std::uint8_t reference(const size_t i) noexcept { return (seed + (i * 0xC9U)) & 0xFFU; } volatile std::uint8_t data_[n_bytes]; }; /// A simple utility class for debugging stack memory corruption. /// The dtor will invoke assert(false) and std::abort() if memory corruption is detected. /// The canary is designed to have a 1-byte alignment. /// Generate reference values for searching in binary dumps: /// /// >>> stage = lambda i: (0xC9 + (i * 0xC9)) & 0xFF /// >>> bytes(map(stage, range(64))).hex() template <std::size_t n_bytes = 64> using StackCanary = volatile StackCanary_Impl<n_bytes>; }