gpt4 book ai didi

c - 重新映射堆栈成功,但随后引发 SEGV

转载 作者:行者123 更新时间:2023-11-30 19:59:36 25 4
gpt4 key购买 nike

我在 strace 下运行了一个用汇编语言编写的简单程序,该程序仅执行 SYS_exit

_start:
mov rax, 0x3C
mov rdi, 0x0
syscall

并注意到堆栈中没有像 mmap 内存这样的东西:

alrorp@dmspc:~$ strace ./bin 
execve("./bin", ["./bin"], 0x7ffd591eda80 /* 65 vars */) = 0
exit(0) = ?
+++ exited with 0 +++

所以我尝试使用MAP_FIXED对堆栈页面对齐地址进行mmap,如下所示:

int main(void){
int a = 1;
void *ptr = &a;
void *page_aligned_ptr = (void *)((intptr_t) ptr & -4096);
mmap(page_aligned_ptr, 4096, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
}

问题是在成功调用 mmap 后它会出现段错误(即它返回请求的地址而不是 MAP_FAILED)。

mmap(0x7ffdf50db000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ffdf50db000
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=NULL} ---
+++ killed by SIGSEGV (core dumped) +++
Segmentation fault

你能给出关于这种行为的任何提示吗?在堆栈损坏的情况下,核心转储似乎(几乎)毫无用处。

为堆栈创建自定义映射之类的东西是否有意义?

最佳答案

用新的零字节匿名页面替换包含返回地址的堆栈页面显然会在 main 返回时导致段错误,并将 0 弹出到 RIP 中。

注意si_addr=NULL,IIRC这是发生故障的代码地址。因此,在 RSP 指向 0 运行 ret 后,RIP=0。 (ret 本身不会出错,但从地址 0 获取代码会出错。)

或者实际上,段错误将位于 mmap 的 libc 包装器内,它本身必须ret

使用调试器单步执行 C 编译器为您创建的 asm。

关于c - 重新映射堆栈成功,但随后引发 SEGV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56878133/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com