MFMessageComposeViewController的入侵攻击

8

我知道在真实的应用程序中,这是不允许的,因为需要保护用户的隐私和安全。但出于纯学术目的,我正在尝试像这样发送消息而不显示MessageComposer UI。

MFMessageComposeViewController *picker = [[MFMessageComposeViewController alloc] init];

if([MFMessageComposeViewController canSendText]) {
    picker.recipients = [NSArray arrayWithObject:@"1234"];
    picker.body = @"Hello";
    [picker performSelector:@selector(smsComposeControllerSendStarted:) withObject:[UIButton buttonWithType:UIButtonTypeCustom]];
}

没有任何反应。控制台上甚至没有失败异常。短信应用程序也没有显示任何消息。我发送的信息的接收者也没有收到。

可以在此处找到MFMessageComposeViewController的iVars和Methods列表。

https://github.com/nst/iOS-Runtime-Headers/blob/master/Frameworks/MessageUI.framework/MFMessageComposeViewController.h

我编写了一个快速代码来验证这些是否实际存在于MFMessageComposeViewController中。

uint varCount = 0;
Class cls= [MFMessageComposeViewController class];
Ivar *vars =  class_copyIvarList(cls, &varCount);

for (uint i = 0; i < varCount; i++) {
   Ivar var = vars[i];
   const char* name = ivar_getName(var);
   const char* typeEncoding = ivar_getTypeEncoding(var);
   printf("iVar%i------------> %s\n",i+1,name);
}    
free(vars);

Method *imps = class_copyMethodList(cls, &varCount);
for (uint i = 0; i < varCount; i++) {
    SEL sel = method_getName(imps[i]);        
    printf("Method%i------------> %s\n",i+1,[(NSStringFromSelector(sel)) UTF8String]);
}

它生成以下输出:
iVar1------------> _messageComposeDelegate
iVar2------------> _recipients
iVar3------------> _body
iVar4------------> _subject
iVar5------------> _mutableAttachmentURLs
iVar6------------> _currentAttachedVideoCount
iVar7------------> _currentAttachedAudioCount
iVar8------------> _currentAttachedImageCount
iVar9------------> _temporaryAttachmentURLs
iVar10------------> _attachments
Method1------------> disableUserAttachments
Method2------------> setCurrentAttachedVideoCount:
Method3------------> setCurrentAttachedAudioCount:
Method4------------> setCurrentAttachedImageCount:
Method5------------> _MIMETypeForURL:
Method6------------> _isVideoMIMEType:
Method7------------> _isAudioMIMEType:
Method8------------> _isImageMIMEType:
Method9------------> mutableAttachmentURLs
Method10------------> _contentTypeForMIMEType:
Method11------------> _updateAttachmentCountForAttachmentURL:
Method12------------> _buildAttachmentInfoForAttachmentURL:andAlternameFilename:
Method13------------> temporaryAttachmentURLs
Method14------------> canAddAttachmentURL:
Method15------------> addAttachmentData:withAlternateFilename:
Method16------------> _setCanEditRecipients:
Method17------------> messageComposeDelegate
Method18------------> setMutableAttachmentURLs:
Method19------------> currentAttachedVideoCount
Method20------------> currentAttachedAudioCount
Method21------------> currentAttachedImageCount
Method22------------> setTemporaryAttachmentURLs:
Method23------------> dealloc
Method24------------> viewWillAppear:
Method25------------> initWithNibName:bundle:
Method26------------> automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers
Method27------------> setModalPresentationStyle:
Method28------------> body
Method29------------> setSubject:
Method30------------> subject
Method31------------> setMessageComposeDelegate:
Method32------------> setBody:
Method33------------> addAttachmentURL:withAlternateFilename:
Method34------------> addAttachmentData:typeIdentifier:filename:
Method35------------> attachmentURLs
Method36------------> attachments
Method37------------> recipients
Method38------------> smsComposeControllerCancelled:
Method39------------> smsComposeControllerSendStarted:
Method40------------> setRecipients:

我认为smsComposeControllerSendStarted:方法更像是代理而不是真正启动消息发送的功能。在上面的方法列表中,没有一种方法签名看起来更接近sendMessage:或类似于实际发送消息的函数。

我的问题是:

1)这确实是MFMessageComposeViewController在代码内部所拥有的全部内容吗?还是它有一些类群集,无法通过运行时函数访问?

2)如何找到实际的messageSend方法及其实现类?

任何想法都将不胜感激。

谢谢。


1
MFMessageComposeViewController是由XPC服务提供的远程视图控制器,旨在使您尝试的操作变得困难。 - quellish
1个回答

