IOS Jailbreak How do intercept SMS / Text Messages - ios

I'm currently trying to write an application that intercepts text messages and reacts depending on the content of that message.
I tried to hook into _receivedMessage:(struct __CKSMSRecord *)message replace:(BOOL)replace method in the CKSMSService class but this seems not do get called at all.
Could someone please tell me what function/class i have to hook in? I need to intercept the text message before it gets displayed and stored into the database. I'm on IOS 5.0.1.
Any help is truly appreciated.

This code snippet should intercept SMS messages- You can extend it for other kinds of notifications. Will work on iOS 5.0.1 as well. Does not work with iMessages though. Link with CoreTelephony framework (there are bunch of private headers there which you'd can class-dump)
#include <dlfcn.h>
#define CORETELPATH "/System/Library/PrivateFrameworks/CoreTelephony.framework/CoreTelephony"
id(*CTTelephonyCenterGetDefault)();
void (*CTTelephonyCenterAddObserver) (id,id,CFNotificationCallback,NSString*,void*,int);
static void telephonyEventCallback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
{
NSString *notifyname=(NSString *)name;
if ([notifyname isEqualToString:#"kCTMessageReceivedNotification"])//received SMS
{
NSLog(#" SMS Notification Received :kCTMessageReceivedNotification");
// Do blocking here.
}
}
-(void) registerCallback {
void *handle = dlopen(CORETELPATH, RTLD_LAZY);
CTTelephonyCenterGetDefault = dlsym(handle, "CTTelephonyCenterGetDefault");
CTTelephonyCenterAddObserver = dlsym(handle,"CTTelephonyCenterAddObserver");
dlclose(handle);
id ct = CTTelephonyCenterGetDefault();
CTTelephonyCenterAddObserver(
ct,
NULL,
telephonyEventCallback,
NULL,
NULL,
CFNotificationSuspensionBehaviorDeliverImmediately);
}

Although the poster already accepted rajagp's answer, I'm pretty sure it doesn't do what the question actually asked, on iOS 5. For iOS 5, I'm no longer seeing the message content anymore, although I do get notified that there is a new message.
So, what I did is take rajagp's notification handler for kCTMessageReceivedNotification, and inside it, use the code posted here to actually get the content of the text message, from the SMS database.

This still works on iOS 7, but I found that you need a slight delay after receiving the kCTMessageReceivedNotification notification. Else you will miss the SMS just received. I use a delay of 0.1 sec, with a [self performSelector .. afterDelay:0.1];

Related

How do you use the confirm phase of a SiriKit custom intent?

Experimenting with the Xcode 10 beta, I've created a custom Siri Intent and it's working well. My Intents Extension successfully receives the intents and handles them in turn.
There is no validation of any sort needed on the parameters of the intent, once it is triggered it will request data from the network. I can do this in (void)handle....
I've noticed in my automatically generated Intent class, a list of possible response codes.
typedef NS_ENUM(NSInteger, SMSCheckTeamIntentResponseCode) {
SMSCheckTeamIntentResponseCodeUnspecified = 0,
SMSCheckTeamIntentResponseCodeReady,
SMSCheckTeamIntentResponseCodeContinueInApp,
SMSCheckTeamIntentResponseCodeInProgress,
SMSCheckTeamIntentResponseCodeSuccess,
SMSCheckTeamIntentResponseCodeFailure,
SMSCheckTeamIntentResponseCodeFailureRequiringAppLaunch,
SMSCheckTeamIntentResponseCodeSuccessPlayingNow = 100
}
The failure, success, and success (playing now) responses are defined in my Intents file. The others, such as ready, and in progress, are not, but I'd still like to tell Siri that my extension is "in progress" using the (void)confirm... method.
SMSCheckTeamIntentResponse * const response = [[SMSCheckTeamIntentResponse alloc] initWithCode:SMSCheckTeamIntentResponseCodeInProgress userActivity:nil];
completion(response);
At the moment, when I call this in the confirm method, Siri says something went wrong with my app, and the extension exits.
Does anyone know how to successfully use these response codes?

Creating a custom iOS Jailbreak keyboard

I have developed a custom input method and now would like to develop a tweak that would register it as a keyboard in iOS.
There are many different keyboards in Cydia (mainly from Chinese developers) such as TouchPal and Baidu Input that appear in settings as a keyboard, so it is definitely possible.
I have tried looking into the following options (barely 4 days in IDA, Xcode with theos and console):
Text Input bundles located in /System/Library/TextInput — seems to have nothing to deal with the keyboards themselves? Some superclass headers are missing (i.e. TIZephyr... classes) so I couldn't quite figure it out. However a native integration would be awesome.
TextInput private framework — also seems to be just for dictionary and so on
UIKit's UIKB.. and UIKeyboard.. classes — UIKeyboardImpl seems to be something related with the keyboard functioning and UIKeyboardLayout is the thing you build upon.
I tried hooking UIKeyboardDictationLayout to just give a plain instance of a UIKeyboardLayout upon initialization — and when I tapped the mic button on the keyboard, the keyboard went blank! That kind of implementation would be nice too (even though killing dictation functionality is undesired). However, I can't find where do I send typing events as well.
So the points are:
What is responsible for registering a class as an input method?
What is responsible for receiving typing events?
I am asking this in hope that there are developers who had to do something similar already, because I couldn't find any articles nor anything that would give me a hint in the header files and bundles.
Thanks in advance.
I got it right this february even though didn't have the time to respond and it's not quite necessary now that iOS 8 has come.
Still, this is how you load your own keyboard:
%hook UIKeyboardInputMode
+ (id)keyboardInputModeWithIdentifier:(id)arg1 {
id o = %orig;
return o;
}
- (id)primaryLanguage {
if([TegakiLayout isTegaki:[self identifier]]) return #"Tegaki";
return %orig;
}
%end
%hook UIKeyboardImpl
/* This is where the magic is! */
+ (Class)layoutClassForInputMode:(NSString*)arg1 keyboardType:(int)arg2 {
Class sass = %orig;
if ([TegakiLayout isTegaki: arg1]) {
return [TegakiLayout class];
}
return sass;
}
%end
extern "C" NSArray*UIKeyboardGetSupportedInputModes();
extern "C" NSArray*UIKeyboardGetActiveInputModes();
static NSArray* (*orig_modes)();
NSArray* rep_modes() {
NSArray* res = [orig_modes() arrayByAddingObjectsFromArray:#[#"TEGAKI", #"TEGAKI_Graffiti"]];
return res;
}
static NSArray* (*orig_active_modes)();
NSArray* rep_active_modes() {
NSArray* res = orig_active_modes();
return res;
}
%ctor {
%init;
MSHookFunction(UIKeyboardGetSupportedInputModes, rep_modes, &orig_modes);
MSHookFunction(UIKeyboardGetActiveInputModes, rep_active_modes, &orig_active_modes);
}
where TegakiLayout is a subclass of UIKeyboardLayout.
You then implement - (BOOL)isAlphabeticPlane for returning whether it's a traditional keyboard thing and do the custom view creation in showKeyboardWithInputTraits:screenTraits:splitTraits:.
To type in you then use [[UIKeyboardImpl activeInstance]insertText:#"\n"];.
To create a 'globe' button you use this:
Class sw = NSClassFromString(#"UIInputSwitcherView");
[[sw sharedInstance]selectNextInputMode];
Don't forget to implement -keyboardName and -keyplaneName as well!
I'll post the whole project one day probably, but for now it's too large to describe here. This should be enough to get you up and running, though.

What's CTSubscriber (and how to use it) on iOS 7?

On iOS 7, CTSubscriber was added to the CoreTelephony framework. There is no documentation available, only its header file:
/*
* CTSubscriberTokenRefreshed
*
* Description:
* The name of the NSNotification sent when the carrier token is available.
*/
CORETELEPHONY_EXTERN NSString * const CTSubscriberTokenRefreshed __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_CLASS_AVAILABLE(7_0)
#interface CTSubscriber : NSObject
/*
* carrierToken
*
* Description:
* A data blob containing authorization information about the subscriber.
*
* May return nil if no token is available.
*/
#property (nonatomic, readonly, retain) NSData* carrierToken __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
#end
Also, on What's new on iOS 7, this is mentioned:
The Core Telephony framework (CoreTelephony.framework) lets you get information about the type of radio technology in use by the device. Apps developed in conjunction with a carrier can also authenticate against a particular subscriber for that carrier.
I think that CTSubscriber is related to the bold part of the text. However, I haven't found anything related on how this happens.
I have tried to use the following code (added to application:didFinishLaunchingWithOptions:) to experiment with this API, but the notification is never fired and carrierToken returns nil:
CTSubscriber *subscriber = [CTSubscriberInfo subscriber];
NSLog(#"%#", subscriber.carrierToken);
[[NSNotificationCenter defaultCenter] addObserverForName:CTSubscriberTokenRefreshed object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
NSLog(#"==========");
NSLog(#"%#", note);
NSLog(#"%#", subscriber.carrierToken);
}];
So, I have the following questions:
What exactly ("authorization information") does carrierToken return and how to make it not nil?
How does Apple know if your app is "developed in conjunction with a carrier"?
Is this how Evernote is giving 1 year of premium account to Telefonica users (http://blog.evernote.com/blog/2013/08/13/evernote-and-telefonica-announce-global-partnership/)? (Probably not, since the information they need can be obtained on CTCarrier)
I asked the same question in the developer forums and got this reply :
You should escalate this via the carrier you're working with, who can in turn escalate it to their contact at Apple.
Link to the thread: https://devforums.apple.com/message/934226#934226
The reason you can’t find any documentation is because much of Core Telephony consists of private APIs. Consequently, there isn’t any way to access the SIM card from an app published on the App Store. A jailbroken device is, of course, another story, but in that case you’re pretty much on your own.
Edit:
The Core Telephony framework (CoreTelephony.framework) lets you get
information about the type of radio technology in use by the device.
Apps developed in conjunction with a carrier can also authenticate
against a particular subscriber for that carrier.

How to find the purple port for the front most application in IOS 5 and above?

I am trying to write an app that runs in the background and injects touches to the springboard or other apps. I understand that I will be using private APIs and structures. The app is an enterprise app and does not need to be approved for the AppStore.
I am using the GSEvent structure as suggested by KennyTM with some minor modifications for IOS 5/6. I am able to send touch events and other events to the Springboard by sending GSSystemEvents.
I need to be able to send similar events to other applications as well, but I am not able to find the port for the front most application.
Is there a way to get the port for the application that is upfront and running so that I can send my GSEvents to the app?
It would be nice if someone can point me to examples or show me how I can get the purple port of the front most app.
Thanks!
UPDATE: I haven't tested this on ios7.
I happen to work on the exact same requirement before.
To get the purple port, you can use GSCopyPurpleNamedPort() with the bundle Id as an argument.
If you need to simulate touch on SpringBoard, use GSGetPurpleSystemEventPort.
With this below code, you should be able to get the port and use it to inject touch system wide.
#import <dlfcn.h>
// Framework Paths
#define SBSERVPATH "/System/Library/PrivateFrameworks/SpringBoardServices.framework/SpringBoardServices"
-(mach_port_t)getFrontMostAppPort
{
bool locked;
bool passcode;
mach_port_t *port;
void *lib = dlopen(SBSERVPATH, RTLD_LAZY);
int (*SBSSpringBoardServerPort)() = dlsym(lib, "SBSSpringBoardServerPort");
void* (*SBGetScreenLockStatus)(mach_port_t* port, bool *lockStatus, bool *passcodeEnabled) = dlsym(lib, "SBGetScreenLockStatus");
port = (mach_port_t *)SBSSpringBoardServerPort();
dlclose(lib);
SBGetScreenLockStatus(port, &locked, &passcode);
void *(*SBFrontmostApplicationDisplayIdentifier)(mach_port_t *port, char *result) = dlsym(lib, "SBFrontmostApplicationDisplayIdentifier");
char appId[256];
memset(appId, 0, sizeof(appId));
SBFrontmostApplicationDisplayIdentifier(port, appId);
NSString * frontmostApp=[NSString stringWithFormat:#"%s",appId];
if([frontmostApp length] == 0 || locked)
return GSGetPurpleSystemEventPort();
else
return GSCopyPurpleNamedPort(appId);
}
I've tested...this works fine on iOS 5 and 6.
You might not need the lock part if you don't inject when the lock screen shows up.
Hope this helps.

pjsip send sms how to

I'm trying to send sms messages through pjsip without luck so far.
The account gets registered on a server and I get a register success response but I can't find any good tutorials that show how to send sms.
I found this book online but it still doesn't give me any examples of how to use this library:
http://www.scribd.com/doc/90092246/Pjsip-Dev-Guide#outer_page_48
I know I'm supposed to use:
pjsip_endpt_create_request(pjsip_endpoint *endpt, const pjsip_method method, const pj_str_t *target, const pj_str_t *from, const pj_str_t *to, , const pj_str_t *call_id, int cseq, const pj_str_t *text, pjsip_tx_data **p_tdata);
pjsip_endpt_acquire_transport(pjsip_endpoint *endpt, pjsip_transport_type_e type, const pj_sockaddr_t *remote, int addr_len, const pjsip_tpselector *sel, pjsip_transport **p_tp)
but apart from these, I have no idea.
Note: I don't want instant messaging, I want the texts to be delivered as SMS if possible.
And it needs to be done in pjsip, no other library (no flexibility unfortunately).
Thanks in advance!
Okay, here I am answering my own question related to pjsip again. I wish this library had proper documentation where the function calls were explained a better way on what they do.
1 thing that confused me was that there in this developer's guide: http://www.pjsip.org/release/0.5.4/PJSIP-Dev-Guide.pdf
there are 2 topics. 1 is message elements and how to create a request. The other is instant messaging. I wasn't exactly sure which was required for SMS. Turns out, its the instant messaging.
The only needed function is:
pjsua_im_send(pjsua_acc_id acc_id, const pj_str_t *to, const pj_str_t *mime_type, const pj_str_t *content, const pjsua_msg_data *msg_data, void *user_data);
1st variable acc_id is what gets initialized at the beginning of the application SIP registration.
2nd variable is the number you want the message to be sent to. I initialized it as such:
"sip:16476804556#sipserverdomain.com"
3rd variable is for sending MIME's. I didn't use this. so it's NULL.
4th variable is the message body itself.
For example:
pj_str_t text;
const char *msgText = [#"Hello there!" UTF8String];
text = pj_str((char*)msgText);
then I passed: &text to the function.
5th variable is the msg data. Again, didn't use it. It's NULL.
6th variable is user data. Didn't use this either. NULL.
And finally, this is what the function call looked like:
pjsua_im_send(app._sip_acc_id, &to, NULL, &text, NULL, NULL);
Hope this helps someone out there having a similar problem!
-c0d3Junk13
A SMS is essentially an email delivered to phonenumber#serviceprovider.com. I have not used pjsip, however I was able to use the Chilkat library to deliver SMS quite easily. For example code to send an email, you can find it on their website.

Resources