Does mach allow to create a new thread that belongs to another task? (MACOSX)

43 views Asked by At

I am trying to create a new thread (thread_create) that belongs to another task, for learning purposes. I want to use the mach interface (not POSIX alternatives) and the C programming language. After trying for a long time, I keep getting a Segmentation fault when the thread is resumed (thread_resume). While I provided a code snippet my question is: is this possible in MacOSX? There are many mach functionalities that do not work or not as intended in MacOSX, is this one of them?

Notes:

  • My PC is a Mac with an Apple Silicon processor, obviously running MacOSX.
  • Yes, I have run the program with sudo privileges.
  • I am not asking for someone to fix my code,, but an answer regarding if what I want to achieve is possible with my PC and OS.
int res;
size_t cpuid;
mach_port_t task = mach_task_self();
mach_port_t newthread;

if (argc == 2) {
    res = task_for_pid(mach_task_self(), (pid_t) atoi(argv[1]), &task);
    check_res(res, "Error fetching task from pid");
}

res = _os_cpu_number();
printf("os_cpu %d\n", res);

pthread_cpu_number_np(&cpuid);
printf("pthread_cpu_number_np %zu\n", cpuid);

void *pb = _os_tsd_get_base();

printf("main tsd_base %p\n", pb);

_STRUCT_ARM_THREAD_STATE64 thread_state;
mach_msg_type_number_t size = ARM_THREAD_STATE64_COUNT;

res = thread_create(task, &newthread);
check_res(res, "Error creating new thread");

arm_thread_state64_t ctx;

res = thread_get_state(newthread, ARM_THREAD_STATE64, &ctx, &size);
check_res(res, "Error getting state from task");

vm_address_t stack_ptr;

res = mach_vm_allocate(task, &stack_ptr, 65536, TRUE);
check_res(res, "Error allocating stack memory");

res = mach_vm_protect(task, stack_ptr, 65536, FALSE, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY);
check_res(res, "Error changing protection");

stack_ptr = (stack_ptr + 65536) & ~0xF;
stack_ptr -= 64;

vm_address_t localdata_ptr;

res = mach_vm_allocate(task, &localdata_ptr, 65536, TRUE);
check_res(res, "Error allocating thread local data (TSD)");

res = mach_vm_protect(task, localdata_ptr, 65536, FALSE, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY);
check_res(res, "Error changing protection");

res = mach_vm_write(task, stack_ptr, (vm_offset_t) & localdata_ptr, sizeof(vm_address_t));
check_res(res, "Error writing to new thread stack");

ctx.__sp = (uint64_t) (stack_ptr);
ctx.__pc = (uintptr_t) & thread_func_caso;

res = thread_set_state(newthread, ARM_THREAD_STATE64, &ctx, size);
check_res(res, "Error setting new thread state");

res = thread_resume(newthread);
check_res(res, "Error resuming thread");

What I have tried

  1. Currently the function the thread is meant to execute expects 1 parameter. I tried with none (just in case).
  2. Modifying protections using vm_protect.
  3. Adjusting the stack pointer (I checked this one a lot of times. Moreover, the program works if it creates a thread for itself.)
0

There are 0 answers