重新映射堆栈成功,但稍后会引发 SEGV
Remapping stack succeeds, but later SEGV is raised
我 运行 一个用汇编编写的简单程序,在 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
成功后出现段错误(即 returns 请求的地址而不是 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
您能就此行为给出任何提示吗?在堆栈损坏的情况下,核心转储似乎(几乎)没用。
为堆栈创建自定义映射之类的东西是否有意义?
用零字节的新匿名页面替换包含您的 return 地址的堆栈页面显然会在 main
return 秒后立即导致段错误,并弹出 0
进入 RIP。
注意si_addr=NULL
,IIRC 那是错误发生的代码地址。所以 RIP=0 在 运行 a ret
之后 RSP 指向 a 0
。 (ret
本身不会出错,但是来自地址 0
的 code-fetch 会出错。)
或者实际上段错误将在 mmap
的 libc 包装器内部,它本身必须 ret
.
使用调试器 single-step C 编译器为您创建的 asm。
我 运行 一个用汇编编写的简单程序,在 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
成功后出现段错误(即 returns 请求的地址而不是 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
您能就此行为给出任何提示吗?在堆栈损坏的情况下,核心转储似乎(几乎)没用。
为堆栈创建自定义映射之类的东西是否有意义?
用零字节的新匿名页面替换包含您的 return 地址的堆栈页面显然会在 main
return 秒后立即导致段错误,并弹出 0
进入 RIP。
注意si_addr=NULL
,IIRC 那是错误发生的代码地址。所以 RIP=0 在 运行 a ret
之后 RSP 指向 a 0
。 (ret
本身不会出错,但是来自地址 0
的 code-fetch 会出错。)
或者实际上段错误将在 mmap
的 libc 包装器内部,它本身必须 ret
.
使用调试器 single-step C 编译器为您创建的 asm。