The frame grows down; strcpy writes up, from
buf[0] towards the saved return address. Set how many bytes are copied
in, and watch where the check happens — that is the part the hardened build
gets marked wrong on.
Jump to a state worth stopping on:
▲ high addresses · the caller
▼ low addresses · buf[0], where strcpy starts
A = a copied byte. 0 = the NUL
terminator, ringed. A faint dot = untouched. Hatched cells are writes
outside buf. When a check aborts before the copy,
every cell stays a dot and every row reads never written — an
empty grid is the difference between preventing a write and
noticing one afterwards. Nothing here is carried by colour alone:
every row also says, in words, whether it is intact.