Created
March 4, 2011 19:59
-
-
Save stuartcarnie/855607 to your computer and use it in GitHub Desktop.
Demonstrates we can now support limited JIT compilation on recent versions of iOS (assuming Apple approves entitlements at some future point)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// main.m | |
// ProtectTest | |
// Demonstrates newer versions of iOS now support PROT_EXEC pages, for just-in-time compilation. | |
// | |
// Must be compiled with Thumb disabled | |
// | |
// Created by Stuart Carnie on 3/4/11. | |
// Copyright 2011 Manomio LLC. All rights reserved. | |
// | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <errno.h> | |
#include <sys/mman.h> | |
#include <limits.h> /* for PAGESIZE */ | |
#ifndef PAGESIZE | |
#define PAGESIZE 4096 | |
#endif | |
typedef int (*inc_t)(int a); | |
inc_t _inc = NULL; | |
int | |
main(void) | |
{ | |
uint32_t code[] = { | |
0xe2800001, // add r0, r0, #1 | |
0xe12fff1e, // bx lr | |
}; | |
uint32_t *p; | |
/* Allocate a buffer; it will have the default | |
protection of PROT_READ|PROT_WRITE. */ | |
p = malloc(1024+PAGESIZE-1); | |
if (!p) { | |
perror("Couldn't malloc(1024)"); | |
exit(errno); | |
} | |
/* Align to a multiple of PAGESIZE, assumed to be a power of two */ | |
p = (uint32_t *)(((int) p + PAGESIZE-1) & ~(PAGESIZE-1)); | |
// copy instructions to function | |
p[0] = code[0]; | |
p[1] = code[1]; | |
/* Mark the buffer read / execute. */ | |
if (mprotect(p, 1024, PROT_READ | PROT_EXEC)) { | |
perror("Couldn't mprotect"); | |
exit(errno); | |
} | |
_inc = (inc_t)p; | |
int a = 1; | |
a = _inc(a); | |
printf("%d\n", a); // as expected, echos 2 | |
exit(0); | |
} |
You can technically change the protection of memory to be executable in iOS on local builds (you wouldn't get past app review process though, obviously).
@dcaspi Could you elaborate on that? I have a small benchmark app I'm playing with for personal use (not going to the app store) that could benefit from executable memory. I've tried mmap and vm_protect but neither seems to work in giving me executable memory.
@vpeca You need a get-task-allow
entitlement (injected by Xcode automatically) and get ptrace
to trace you in some way. Either this can be done by attaching via LLDB, as Xcode does, or you can do it programmatically with ptrace(PT_TRACE_ME, 0, NULL, 0)
.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For future reference -