
基础知识感谢这位师傅的博客,然我茅塞顿开!!
原理c++中当某个函数throw某个exception时,程序便会从当前函数开始向上回溯调用链,直到找到匹配的catch,执行完catch后,便会接着在catch所在函数继续执行。
结论异常处理本身存在一些问题,并且使得canary这样的栈保护机制无效。因为异常抛出后的代码不会执行,自然也不会检测canary,自然也不会调用stack_check_fail(). 在此基础上我们发现了一些控制程序流的方式:
通过覆盖rbp,进而控制程序流走向。当然前提是栈帧的确使用rbp存储,因为一些情况下程序只依靠rsp增减。
通过覆盖ret地址,使异常被另外一个handler处理
在某些情况下还可以通过伪造覆盖类虚表的手法,使其在cleanup handler执行析构函数的时候劫持程序流(本文不做详细分析)
覆盖ret地址后,就会去执行ret地址的handler函数。前提是这个handler函数要能够匹配这样的异常。
例题羊城杯2024 logger
❯ checksec pwn[*] '/home/yang/pwn' Ar ...