7
MFMessageComposeViewController 内部,使用来自私有的 ChatKit.framework 的实际 UI CKSMSComposeController,该框架使用了许多其他类(CKSMSComposeQueuingRemoteViewControllerProxyCKSMSComposeRemoteViewControllerCKSMSComposeViewServiceController),包括 XPC 接口 XPCProxy<CKSMSCompose>
在阅读quellish的评论后,我发现了这篇文章http://oleb.net/blog/2012/10/remote-view-controllers-in-ios-6/。看起来像MFMessageComposeViewController和类似的类会为其目的启动另一个进程。这些进程是实现特定协议的XPC服务,通过这些协议,您的应用程序与它们进行通信。这些进程已签署所有必需的授权。可能/Applications/MessagesViewService.app/MessagesViewService实际上是发送短信的程序。这个二进制文件已签署了com.apple.messages.composeclient,这是使用this ChatKit.framework中找到的代码发送消息所必需的。我认为有一种方法可以手动与该XPC服务通信以发送短信,但这将很困难。这不是您可以使用类转储和类似的简单工具轻松完成的事情,因为它们并不能提供太多信息。

更新2

我已经找到了问题的根源。我丢弃了所有助手类和与XPC服务没有真正通信的所有UI元素。剩下的足以显示SMS视图控制器并向XPC服务发送一些方法,而不会有任何阻碍。
当我们显示SMS组合UI时,iOS确实启动/Applications/MessagesViewService.app/MessagesViewService进程。那就是XPC服务。您可以在应用程序显示它时尝试杀死它-您将获得黑屏,这意味着它是正确的。 CKSMSComposeRemoteViewController是显示SMS UI的视图控制器。它是_UIRemoteViewController类的子类。基本上,它管理我们的应用程序与在其他进程中运行的XPC服务内部实际UI之间的连接。这是我如何在我的-(void)viewDidLoad方法中获取它的实例。
_UIAsyncInvocation* cancelationInvocation = 
[CKSMSComposeRemoveViewController requestViewController:@"CKSMSComposeViewServiceController"
                        fromServiceWithBundleIdentifier:@"com.apple.mobilesms.compose"
                        connectionHandler:
^(CKSMSComposeRemoteViewController* obj, NSError* error){
    smsViewController = obj;
    [smsViewController setDelegate:self];

    smsViewControllerProxy = [smsViewController serviceViewControllerProxy];
}]; 

smsViewController是一个远程视图控制器实例。 smsViewControllerProxy 是一个 XPCProxy<CKSMSCompose> 实例,它实现了 CKSMSComposeViewServiceProtocol 协议 - 方法调用将转发到 XPC 服务。 XPCProxy 并没有真正实现这些方法。它实现了 forwardInvocation: 方法以便将调用转发到 XPC 连接。

_UIAsyncInvocation,根据 ivar 名称 cancelationInvocation,用于取消 XPC 消息。它只会在 CKSMSComposeController viewServiceDidTerminateWithError: 方法中被调用。

这是我如何显示控制器的方式:

[self presentViewController:smsViewController animated:YES completion:NULL];

您可能已经注意到了[smsViewController setDelegate:self]。委托必须实现CKSMSComposeRemoteViewControllerDelegate协议,否则应用程序将因异常(未识别的选择器)而崩溃。以下是我实现的内容:
-(void)smsComposeControllerAppeared
{
}

-(void)smsComposeControllerCancelled
{
}

-(void)smsComposeControllerDataInserted
{
}

那已经足够开始了。
以下是如何向远程视图控制器发送消息的方法:
[smsViewControllerProxy insertTextPart:@"Some text"];

这将把文本插入到短信文本字段中,并调用smsComposeControllerDataInserted委托方法。

考虑到所有这些,我不再认为我们可以在没有UI的情况下发送短信。实际的UI运行在另一个进程中,我们无法控制它。我们可以设置一些字段,但仅此而已。我曾希望有一种方法,但事实是,难怪我们不能。远程视图是在iOS 6中引入的,以解决这个确切的安全问题 - 在iOS 5中,有一种方法可以在没有用户许可的情况下发送短信,一些AppStore应用程序也会这样做。所以向苹果致敬。

更新3

我已经成功拦截到与SMS UI交互时发送的XPC消息。关于日志格式,第一行显示消息被拦截的位置。它可以是函数名,也可以是“Incoming event”,表示这是来自服务的传入消息。“Connection name”只是XPC连接名称。“Message”是XPC消息字典内容。“Message data”- 一些XPC消息包含二进制数据在“d” -> “r”键中。这是一个序列化的二进制属性列表,不能使用“NSPropertyListSerialization”反序列化 - 它采用了一些新格式。相反,您需要使用Foundation.framework中的“NSXPCDecoder-(id)_initWithRootXPCObject:(xpc_object_t)”方法进行解码。现在是转储内容:
SMS UI展示:http://pastebin.com/NVEpujSh 按下“发送”按钮后的SMS UI:http://pastebin.com/BYXd2djF 你编辑短信字段时会发送和接收消息,但这些消息仅与UI事件对应。例如,成为第一个响应者的人,这些内容并不能真正反映SMS UI中正在发生的事情。

1
继续保持好工作,Creker。你知道BiteSMS Cydia应用程序是如何工作的吗? - Selvin
通过越狱,您可以使用此链接中的方法在越狱设备上编程发送短信:https://dev59.com/dGUo5IYBdhLWcg3wpg0f?lq=1 - creker
汪,这是硬核的。 - duhaime

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接