Some comments:
As you see, the string does not just consist of the address of bar (last 4 bytes), but also some gibberish before it (there is nothing sacred about "1234", it could be anything). This is because we are trying to overwrite the return address. On my machine, the stack looks like this:
So in order to overwrite the return address, we need to write on buf[22] to buf[25]. I suspect that in order to not segfault at all, we would need to write a good value on the saved ebp as well...Code:+----------------+
| return address | buf[22-25]
+----------------+
| saved ebp | buf[18-21]
+----------------+
| buf[14-17] |
+----------------+
| buf[10-13] |
+----------------+
| buf[6-9] |
+----------------+
| buf[2-5] |
+--------+-------+
| |buf[0-1]
+--------+-------+
The point is that here we are writing on memory that we own, but shouldn't write to. This is why the x86 arch is so bad from a security standpoint: it trusts that you are not going to write to some places, even though you technically can because you own them.