首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >mach_vm_protect无法使内存可执行

mach_vm_protect无法使内存可执行
EN

Stack Overflow用户
提问于 2022-02-22 17:33:04
回答 1查看 171关注 0票数 0

我试图动态地分配内存,并让它可以通过mach_vm_protect执行;但是,每当我试图执行代码时,应用程序都会崩溃。但是mach_vm_protect成功了,这是我不明白的。

代码语言:javascript
复制
#include <stdio.h>
#include <unistd.h>
#include <mach/mach_init.h>
#include <mach/vm_map.h>
#include <mach/mach_vm.h>

int test(int x, int y){
    return x+y;
}
typedef int (*test_mach_copy)(int,int);
#define CODE_SIZE 0x17
int main()
{

    
    mach_vm_address_t remoteCode64 = (vm_address_t) NULL;
    mach_vm_address_t testvmaddr = (vm_address_t)&test;
    task_t remotetask;
    task_for_pid(mach_task_self(), getpid(), &remotetask);
    if (mach_vm_protect(remotetask, testvmaddr, CODE_SIZE, 1, VM_PROT_READ|VM_PROT_EXECUTE)!=KERN_SUCCESS) {
      return 1;
    }
      
    if(mach_vm_allocate(remotetask,&remoteCode64,CODE_SIZE,VM_FLAGS_ANYWHERE)!=KERN_SUCCESS){
        return 1;
    }
    if (mach_vm_protect(remotetask, remoteCode64, CODE_SIZE, 1, VM_PROT_READ|VM_PROT_EXECUTE|VM_PROT_WRITE|VM_PROT_COPY)!=KERN_SUCCESS) {
      return 1;
    }
    mach_vm_copy(remotetask, testvmaddr, CODE_SIZE, remoteCode64);
    test_mach_copy tmc = (test_mach_copy)remoteCode64;
    int x = tmc(10,20);
    printf("%d\n",x);

    return 0;
}

x017的大小是正确的大小(test())

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-02-22 19:04:39

问题可能在于您对VM_PROT_READ|VM_PROT_EXECUTE|VM_PROT_WRITE|VM_PROT_COPY的使用。现代操作系统和体系结构试图强制执行W^X权限。也就是说,内存范围要么是可执行的,要么是可写的,但永远不能两者兼而有之。

由于您对mach_vm_protect的调用正在返回KERN_SUCCESS,所以内核中可能有一个bug。

我只需连续对mach_vm_protect进行2次调用,就可以使您的代码正常工作:

代码语言:javascript
复制
int main()
{
    mach_vm_address_t remoteCode64 = (vm_address_t) NULL;
    mach_vm_address_t testvmaddr = (vm_address_t)&test;
    task_t remotetask;
    task_for_pid(mach_task_self(), getpid(), &remotetask);
    if (mach_vm_protect(remotetask, testvmaddr, CODE_SIZE, 1, VM_PROT_READ|VM_PROT_EXECUTE)!=KERN_SUCCESS) {
      return 1;
    }

    if(mach_vm_allocate(remotetask,&remoteCode64,CODE_SIZE,VM_FLAGS_ANYWHERE)!=KERN_SUCCESS){
      return 1;
    }

    if (mach_vm_protect(remotetask, remoteCode64, CODE_SIZE, 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_COPY)!=KERN_SUCCESS) {
      return 1;
    }
    if (mach_vm_copy(remotetask, testvmaddr, CODE_SIZE, remoteCode64) != KERN_SUCCESS) {
      return 1;
    }
    if (mach_vm_protect(remotetask, remoteCode64, CODE_SIZE, 0, VM_PROT_READ|VM_PROT_EXECUTE)!=KERN_SUCCESS) {
      return 1;
    }
    test_mach_copy tmc = (test_mach_copy)remoteCode64;
    int x = tmc(10,20);
    printf("%d\n",x);

    return 0;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71225810

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档