为了账号安全,请及时绑定邮箱和手机立即绑定

在mmap中执行代码以生成可执行代码段错误

在mmap中执行代码以生成可执行代码段错误

Qyouu 2021-04-09 13:15:48
我试图编写一个函数来复制一个函数(并最终修改其程序集)并返回它。对于一个间接级别来说,这很好用,但在两个级别上,我都遇到了段错误。这是一个最小的(不)工作示例:#include <stdio.h>#include <string.h>#include <sys/mman.h>#define BODY_SIZE 100int f(void) { return 42; }int (*G(void))(void) { return f; }int (*(*H(void))(void))(void) { return G; }int (*g(void))(void) {    void *r = mmap(0, BODY_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);    memcpy(r, f, BODY_SIZE);    return r;}int (*(*h(void))(void))(void) {    void *r = mmap(0, BODY_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);    memcpy(r, g, BODY_SIZE);    return r;}int main() {    printf("%d\n", f());    printf("%d\n", G()());    printf("%d\n", g()());    printf("%d\n", H()()());    printf("%d\n", h()()()); // This one fails - why?    return 0;}我可以一次将内存转移到mmap'ed区域中,以创建一个可以称为(g()())的有效函数。但是,如果我尝试再次应用(h()()()),则会出现段错误。我已经确认它可以正确创建的复制版本g,但是当我执行该版本时,就会出现段错误。我为什么不能在一个mmap'ed区域中执行代码而又不能在另一个mmap'ed区域中执行代码呢?从带有x/i检查的探索性gdb-ing看来,我可以成功调用,但是当我返回该函数时,我所来自的函数已被擦除并替换为0。如何使这种行为起作用?可能吗?
查看完整描述

3 回答

  • 3 回答
  • 0 关注
  • 334 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信