public
Last active

Demonstrates we can now support limited JIT compilation on recent versions of iOS (assuming Apple approves entitlements at some future point)

  • Download Gist
main.m
Objective-C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
//
// 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);
}

On my iPhone 4, jailbroken 4.3.1:

gcc main.m -o main
./main
2

:)

"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.

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.

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.

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

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.

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

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.

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.")

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.