Issue
Unless I am misunderstanding something, it seems the position of the canary value can be before or after ebp
, therefore in the second case the attacker can overwrite the frame pointer without touching the canary.
For example in this snippet, the canary is located at a lower address (ebp-0xc
) than ebp
therefore protecting it (an attacker must overwrite the canary to overwrite ebp
):
0x080484e0 <+52>: mov eax,DWORD PTR [ebp-0xc]
0x080484e3 <+55>: xor eax,DWORD PTR gs:0x14
0x080484ea <+62>: je 0x80484f1 <func+69>
0x080484ec <+64>: call 0x8048360 <__stack_chk_fail@plt>
However looking at other code the canary is after rbp+8
:
How should I interpret this? Does this depend on GCC version or something else?
Solution
The canary is always below the frame pointer, with every version of gcc I've tried. You can see that confirmed in the gdb disassembly immediately below the IDA disassembly in the blog post you linked, which has mov rax, QWORD PTR [rbp-0x8]
.
I think this is just an artifact of IDA's disassembler. Instead of displaying the numerical offset for rbp
-relative addresses, it assigns a name to each stack slot, and displays the name instead; basically assuming that every rbp
-relative access is to a local variable or argument. And it looks like it always displays that name with a +
regardless of whether the offset is positive or negative. Note that buf
and fd
also get a +
sign even though they are local variables which are clearly below the frame pointer.
In this example, it has named the canary var_8
as if it were a local variable. So I suppose to translate this properly, you have to think of var_8
as having the value -8
.
Answered By - Nate Eldredge