在使用Cycript完成核心功能的测试后,用Theos编写代码就仅仅是简单的体力劳动了。本节,就用最直观的代码,给MobileSMS中的SMSApplication类添加2个实例函数,分别是“-(int)madridStatusForAddress:(NSString*)address”和“-(void)sendMadridMessage ToAddress:(NSString*)address withText:(NSString*)text”,然后用Cycript测试这2个类函数的有效性。开始行动!
新建iOSREMadridMessenger工程的命令如下:
snakeninnys-MacBook:Code snakeninny$ /opt/theos/bin/nic.pl NIC 2.0 - New Instance Creator ------------------------------ [1.] iphone/application [2.] iphone/cydget [3.] iphone/framework [4.] iphone/library [5.] iphone/notification_center_widget [6.] iphone/preference_bundle [7.] iphone/sbsettingstoggle [8.] iphone/tool [9.] iphone/tweak [10.] iphone/xpc_service Choose a Template (required): 9 Project Name (required): iOSREMadridMessenger Package Name [com.yourcompany.iosremadridmessenger]: com.iosre.iosremadridmessenger Author/Maintainer Name [snakeninny]: snakeninny [iphone/tweak] MobileSubstrate Bundle filter [com.apple.springboard]: com.apple.MobileSMS [iphone/tweak] List of applications to terminate upon installation (space-separated, '-' for none) [SpringBoard]:MobileSMS Instantiating iphone/tweak in iosremadridmessenger/... Done.
在10.2节的检测及10.3节的发送中,用到了私有框架IDS、ChatKit和IMCore中的多个私有类和私有函数,我们必须给出它们的定义,才能避免编译器报错或警告。当然,iOSREMadridMessenger.h的内容并不是凭空构造出来的,所有的定义均来自于class-dump出的头文件,我们只是把用到的东西挑选出来,再整合到一个头文件里而已——我们构造的只是一个“精选头文件”。编辑后的iOSREMadridMessenger.h内容如下:
@interface IDSIDQueryController + (instancetype)sharedInstance; - (NSDictionary *)_currentIDStatusForDestinations:(NSArray*)arg1 service:(NSString *)arg2 listenerID:(NSString *)arg3; @end @interface IMServiceImpl : NSObject + (instancetype)iMessageService; @end @class IMHandle; @interface IMAccount : NSObject - (IMHandle *)imHandleWithID:(NSString *)arg1 alreadyCanonical:(BOOL)arg2; @end @interface IMAccountController : NSObject + (instancetype)sharedInstance; - (IMAccount *)__ck_defaultAccountForService:(IMServiceImpl*)arg1; @end @interface IMMessage : NSObject + (instancetype)instantMessageWithText:(NSAttributedString*)arg1 flags:(unsigned long long)arg2; @end @interface IMChat : NSObject - (void)sendMessage:(IMMessage *)arg1; @end @interface IMChatRegistry : NSObject + (instancetype)sharedInstance; - (IMChat *)chatForIMHandle:(IMHandle *)arg1; @end
编辑后的Tweak.xm内容如下:
#import "iOSREMadridMessenger.h" %hook SMSApplication %new - (int)madridStatusForAddress:(NSString *)address { NSString *formattedAddress = nil; if ([address rangeOfString:@"@"].location != NSNotFound) formattedAddress = [@"mailto:" stringByAppendingString:address]; else formattedAddress = [@"tel:" stringByAppendingString:address]; NSDictionary *status = [[IDSIDQueryController sharedInstance] _current IDStatusForDestinations:@[formattedAddress] service:@"com.apple.madrid" listenerID: @"__kIMChatServiceForSendingIDSQueryControllerListenerID"]; return [status[formattedAddress] intValue]; } %new - (void)sendMadridMessageToAddress:(NSString *)address withText:(NSString *)text { IMServiceImpl *service = [IMServiceImpl iMessageService]; IMAccount *account = [[IMAccountController sharedInstance] __ck_defaultAccountForService:service]; IMHandle *handle = [account imHandleWithID:address alreadyCanonical:NO]; IMChat *chat = [[IMChatRegistry sharedInstance] chatForIMHandle:handle]; NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString: text]; IMMessage *message = [IMMessage instantMessageWithText:attributedString flags: 100005]; [chat sendMessage:message]; [attributedString release]; } %end
编辑后的Makefile内容如下:
THEOS_DEVICE_IP = iOSIP ARCHS = armv7 arm64 TARGET = iphone:latest:8.0 include theos/makefiles/common.mk TWEAK_NAME = iOSREMadridMessenger iOSREMadridMessenger_FILES = Tweak.xm iOSREMadridMessenger_PRIVATE_FRAMEWORKS = IDS ChatKit IMCore include $(THEOS_MAKE_PATH)/tweak.mk after-install:: install.exec "killall -9 MobileSMS"
编辑后的control内容如下:
Package: com.iosre.iosremadridmessenger Name: iOSREMadridMessenger Depends: mobilesubstrate, firmware (>= 8.0) Version: 1.0 Architecture: iphoneos-arm Description: Detect and send iMessage example Maintainer: snakeninny Author: snakeninny Section: Tweaks Homepage: http://bbs.iosre.com
将写好的tweak编译打包安装到iOS后,执行ssh命令连接到iOS中,然后执行如下代码:
FunMaker-5:~ root# cycript -p MobileSMS cy# [UIApp madridStatusForAddress:@"snakeninny@icloud.com"] 1 cy# [UIApp sendMadridMessageToAddress:@"snakeninny@icloud.com" withText:@"Sent from iOSREMadridMessenger"]
“snakeninny@icloud.com”的检测结果是1,支持iMessage,且此条iMessage被成功发送,如图10-98所示。
图10-98 成功发送iMessage
如果你按照上面的思路和方法成功搞定了iMessage的检测和发送,就给“snakeninny@gmail.com”发一条iMessage吧!