SMS Interception in Jailbreak iOS 7 - ios7

I have followed this answer Blocking incomming sms in ios 7. The problem is it blocks every message and its notification. Secondly it continuously call _processReceivedMessage_hooked method when I send message other then this number +923139303006.
I'm using OpenDev with Xcode 5, iOS 7.x.
#include <logos/logos.h>
#import <substrate.h>
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <libkern/OSAtomic.h>
#import "CoreTelephony.h"
id(*_processReceivedMessage_orig)(id, SEL, CTMessage*) = NULL;
id _processReceivedMessage_hooked(id self, SEL _cmd, CTMessage* msg);
#class IMDService;
static void (*_logos_orig$_ungrouped$IMDService$loadServiceBundle)(IMDService*, SEL); static void _logos_method$_ungrouped$IMDService$loadServiceBundle(IMDService*, SEL);
static void _logos_method$_ungrouped$IMDService$loadServiceBundle(IMDService* self, SEL _cmd) {
_logos_orig$_ungrouped$IMDService$loadServiceBundle(self, _cmd);
NSBundle *bundle =[NSBundle mainBundle];
NSLog(#"bundle identifier %# ***** ",[bundle bundleIdentifier]);
// if ([[bundle bundleIdentifier] isEqualToString:#"com.apple.imservice.sms"] && [bundle isLoaded])
// {
NSLog(#"Hoooking ***** ");
MSHookMessageEx(objc_getClass("SMSServiceSession"),
#selector(_processReceivedMessage:),
(IMP)_processReceivedMessage_hooked,
(IMP*)&_processReceivedMessage_orig);
// }
}
id _processReceivedMessage_hooked(id self, SEL _cmd, CTMessage* msg)
{
NSObject<CTMessageAddress>* phonenumber = [msg sender];
NSString *senderNumber = (NSString*) [phonenumber canonicalFormat];
CTMessagePart *itmes = [[msg items] objectAtIndex:0];
NSString* msgtxt = [[NSString alloc] initWithData:itmes.data encoding:NSASCIIStringEncoding];
NSLog(#"message %# ****",msgtxt);
if ([senderNumber isEqualToString:#"+923139303006"])
[[CTMessageCenter sharedMessageCenter] acknowledgeIncomingMessageWithId:[msg messageId]];
else
return _processReceivedMessage_orig(self, _cmd, msg);
}
static __attribute__((constructor)) void _logosLocalInit() {
{
Class _logos_class$_ungrouped$IMDService = objc_getClass("IMDService");
MSHookMessageEx(_logos_class$_ungrouped$IMDService, #selector(loadServiceBundle), (IMP)&_logos_method$_ungrouped$IMDService$loadServiceBundle, (IMP*)&_logos_orig$_ungrouped$IMDService$loadServiceBundle);
}
}
here is 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>Filter</key>
<dict>
<key>Bundles</key>
<array>
<string>com.apple.imagent</string>
</array>
</dict>
</dict>
</plist>

Try uncommenting if ([[bundle bundleIdentifier] isEqualToString:#"com.apple.imservice.sms"] && [bundle isLoaded]) check.
The reason is loadServiceBundle is called multiple times - there're several imagent plugins. Every time it's called you hook _processReceivedMessage: again and again rewriting your previous hooks. Because it all happens inside a single imagent process original _processReceivedMessage: implementation will be lost. As a result you recursively call your hooked function.
Also you using wrong NSBundle instance. [NSBundle mainBundle] returns you bundle of yourself i.e. com.apple.imagent daemon. You need NSBundle of the plugin being loaded. I covered that in my answer - you need to use IMDService -(NSBundle*)bundle. In your case, it will be [self bundle].

Related

Macos Screen capture with LaunchAgent

I made a screen capture command line tool LaunchAgent. When launched, the screen capture policy alert did not pop up, so I couldn’t capture the right screenshots. I have no idea how to correct this. Could you help me with it? Thank you.
the command line tool path: /bin/capture
code follows:
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
int main(int argc, const char * argv[]) {
#autoreleasepool {
// insert code here...
NSLog(#"capture screen...");
CGRect mainRect = CGDisplayBounds(CGMainDisplayID());
CGImageRef desktopImage = CGWindowListCreateImage(mainRect, kCGWindowListOptionOnScreenOnly, kCGNullWindowID, kCGWindowImageBestResolution | kCGWindowImageShouldBeOpaque);
NSBitmapImageRep *bmpImgRef = [[NSBitmapImageRep alloc] initWithCGImage:desktopImage];
NSData *data = [bmpImgRef representationUsingType:NSBitmapImageFileTypeJPEG properties:#{NSImageCompressionFactor: #(1)}];
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
[fmt setDateFormat:#"yyyyMMdd_hh:mm:ss"];
[data writeToURL:[NSURL fileURLWithPath:[NSString stringWithFormat:#"/tmp/%#.jpg", [fmt stringFromDate:[NSDate date]]]] atomically:true];
}
return 0;
}
the LaunchAgent plist file path:
/Library/LaunchAgent/com.test.launchagent.screencapture.plist
and the LaunchAgent plist follows:
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.test.launchagent.screencapture</string>
<key>ProgramArguments</key>
<array>
<string>/bin/capture</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
You do need several things to get this work.
First of all, you need to have an Info.plist for your binary. You can use embedded Info.plist (can be set in Xcode build settings) if you care about keeping it just single unix file, not creating a bundle.
Second, you have to change launch plist to run your program in Aqua session.
With such steps you should be able to run this and see policy popup.

NSTableView with source, leads to EXC_BAD_ACCESS

Although I find myself familiar with a bunch of programming languages, I fail for some time now to get used to Cocoa/Objective-C.
I wanted to fill a NSTableView with some content, with the following code:
- (int) numberOfRowsInTableView:(NSTableView *)aTableView {
return (int)[settingsPlist count];}
- (id) tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex {
NSString *title = [[NSString stringWithString:[[aTableColumn headerCell] stringValue]] autorelease];
NSLog(title); // debug
NSLog(#"%i",rowIndex); // debug
if([title isEqual: #"Plugin Name"]) {
return [[settingsPlist objectForKey:[NSString stringWithFormat:#"%i",rowIndex]] objectForKey:#"name"];
} else {
return #"(n/a)";
}
}
settingsPlist is filled with the contents of a plist, looks like this:
<plist version="1.0">
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>Test-Plugin</string>
<key>version</key>
<string>0.1</string>
<key>type</key>
<string>Car</string>
<key>creator</key>
<string>Icke</string>
<key>checksum</key>
<string>0x32</string>
<key>link</key>
<string>http://</string>
</dict>
</dict>
The problem: It works fine for one row (you can tell by looking at the console output, thrown up by NSLog(title); and NSLog(rowIndex);), however, after that, the debugger halts the execution, throwing up EXC_BAD_ACCESS. I know what that means, but I don't know why I'm getting this and how to fix this.
Thanks for any help. :)
you did over release here,
NSString *title = [[NSString stringWithString:[[aTableColumn headerCell] stringValue]] autorelease];
-[NSString stringWithString:] already autorelease the returned value, so you didn't need to call it again.

Implementing NSCoding protocol to send object over to the Java based server

I have asked a similar question a couple of days ago...
While I have made some progress, I still cant seem to make it work.
Here is what I got up till now:
customWriteableObj.h:
#interface customWriteableObj : NSObject <NSCoding>
#property int integer;
#property NSString * string;
#property BOOL boo;
#end
customWriteableObj.m:
#import "customWriteableObj.h"
#implementation customWriteableObj
-(id)init
{
_integer = 117;
_string = #"aString";
_boo = YES;
return self;
}
-(id)initWithCoder:(NSCoder *)aDecoder
{
_integer = [aDecoder decodeIntForKey:#"integer"];
_boo = [aDecoder decodeBoolForKey:#"boo"];
_string = [aDecoder decodeObjectForKey:#"string"];
return self;
}
-(void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.string forKey:#"string"];
[aCoder encodeBool:self.boo forKey:#"boo"];
[aCoder encodeInteger:self.integer forKey:#"integer"];
}
#end
main:
customWriteableObj * x = [[customWriteableObj alloc]init];
NSMutableData *dat = [[NSMutableData alloc] init];
NSKeyedArchiver* arch1 = [[NSKeyedArchiver alloc]initForWritingWithMutableData:dat];
arch1.outputFormat = NSPropertyListXMLFormat_v1_0;
[arch1 encodeObject:x forKey:#"tester1"];
[arch1 finishEncoding];
[dat writeToFile:#"text.xml";
customWriteableObj * y = [[customWriteableObj alloc]init];
y = [NSKeyedUnarchiver unarchiveObjectWithFile:#"text.xml";
Output in XML:
<?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>$archiver</key>
<string>NSKeyedArchiver</string>
<key>$objects</key>
<array>
<string>$null</string>
<dict>
<key>$class</key>
<dict>
<key>CF$UID</key>
<integer>3</integer>
</dict>
<key>boo</key>
<true/>
<key>integer</key>
<integer>117</integer>
<key>string</key>
<dict>
<key>CF$UID</key>
<integer>2</integer>
</dict>
</dict>
<string>aString</string>
<dict>
<key>$classes</key>
<array>
<string>customWriteableObj</string>
<string>NSObject</string>
</array>
<key>$classname</key>
<string>customWriteableObj</string>
</dict>
</array>
<key>$top</key>
<dict>
<key>tester1</key>
<dict>
<key>CF$UID</key>
<integer>1</integer>
</dict>
</dict>
<key>$version</key>
<integer>100000</integer>
</dict>
</plist>
which doesnt seem to be correct, since I cant see any data here, plus, when I try to read it back I get a nil!
I also need to persist this object to a database on a java based server...
At a glance it looks like you are missing the super calls in your init methods. This means you overrode these initialization methods and never actually initialize an object. So when you deserialize you would just end up with nil. This should fix it:
-(id)init
{
if(self = [super init])
{
_integer = 117;
_string = #"aString";
_boo = YES;
}
return self;
}
-(id)initWithCoder:(NSCoder *)aDecoder
{
if(self = [self init])
{
_integer = [aDecoder decodeIntForKey:#"integer"];
_boo = [aDecoder decodeBoolForKey:#"boo"];
_string = [aDecoder decodeObjectForKey:#"string"];
}
return self;
}
EDIT with JSON serialization example
Create a method on your custom object class that converts the object into a serializable dictionary. It might look something like:
- (NSDictionary *) jsonDictionary
{
return #{#"integer": #(_integer), #"boo": #(_boo), #"string" : _string};
}
Then just call that iteratively on all the objects in your array whenever you are ready to send them over. That might look something like:
// Assuming you have an NSArray called customObjects
NSMutableArray *customObjectsJSON = [[NSMutableArray alloc] initWithCapacity:customObjects.count];
for(customWriteableObj *object in customObjects)
{
[customObjectsJSON addObject:[object jsonDictionary]];
}
At this point, customObjectsJSON is ready to be set as a parameter for a network request. Depending on what other tools you are using you may need to convert it to JSON yourself using NSJSONSerialization
It looks correct. In the XML you can see your 117 and aString values. The XML is a custom format so you generally shouldn't be trying to use it for anything other than storing and reloading.
Your result object when you try to load the archive back in is nil because you are reloading differently than you are archiving (in terms of structure). If you are archiving with [arch1 encodeObject:x forKey:#"tester1"]; then you need to unarchive with initForReadingWithData: and decodeObjectForKey:.

How come reading from a plist fails in my iOS application?

I am trying to create an NSMutableDictionary containing a list of animals in my iOS app with this function.
// puts animals into dictionary
- (void) putAnimalsFromPlistToDictionary
{
NSBundle *bundle = [NSBundle mainBundle];
NSString *path = [bundle pathForResource:#"myAnimals" ofType:#"plist"];
myAnimalDictionary = [[NSMutableDictionary alloc] initWithContentsOfFile:path];
// I set a breakpoint here in XCode.
}
I dragged myAnimals.plist (which looks like the below) into my supporting files folder for my application.
<?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">
<array>
<string>elephant</string>
<string>monkey</string>
<string>cat</string>
</array>
</plist>
However, when I reach the breakpoint (as listed in my comment), I see that myAnimalDictionary is nil. Why?
Perhaps it's because you have an array in your .plist but you're trying to instantiate a mutable dictionary instance.

opening files with different extensions with Cocoa

I have an NSDocument based app that already handles *.txt files. I can drag and drop those files in the dock and my app will launch correctly.
Now I want to be able to open *.text files too. So I have added:
<key>CFBundleTypeExtensions</key>
<array>
<string>.txt</string>
<string>.text</string>
</array>
to my *plist
However I can't open *.text files by drag&dropping them in the dock. (I can do MyApp> File>Open> myFile.text )
I can open *.txt as usual, and drag and drop them in the dock.
I have tried implementing these NSApp delegate methods but now I get an error and I can't open any kind of file.
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename{
NSURL *url = [NSURL URLWithString:filename];
NSError *error = nil;
[[NSDocumentController sharedDocumentController] openDocumentWithContentsOfURL:url display:YES error:&error];
if (error) {
NSLog(#"error: %#", [error localizedDescription]);
error = nil;
return NO;
}
return YES;
}
- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames{
for (NSString *filename in filenames) {
[self application:sender openFile:filename];
}
}
Error:
typeForContentsOfURL:error: must be
overridden for your application to
support non-'file:' URLs.
I am not subclassing NSDocumentController, so do I really need to? or is there a better/easier way of doing this?
Thanks in advance
The file extensions in the Info.plist file should not contain a period character (.). What happens if you do this?:
<key>CFBundleTypeExtensions</key>
<array>
<string>txt</string>
<string>text</string>
</array>