
How to call iOS7 [jailbreak] from the application?

I had a task to call from iPhone to iOS7. On previous versions of iOS (6 and earlier), it was enough to use the private API and everything worked, but on iOS7 this approach stopped working. In this post I want to tell how to make a call and get my own phone number from the application.
Project code on github .
Jailbreak
The first thing that everything works is to do a Jailbreak. For the latest version of iOS 7.1.2, it is perfectly done using en.pangu.io - jailbreak tool You can see the jalibreak instructions here , for example . I did this with iPhone4, iOS 7.1.2 on Windows 8.1. After jailbreak is done, install OpenSSH via Cydia.

We go on the iPhone via ssh and change the password for root [default password: alpine]
$ssh root@10.231.65.56
$passwd
The phone is ready. Prepare the application that will ring. In the application, we will use the following private APIs:
void CTCallListDisconnectAll(); // for ending call header: CTCall.h
CTCallRef CTCallDial(CFStringRef number); // for calling header: CTCall.h
CFStringRef CTSettingCopyMyPhoneNumber(); // for getting own number header: CTSetting.h
The header files CTCall.h, CTSetting.h can be found in the repository on GitHub.
Now let's look at a code that works without problems on iOS 6.1.4 and without jailbreak.
Call start method
- (IBAction)onPlaceCall:(id)sender {
NSString *numberToCall = [self.tfNumberToCall text];
NSLog(@"Open CoreTelephony");
void *ptrCoreTelephone = dlopen("/System/Library/Framework/CoreTelephony.framework/CoreTelephony", RTLD_LAZY);
if (ptrCoreTelephone == nil){
NSLog(@"ptrCoreTelephone is nil");
return;
}
NSLog(@"Get CTCallDial from CoreTelephony");
int (*pCTCallDial)(NSString*) = dlsym(ptrCoreTelephone, "CTCallDial");
if (pCTCallDial != nil) {
int error = pCTCallDial(numberToCall);
NSLog(@"pCTCallDial error: %d", error);
}
NSLog(@"Close CoreTelephony");
dlclose(ptrCoreTelephone);
}
Wrap Interrupt Method
- (IBAction)onStopCall:(id)sender {
NSLog(@"onStopCall");
void *ptrCoreTelephone = dlopen("/System/Library/Framework/CoreTelephony.framework/CoreTelephony", RTLD_LAZY);
if (ptrCoreTelephone == nil){
NSLog(@"ptrCoreTelephone is nil");
return;
}
NSLog(@"Get CTCallListDisconnectAll from CoreTelephony");
int (*pCTCallListDisconnectAll)() = dlsym(ptrCoreTelephone,
"CTCallListDisconnectAll");
if (pCTCallListDisconnectAll != nil) {
int error = pCTCallListDisconnectAll();
NSLog(@"pCTCallListDisconnectAll error: %d", error);
}
dlclose(ptrCoreTelephone);
}
Number Method
-(NSString*) getMyNumber {
NSLog(@"Open CoreTelephony");
void *lib = dlopen("/Symbols/System/Library/Framework/CoreTelephony.framework/CoreTelephony",RTLD_LAZY);
NSLog(@"Get CTSettingCopyMyPhoneNumber from CoreTelephony");
NSString* (*pCTSettingCopyMyPhoneNumber)() = dlsym(lib, "CTSettingCopyMyPhoneNumber");
NSLog(@"Get CTSettingCopyMyPhoneNumber from CoreTelephony");
if (pCTSettingCopyMyPhoneNumber == nil) {
NSLog(@"pCTSettingCopyMyPhoneNumber is nil");
return nil;
}
NSString* ownPhoneNumber = pCTSettingCopyMyPhoneNumber();
dlclose(lib);
return ownPhoneNumber;
}
Now the fun part. The same code will work on iOS7 if you add entitlements to the application and re-sign it with these entitlements. To do this, do the following.
- Build an application without a signature
- Prepare and attach the application xml file with entitlements
- Sign the application and put on the phone
Build an application without a signature
For this, you need to set the following in Xcode in Build Settings:

Then run the assembly.
Preparing an xml file with entitlements
You need to create a file with the following contents:
com.apple.coretelephony.Calls.allow com.apple.coretelephony.Identity.get
com.apple.coretelephony.Calls.allow - for calls
com.apple.coretelephony.Identity.get - to get the number
Put it in the same place from where the signature command will be launched.
Signature and Installation
To sign, we need a folder with binaries. To understand where Xcode puts them, you can run the command:
$ls -la ~/Library/Developer/Xcode/DerivedData/ | grep JBCall
The path would be something like this:
/Users/username/Library/Developer/Xcode/DerivedData/JBCall-cktasembftvbmqaaiiunvljdwocs/Build/Products/Debug-iphoneos/JBCall.app
Copy JBCall.app to a separate folder, put entitlements.xml next to it:
JBCall.app
entitlements.xml
Now you need to sign the binaries with the following command:
$codesign --sign='iPhone Developer: FirstName SecondName (XXXXXXXX)’ --entitlements entitlements.xml JBCall.app
iPhone Developer: FirstName SecondName (XXXXXXXX) - the name of the certificate, which can be viewed in keychain.

After the actions done, you can install the application and use. In this case, the installation consists of copying the * .app folder to the iPhone and restarting SpringBoard. I did this via scp in the script:
DST_DIR='/Applications'
APP_NAME='JBCall.app'
USER='root'
PASSWD='mypass'
IP='10.231.65.56'
APP_ON_MAC="/Users/username/Library/Developer/Xcode/DerivedData/JBCall-cktasembftvbmqaaiiunvljdwocs/Build/Products/Debug-iphoneos/JBCall.app"
sshpass -p $PASSWD scp -r $APP_NAME $USER@$IP:$DST_DIR
In the script, you need to change only the values of variables for yourself and you can run it. The path also needs to be updated:
/ Users / username / Library / Developer / Xcode / DerivedData / JBCall-cktasembftvbmqaaiiunvljdwocs /Build/Products/Debug-iphoneos/JBCall.app
Restarting SpringBoard:
$sshpass -p $PASSWD ssh $USER@$IP su mobile -c uicache 1>/dev/null 2>&1
Separate restart command from the device:
$su mobile -c uicache 1>/dev/null 2>&1
Of course sshpass and scp must be installed.
All the described installation actions are arranged in the form of a script.
Everything, now the application can make calls, hang up, show the phone number.
Screenshots from iOS 6.1.4

Screenshots from iOS 7.1.2

Total
As a result, we got an application that calls on the latest version of iOS with jailbreak. I hope someone comes in handy this experience.
How did I find out about entitlements?
Thanks to the creker user on stackoverflow for the tip about entitlements that he found in the file:
/System/Library/CoreServices/SpringBoard.app/SpringBoard
Indeed, looking at the binary you can find the text lines:
com.apple.coretelephony.Calls.allow
com. apple.coretelephony.Identity.get
