I wan't to turn on/off the call waiting feature of iPhone (that can be found at Settings > Phone > Call Waiting) programmatically.
What I have figured out is that the phone settings calls -setCallWaitingEnabled:specifier: method from PhoneSettingsCallWaitingController class found here. I found it in /System/Library/PreferenceBundles/MobilePhoneSettings.bundle/Call Waiting.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>id</key>
<string>com.apple.preferences.phone.call-waiting</string>
<key>items</key>
<array>
<dict>
<key>cell</key>
<string>PSGroupCell</string>
</dict>
<dict>
<key>cell</key>
<string>PSSwitchCell</string>
<key>get</key>
<string>callWaitingEnabled:</string>
<key>label</key>
<string>Call Waiting</string>
<key>set</key>
<string>setCallWaitingEnabled:specifier:</string>
</dict>
</array>
<key>title</key>
<string>Call Waiting</string>
</dict>
</plist>
I loaded the bundle manually and initialized the above class and called the method I said but nothing happens. Here's the code:
NSBundle *b = [NSBundle bundleWithPath:#"/System/Library/PreferenceBundles/MobilePhoneSettings.bundle"];
BOOL success = [b load];
if (success)
{
NSLog(#"\n\n\n\n Bundle load successfull! \n\n\n\n ");
Class PhoneSettingsCallWaitingController = NSClassFromString(#"PhoneSettingsCallWaitingController");
id tc = [[PhoneSettingsCallWaitingController alloc] init];
[tc setCallWaitingEnabled:0 specifier:0];
} else NSLog(#"\n\n\n\n Bundle load failure! \n\n\n\n ");
I don't know if I'm in the correct path. Is there another way to turn on/off the Call Waiting setting?
Declarations for CoreTelephony.framework private APIs
CF_EXTERN_C_BEGIN
CF_EXPORT CFNotificationCenterRef CTTelephonyCenterGetDefault();
CF_EXPORT void CTTelephonyCenterAddObserver(CFNotificationCenterRef center, const void *observer, CFNotificationCallback callBack, CFStringRef name, const void *object, CFNotificationSuspensionBehavior suspensionBehavior);
CF_EXPORT void CTSettingRequest(NSDictionary* dict);
CF_EXPORT void CTSettingSave(NSDictionary* dict);
CF_EXPORT NSString* kCTSettingCallClassVoice;
CF_EXPORT NSString* kCTSettingTypeCallWaiting;
CF_EXPORT NSString* kCTSettingType;
CF_EXPORT NSString* kCTSettingCallClass;
CF_EXPORT NSString* kCTSettingEnabled;
CF_EXTERN_C_END
Setting requests and saves are done asynchronously. Results will be sent to telephony center callback:
void SettingCallback(CFNotificationCallback center, void* observer, NSString* name, const void* objec, NSDictionary* userInfo)
{
if ([name isEqualToString:#"kCTSettingRequestSuccessNotification"])
{
//Setting request results are in 'userInfo' argument
}
else if ([name isEqualToString:#"kCTSettingRequestErrorNotification"])
{
//Setting request error
}
else if ([name isEqualToString:#"kCTSettingSaveSuccessNotification"])
{
//Setting saved
}
else if ([name isEqualToString:#"kCTSettingSaveErrorNotification"])
{
//Setting save error
}
}
...
CTTelephonyCenterAddObserver(CTTelephonyCenterGetDefault(), NULL, SettingCallback, NULL, NULL, CFNotificationSuspensionBehaviorHold);
Request call waiting setting:
CTSettingRequest(#{#"STSettingTypeUniqueIdentifier" : kCTSettingTypeCallWaiting,
kCTSettingCallClass : kCTSettingCallClassVoice,
kCTSettingType : kCTSettingTypeCallWaiting});
Save call waiting setting (in this case, enabled):
CTSettingSave(#{#"STSettingTypeUniqueIdentifier" : kCTSettingTypeCallWaiting,
kCTSettingCallClass : kCTSettingCallClassVoice,
kCTSettingType : kCTSettingTypeCallWaiting,
kCTSettingEnabled : #YES});
Related
I'm trying to make a file manager for iOS (my code has an exploit built in so it works).
The main code for my application is written in Swift and the code for running the exploit and reading files is written in Objecive-C.
This is the code I'm currently using in Objective-C:
NSString* readFile(NSString* file) {
char* buffer;
long lSize;
char* convertedFileName = [file UTF8String];
char* newFileName = deleteLastChar(convertedFileName); >> removes last / from path
char ch;
FILE *fp=fopen(newFileName, "r");
fseek( fp , 0L , SEEK_END);
lSize = ftell( fp );
rewind( fp );
buffer = calloc( 1, lSize+1 );
if( !buffer ) fclose(fp),fputs("memory alloc fails",stderr),exit(1);
if( 1!=fread( buffer , lSize, 1 , fp) )
fclose(fp),free(buffer),fputs("entire read fails",stderr),exit(1);
printf(buffer);
fclose(fp);
return [[NSString alloc] initWithUTF8String:buffer];
}
And this is the code for Swift:
func openFile(file: String) {
let fileContents = readFile(file)
print(fileContents) >> outputs nil
}
This is an example of a file I'm trying to open (plist file):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>canvas_height</key>
<integer>1136</integer>
<key>canvas_width</key>
<integer>640</integer>
</dict>
</plist>
This is what the printf in the Objective-C code returns:
bplist00\322]canvas_height\canvas_width\240\332
(+
And Swift says the string is nil
The file is being read but there is still something wrong. Any ideas on how to fix this or a better way to handle this?
I searched from internet, got the below code, it works well on simulator, while it does not work on my ipad mini4(ios 10.2, already jailbroken).
-- does not work means it cannot install/uninstall other apps. I can see message as below if I debug from Xcode.
LaunchServices: disconnect event received for service com.apple.lsd.modifydb
I also tried add signature using ldid, the same error.
My code is as below:
IPAResult installApp(NSString *ipaPath, NSString *ipaId) {
IPAResult ret = -1;
if (kCFCoreFoundationVersionNumber < 1140.10) {
void *lib = dlopen(KEY_SDKPATH, RTLD_LAZY);
if (lib) {
MobileInstallationInstall install = (MobileInstallationInstall)dlsym(lib, "MobileInstallationInstall");
if (install)
ret = install(ipaPath, [NSDictionary dictionaryWithObject:KEY_INSTALL_TYPE forKey:#"ApplicationType"], 0, ipaPath);
dlclose(lib);
}
} else {
NSLog(#"path:%#,id:%#", ipaPath, ipaId);
Class LSApplicationWorkspace_class = objc_getClass("LSApplicationWorkspace");
if (LSApplicationWorkspace_class) {
LSApplicationWorkspace *workspace = [LSApplicationWorkspace_class performSelector:#selector(defaultWorkspace)];
if (workspace && [workspace installApplication:[NSURL fileURLWithPath:ipaPath] withOptions:[NSDictionary dictionaryWithObject:ipaId forKey:#"CFBundleIdentifier"]])
ret = 0;
}
}
return ret;
}
BOOL uninstallApplication(NSString *appIdentifier) {
if (kCFCoreFoundationVersionNumber < 1140.10) {
void *lib = dlopen(KEY_SDKPATH, RTLD_LAZY);
if (lib) {
MobileInstallationUninstall uninstall = (MobileInstallationUninstall)dlsym(lib, "MobileInstallationUninstall");
if (uninstall)
return 0 == uninstall(appIdentifier, nil, nil);
dlclose(lib);
}
} else {
Class LSApplicationWorkspace_class = objc_getClass("LSApplicationWorkspace");
if (LSApplicationWorkspace_class) {
LSApplicationWorkspace *workspace = [LSApplicationWorkspace_class performSelector:#selector(defaultWorkspace)];
if (workspace && [workspace uninstallApplication:appIdentifier withOptions:nil])
return YES;
}
}
return NO;
}
The signature I used are:
<key>get-task-allow</key>
<true/>
<key>com.apple.private.mobileinstall.allowedSPI</key>
<array>
<string>CheckCapabilitiesMatch</string>
<string>InstallForLaunchServices</string>
<string>UninstallForLaunchServices</string>
</array>
<key>com.apple.backboardd.launchapplications</key>
<true/>
<key>com.apple.springboard.openapplications</key>
<true/>
iOS applications are sandboxed and cannot touch anything except themselves. This includes the operating system, and, in your case, other applications.
You're not going to be able to achieve what you are trying to achieve, it's restricted by the operating system.
For some reason - maybe has to do with a latest Xcode upgrade to version 7.2.1 - my pbxproj's structure got changed, and because of that, when I'm about to merge a PR, it just shows me a one big conflict on the entire file.
The reason, as I see it, is that one of them has this structure (posting the start of the file):
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
009025BEF30C41848E6869F6 /* RolloutDynamic_18.m in Sources */ = {isa = PBXBuildFile; fileRef = E1BF845EAB9E4962853253B5 /* RolloutDynamic_18.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
00AFDB74BD584F1C9BD41B9D /* RolloutDynamic_03.m in Sources */ = {isa = PBXBuildFile; fileRef = 588F21D12977444EAE3C70F5 /* RolloutDynamic_03.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
054D17D506BF45EE98822AB9 /* RolloutDynamic_15.m in Sources */ = {isa = PBXBuildFile; fileRef = 54D47CE8182E4482955DA02E /* RolloutDynamic_15.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
and the other one that structure (start of the file):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>archiveVersion</key>
<string>1</string>
<key>classes</key>
<dict/>
<key>objectVersion</key>
<string>46</string>
<key>objects</key>
<dict>
<key>18011C201B1F865300F52714</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.h</string>
<key>path</key>
<string>UserProfileTableViewController.h</string>
<key>sourceTree</key>
<string><group></string>
</dict>
Any idea how can this be solved?
Before we can use CFMessagePort, but now it's invalid for iOS7 and above, is there any replaced methods? I tried CFMessagePort when hooking the constructor of UIApplication in the jailbreak environment, but in most of the apps, it can't CFMessagePortCreateLocal successfully, it just return NULL.Am I wrong somewhere?
static void setupUIApplicationMessagePort()
{
NSString *identifier = #"com.foo.foo.UIApplication";
CFMessagePortRef local = CFMessagePortCreateLocal(NULL, (__bridge CFStringRef)identifier, callBackForUIApplication, NULL, NULL);
if (local) {
NSLog(#"local OK: %#", local);
CFRunLoopSourceRef source = CFMessagePortCreateRunLoopSource(NULL, local, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopCommonModes);
rocketbootstrap_cfmessageportexposelocal(local);
} else {
NSLog(#"local is NULL"); // in most of the apps it returns NULL
}
}
%ctor {
if(%c(UIApplication)) {
setupUIApplicationMessagePort();
}
}
try CFNotificationCenter using CFNotificationCenterGetDarwinNotifyCenter
#include <CoreFoundation/CFNotificationCenter.h>
/* This function will be called whatever a notification posted with the specified name */
void NotificationCallback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo){
}
void addObserver(){
CFStringRef name = CFSTR("NotificationName");
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),&NotificationCallback,name,NULL,CFNotificationSuspensionBehaviorDeliverImmediately);
}
This will listen to notifications named NotificationName
To post a notification
void postNotification(){
CFStringRef name = CFSTR("NotificationName");
/* You have to create the userInfo dictionary and add all the keys to it */
CFDictionaryRef userInfo;
CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), name, NULL, userInfo, true);
}
I have a rather large plist that I am trying to load data from. Here is an example of the plist, but there are 580 records so I can't put them all here:
<plist version="1.0">
<array>
<dict>
<key>Grave #</key>
<string></string>
<key>Last Name</key>
<string>?</string>
<key>First Name</key>
<string>Ada Lou daughter of</string>
<key>Dates</key>
<string>?-? Unable to read stone</string>
<key>Notes</key>
<string></string>
<key></key>
<string></string>
</dict>
<dict>
<key>Grave #</key>
<string></string>
<key>Last Name</key>
<string>?</string>
<key>First Name</key>
<string>Stone w/ Cherokee syllabry and also in english says: Here we rest</string>
<key>Dates</key>
<string></string>
<key>Notes</key>
<string></string>
<key></key>
<string></string>
</dict>
I have my property in my .h file
#property (nonatomic, strong) NSDictionary *graves;
Synthesized in my .m file:
#synthesize graves;
Here is my code that loads the file in my view did load function:
NSString *file = [[NSBundle mainBundle] pathForResource:#"RossCemeteryList" ofType:#"plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:file]) {
NSLog(#"The file exists");
} else {
NSLog(#"The file does not exist");
}
graves = [[NSDictionary alloc] initWithContentsOfFile:file];
NSLog(#"%i", [graves count]);
The NSLog messages says it finds the file, the there are 0 rows in the second NSLog message. I can try to spit out the contents graves using "NSLog (#"%#", graves);" and it returns NULL.
I am a little lost. Any help appreciated.
You are trying to create an NSDictionary object and initialize it from the contents of that plist while that plist actually contains an NSArray as its root object. You need to change your NSDictionary into an NSArray or NSMutableArray.
I don't know if you're still looking for a solution, but this code should allow you to load a plist file and determine the type of its contents:
// load a Property List ("plist") file (fully-qualified path) into a generic object, if
// it's available...
- ( NSObject * ) testLoadPListData: ( NSString * const ) plistPath
{
// load the file data into a raw data object...
NSData * const data = [ NSData dataWithContentsOfFile: plistPath ];
// fields returned from property list creation...
NSPropertyListFormat fmt = 0;
NSError * err = nil;
// load the file data into a serialized property list object...
NSPropertyListSerialization * plist = [ NSPropertyListSerialization propertyListWithData: data
options: NSPropertyListImmutable
format: &fmt
error: &err
];
// if there was an error creating the serialized object...
NSString * const errorText = err ? [ err description ] : nil;
if ( errorText )
{
// log the error string...
NSLog( #"error while reading data from file \"%#\": %#"
, plistPath
, errorText
);
} // end error creating serialized object
#if defined( DEBUG )
//////////////////////////////
// //
// DEBUG PURPOSES ONLY... //
// //
//////////////////////////////
// if this file is in a format that can be readily translated into one of our target data types...
if ( plist )
{
// if this property list file contains a dictionary...
if ( [ plist isKindOfClass: [ NSDictionary class ] ] )
{
// dump the contents of the dictionary to the debug output window...
NSDictionary * const dict = ( NSDictionary * )( plist );
__CCLOG( #"<Dictionary>%#\n</Dictionary>", dict );
} // end is dictionary plist file
// if this property list file contains an array...
else if ( [ plist isKindOfClass: [ NSArray class ] ] )
{
// dump the contents of the array to the debug output window...
NSArray * const arr = ( NSArray * )( plist );
__CCLOG( #"<Array>%#</Array>", arr );
} // end is array plist file
} // end valid file format
#endif // defined( DEBUG )
return plist;
} // end testLoadPListData