mach_vm_protect 无法使内存可执行

发布于 2025-01-09 01:25:28 字数 1240 浏览 1 评论 0原文

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

#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 大小是否正确 sizeof(test())

I'm trying to allocate memory dynamically and have it be executable through mach_vm_protect; however any time I try to execute the code the application crashes. But mach_vm_protect succeeds which is what I don't understand.

#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 Is size the correct sizeof(test())

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

初相遇 2025-01-16 01:25:28

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

由于您对 mach_vm_protect 的调用返回 KERN_SUCCESS,因此内核中可能存在错误。

我只需连续两次调用 mach_vm_protect 即可让您的代码正常工作:

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;
}

The issue is probably your use of VM_PROT_READ|VM_PROT_EXECUTE|VM_PROT_WRITE|VM_PROT_COPY. Modern operating systems, and architectures, try to enforce W^X permissions. That is, either a memory range is executable or writeable, but never both.

There might be a bug in the kernel since your call to mach_vm_protect is returning KERN_SUCCESS.

I was able to get your code working by simply making 2 calls to mach_vm_protect in succession:

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文