Skip to content
Create a gist now

Instantly share code, notes, and snippets.

Demonstrates we can now support limited JIT compilation on recent versions of iOS (assuming Apple approves entitlements at some future point)
//
// 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);
}
@TooTallNate

On my iPhone 4, jailbroken 4.3.1:

gcc main.m -o main
./main
2

:)

@saurik
saurik commented Apr 10, 2011

"Demonstrates newer versions of iOS now support PROT_EXEC pages, for just-in-time compilation." <- For the record, jailbroken devices have always supported this (this is exactly how MobileSubstrate works, as well as the various code-generation engines used in JocStrap, PyObjC, and Cycript). It is true that iOS 4.3 now supports a "dynamic_codesign" entitlement, that allows this kind of page flipping, but as you did not add that entitlement to your binary it would not work on a non-jailbroken device.

@stuartcarnie
Owner

Indeed - I used otool to list the entitlements of MobileSafari from a decrypted 4.3 image and found the dynamic_codesign property (among others). Almost certain that Apple will reject apps which have been signed with this undocumented entitlement.

For jailbroken devices, you are lucky enough to support rwx, whereas currently this entitlement only allows either rw or rx, but no rwx. This severely limits its use for dynamic code gen.

@diclophis

Almost certain that Apple will reject apps which have been signed with this undocumented entitlement.

Is there any way we can get ahold of apple to see if this is something that they would indeed react on?

Might be worthwhile to try an update an existing app with this entitlement and see how far it gets through the review process.

@stuartcarnie
Owner

Given it is not documented anywhere, that is a pretty good sign Apple won't accept it, however, you could try contacting appreview at apple.com

@eniton
eniton commented Dec 13, 2011

How to add a new entitlement in Xcode 4 as it doesn't support creating custom entitlement file anymore?
I tried to list a valid entitlement file first via: codesign -d --entitlements - /path/to/myapp.app
And then add "dynamic_codesign" into it. But I still got "Invalid entitlement ***" error when I tried to install on my non-jailbroken iPhone.

@wtholliday

I just ran this on an iOS 6 iPad and it worked without adding an entitlement. Am I missing something?

@munsie
munsie commented Dec 5, 2012

To follow up to @wtholliday's post, this does appear to work as is, without an entitlements, on iOS 6. Someone should check with Apple to see if this would actually be allowed into the App Store. If so, this is a very welcome change.

@rolfbjarne

It works on both iOS 5.1 and iOS 6.0 if you run it from Xcode. If you tap on the app it crashes in both cases. Presumably starting the app with gdbserver enables jitting (my guess is that this is to support executing random expressions in the debugger).

I was not able to set the "dynamic_codesign" entitlement, Xcode refused to deploy/install the app ("The executable was signed with invalid entitlements" and "The entitlements specified in your application's Code Signing Entitlements file do not match those specified in your provisioning profile.")

@dcaspi
dcaspi commented Feb 24, 2016

For future reference -

  • 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).
  • Marking memory regions for JIT use with 'mmap's MAP_JIT flag is still blocked, even in local builds. This is guarded today by the 'dynamic_codesign' entitlement. That's what's keeping JavaScriptCore.framework from using JIT when running locally in your app.
  • It seems that the old method of just adding the dynamic_codesign entitlement in Xcode doesn't work anymore.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.