Skip to content

Instantly share code, notes, and snippets.

@JJTech0130
Created February 23, 2025 03:43
Show Gist options
  • Save JJTech0130/1b93f5a4bbdaa33c970c5f3b6f307d67 to your computer and use it in GitHub Desktop.
Save JJTech0130/1b93f5a4bbdaa33c970c5f3b6f307d67 to your computer and use it in GitHub Desktop.
#import <Foundation/Foundation.h>
#import <mach/mach.h>
#import <stdio.h>
#import <stdlib.h>
#import <string.h>
#define PAGE 0x4000
__attribute__((section("__TEXT,__nop_section"), aligned(PAGE)))
static const uint32_t nop_page[PAGE / sizeof(uint32_t)] = {
[0 ... (PAGE / sizeof(uint32_t)) - 1] = 0x1F2003D5 // nop
};
typedef int (*JitFunction)(void);
void write_instructions(void *page) {
uint32_t instructions[] = {
0x52800540, // mov w0, #42
0xD65F03C0 // ret
};
memcpy(page, instructions, sizeof(instructions));
}
int main(int argc, char *argv[]) {
void *page = (void *)nop_page;
printf("NOP page address: %p\n", page);
// Set page to RW (PROT_READ | PROT_WRITE | PROT_COPY)
kern_return_t kr = vm_protect(mach_task_self_, (mach_vm_address_t)page, PAGE, FALSE, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY);
if (kr != KERN_SUCCESS) {
fprintf(stderr, "Failed to set RW protection: %d\n", kr);
return 1;
}
// Write new instructions
write_instructions(page);
// Set page to RX (PROT_READ | PROT_EXEC)
kr = vm_protect(mach_task_self_, (mach_vm_address_t)page, PAGE, FALSE, VM_PROT_READ | VM_PROT_EXECUTE);
if (kr != KERN_SUCCESS) {
fprintf(stderr, "Failed to set RX protection: %d\n", kr);
return 1;
}
JitFunction func = (JitFunction)page;
int result = func();
printf("Executed JIT-ed function, result: %d\n", result); // Should print 42
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment