#include // mach_task_self, vm_protect #include // MSFindSymbol // MARK: - Types typedef void (*MSHookMemory_ptr_t)(void *target, const void *data, size_t size); #define ENSURE_KERN_SUCCESS(ret) \ if (ret != KERN_SUCCESS) { \ return false; \ } \ // MARK: - Functions bool write_memory(void *destination, const void *data, size_t size) { MSHookMemory_ptr_t __MSHookMemory = (MSHookMemory_ptr_t)MSFindSymbol(NULL, "_MSHookMemory"); if (__MSHookMemory) { // We can use MSHookMemory! __MSHookMemory(destination, data, size); return true; } // We can't use MSHookMemory, so try and remap the permissions mach_port_t our_port = mach_task_self(); // Attempt to map as RWX ENSURE_KERN_SUCCESS(vm_protect(our_port, (vm_address_t)destination, size, false, VM_PROT_ALL)) // Write to memory ENSURE_KERN_SUCCESS(vm_write(our_port, (vm_address_t)destination, data, size)) // Map back to RX ENSURE_KERN_SUCCESS(vm_protect(our_port, (vm_address_t)destination, size, false, VM_PROT_READ | VM_PROT_EXECUTE)) return true; }