我需要 EBP/RBP 的内容来检索函数的返回地址。此地址应位于堆栈帧内的位置 8(%RBP)(我们仅考虑 x86_64 位架构)。
我从传递给信号处理程序的 ucontex_t 结构中检索此值,但程序有一个非常奇怪的行为。有时 RBP 寄存器中包含的值根本没有意义(例如,0x00、0x01),有时它包含正确的堆栈基值。当然,这种行为会导致多个应用程序崩溃。
我需要检索函数的返回地址,因为我想找出调用函数的地址。
这是我正在使用的代码:
syscall = ctx->uc_mcontext.gregs[REG_SYSCALL];
pc=ctx->uc_mcontext.gregs[REG_PC];
stack=ctx->uc_mcontext.gregs[REG_STACK];
stack_base=ctx->uc_mcontext.gregs[REG_BASE];
function_address=get_function_address((char *)stack_base);
DPRINT(DEBUG_INFO, "Received SYS_SECCOMP signal : syscall %lu\n", syscall);
DPRINT(DEBUG_ALL, "Syscall instruction address %p\n", info->si_call_addr);
DPRINT(DEBUG_ALL, "PC 0x%lx, BASE_STACK 0x%lx, Stack 0x%lx\n", pc, stack_base, stack);
DPRINT(DEBUG_ALL, "Syscall number %d\n", info->si_syscall);
DPRINT(DEBUG_ALL, "Syscall arch %u\n", info->si_arch);
宏定义如下:
#define REG_SYSCALL REG_RAX
#define REG_PC REG_RIP
#define REG_BASE REG_RBP
#define REG_STACK REG_RSP
前面代码的输出示例是:正确值:
[DEBUG_INFO] Received SYS_SECCOMP signal : syscall 3
Syscall instruction address 0x7fa058d67452
PC 0x7fa058d67452, BASE_STACK 0x7fff145c1d00, Stack 0x7fff145c1bc0
Syscall number 3
Syscall arch 3221225534
错误的值:
[DEBUG_INFO] Received SYS_SECCOMP signal : syscall 78
Syscall instruction address 0x7fa058df2495
PC 0x7fa058df2495, BASE_STACK 0xffffffffffffffa8, Stack 0x7fff145c1ed0
Syscall number 78
Syscall arch 3221225534
更糟 :
[DEBUG_INFO] Received SYS_SECCOMP signal : syscall 3
Syscall instruction address 0x7fa058e18360
PC 0x7fa058e18360, BASE_STACK 0x0, Stack 0x7fff145c1e68
Syscall number 3
Syscall arch 3221225534
我注意到,当 RBP 包含零时,它会保持相同的值,直到应用程序结束。