首先,这里发生的事情是他将函数 foo() 的硬编码地址存储在他读入变量“x”的“文件”中。他将其存储为 '134513853' ,当转换为十六进制时变为: 0x80484bd 必须是 function foo() 的 address 。
所以,按照执行顺序,
程序从文件中读取foo()的地址并将其复制到x中。然后它用这个地址覆盖缓冲区,这样在它溢出缓冲区后,它会覆盖返回地址。
例如:
如果这是函数堆栈的样子,
缓冲区----------------->
EBP ----------------->
返回地址 --------> 一些 0x 值
后溢出它看起来像这样:
缓冲区-----------------> 0x80484bd
EBP--------> 0x80484bd
返回地址---------> 0x80484bd EIP
暂时不要打扰 little-endian。因此,当 main() 函数结束时,将从存储在“返回地址”中的地址继续执行,从而将执行转移到函数 foo() 并打印字符串“欢迎来到我的...”。
关于你的第二个问题,我认为制作视频的人禁用了 ASLR 和 Stack Cookies。
ASLR 或地址空间布局随机化随机化可执行文件的关键部分,以便函数存在于每个新实例的不同地址。
Stack Cookie/Canary 是一个随机运行时生成值,它位于局部变量和返回地址之间,因此任何溢出都必须首先覆盖 cookie 值。在函数结束之前检查这个 cookie 值,如果不匹配,则函数退出,从而不会让执行流被转移到攻击者控制的返回地址。
为了重复这个,你必须在你的系统上禁用 ASLR,在 Ubuntu 上,这可以通过在你的终端中键入以下来实现,例如 Bash:
回声 0 | sudo tee /proc/sys/kernel/randomize_va_space
然后,您将不得不通过以下方式在没有堆栈 cookie 的情况下编译您的程序:
gcc -fno-stack-protector -z execstack -o test test.c
更多信息:
ASLR:http://en.wikipedia.org/wiki/Address_space_layout_randomization
http://en.wikipedia.org/wiki/Buffer_overflow_protection#Canaries
希望这会有所帮助。