uint64_t call_remote(mach_port_t task_port, void* fptr, int n_params, ...)
{
if (n_params > MAX_REMOTE_ARGS || n_params < 0){
NSLog(@"unsupported number of arguments to remote function (%d)\n", n_params);
return 0;
}
kern_return_t err;
uint64_t remote_stack_base = 0;
uint64_t remote_stack_size = 4*1024*1024;
remote_stack_base = remote_alloc(task_port, remote_stack_size);
uint64_t remote_stack_middle = remote_stack_base + (remote_stack_size/2);
// create a new thread in the target
// just using the mach thread API doesn't initialize the pthread thread-local-storage
// which means that stuff which relies on that will crash
// we can sort-of make that work by calling _pthread_set_self(NULL) in the target process
// which will give the newly created thread the same TLS region as the main thread
_STRUCT_ARM_THREAD_STATE64 thread_state = {{0}};
mach_msg_type_number_t thread_stateCnt = sizeof(thread_state)/4;
// we'll start the thread running and call _pthread_set_self first:
thread_state.__sp = remote_stack_middle;
thread_state.__pc = (uint64_t)_pthread_set_self;
// set these up to put us into a predictable state we can monitor for:
uint64_t loop_lr = find_blr_x19_gadget();
thread_state.__x[19] = loop_lr;
thread_state.__lr = loop_lr;
// set the argument to NULL:
thread_state.__x[0] = 0;
mach_port_t thread_port = MACH_PORT_NULL;
err = thread_create_running(task_port, ARM_THREAD_STATE64, (thread_state_t)&thread_state, thread_stateCnt, &thread_port);
if (err != KERN_SUCCESS){
NSLog(@"error creating thread in child: %s\n", mach_error_string(err));
return 0;
}
// NSLog(@"new thread running in child: %x\n", thread_port);
// wait for it to hit the loop:
while(1){
// monitor the thread until we see it's in the infinite loop indicating it's done:
err = thread_get_state(thread_port, ARM_THREAD_STATE64, (thread_state_t)&thread_state, &thread_stateCnt);
if (err != KERN_SUCCESS){
NSLog(@"error getting thread state: %s\n", mach_error_string(err));
return 0;
}
if (thread_state.__pc == loop_lr && thread_state.__x[19] == loop_lr){
// thread has returned from the target function
break;
}
}
以上代码thread_create_running执行后被注入的进程会挂掉。
日志打印如下:
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)