iphone4 短信截获

所谓的短信截获,可以被程序提前接受到,经过过滤以及相应的处理,然后发送到手机的收件箱中。

ios3上的短信截获通过可以通过一些私有的api即可完成,网上的教程也较多,这里不在重复。

前段时间在调研的ios4上的短信截获,在网上也很难找到相应的,较完整的资料,刚好前段时间学习了hook,

故周末抽了点时间使用hook重新调研了下,这里做个记录,以防止后期遗忘.

测试环境: iphone4 ios4.3.2 已越狱

1. 搭建hook demo开发环境,可以参照我的另一篇文章,这里不再重复。对接受短信的函数进行hook,并进行相应处理与过滤,在通过到手机上。

2. class-dump SMSCTServer.framework, ChatKit.framework, CoreTelephony.framework等framework

其中SMSCTServer.framework中主要包含一些短信发送与接受相关的Api, ChatKit较复杂,其中CKSMSService.h包含很多相应的操作,

例如markAllMessagesInConversationAsRead则是当第一次阅读短信时设置标志位为阅读状态。

CoreTelephony.framework已在ios4上面开放,但是依然有很多的私有api没有被apple开放出来,需要自己测试。

将上面三个库倒出来的头文件加入XCode的编译搜索路径当中,当使用某个类的时候,就可以直接进行#import,此时当然会遇到一些编译错误,

此时需要考虑相对路径与绝对路径,对framework内部的一些#import进行处理。不过好处在于只有你#import某个头文件时,才会去检查这个

头文件内部的语法结构,这就不需要去手动处理所有的framework中的头文件。

3. 环境都搭建好了,接下来就需要去查询可能涉及到的函数,并对其进行hook。

在这里我推荐使用命令grep进行查询,例如查找sendMessage函数,使用grep sendMessage . -r就可以列出所有的包含有这个单词的相关内容。

便于高效快速的去获取到需要的信息。

4. 通过第3步,相信会对一些函数的作用产生怀疑,这个函数到底是不是接受短信的api呢?验证真理最好的办法就是测试。对这些函数进行hook,

并在其中加上一些打印,便可以试验出这些函数的可能功能。

5. 最后得出当接受短信时,由于framework中的函数众多,我只是hook了部分值得怀疑的函数。

- (void)_processReceivedMessageWithInfo:(struct __CFDictionary *)arg1;

- (void)_ingestIncomingCTMessage:(id)arg1;

- (void)_receivedMessage:(struct __CKSMSRecord *)arg1 replace:(BOOL)arg2; 

当短信到来时,会至上而下的执行这些函数。在_ingestIncomingCTMessage可以对短信是否发送到手机上进行控制。如果在_processReceivedMessageWithInfo

函数中进行过滤的话,短信在当前确实不会到来,但是重启手机之后,短信其实已经到达收件箱了,只是没有收到通知而已,显然我们想要的不仅仅这么多。

hook的代码如下:

[plain]  view plain copy
  1. extern "C" void replaced_SMSCTServer_ingestIncomingCTMessage(SMSCTServer *self, SEL cmd, id arg1)  
  2. {  
  3.     NSLog(@"--------------------------------replaced_SMSCTServer_ingestIncomingCTMessage enter, arg1 =%@", arg1);  
  4.        
  5.        
  6.     NSLog(@"===================replaced_SMSCTServer_ingestIncomingCTMessage==============NSStringFromClass([arg1 class]) = %@", NSStringFromClass([arg1 class]));  
  7.        
  8.     CTMessage *message = (CTMessage *)arg1;  
  9.        
  10.     CTPhoneNumber *sender = (CTPhoneNumber *)message.sender;  
  11.     NSString *digits = sender.digits;       // 电话号码  
  12.     NSString *countryCode = sender.countryCode;  
  13.     NSDate *date = message.date;  
  14.        
  15.     NSArray *items = message.items;  
  16.        
  17.     for(CTMessagePart *part in items)  
  18.     {  
  19.         NSData *data = part.data;  
  20.         NSLog(@"=====================data = %@", data);  
  21. //        NSLog(@"====================smsData = %@", [CTMmsEncoder decodeMessageFromData:data]);  
  22.            
  23.     }  
  24.        
  25.     NSLog(@"=============countryCode = %@, digits = %@, date = %@", countryCode, digits, date);  
  26.     NSLog(@"-----------------------------message = %@, sender = %@", message, sender);  
  27.        
  28.     // 在此处可以进行短信的成功截获,利用arg1包含的一些短信信息确认是否应该接受该信息  
  29.     if([@"1065583393" isEqualToString:digits])  
  30.     {  
  31.         NSLog(@"---------------------------------------------不允许接受该电话号码的短信.");  
  32. // 对新短信的到来给予提示  
  33.    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"垃圾短信(%@)", digits] message:[NSString stringWithFormat:@"短信发送日期:%@", date] delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];  
  34.    [alertView show];  
  35.    [alertView release];  
  36. <span class="Apple-style-span" style="font-family: verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; white-space: normal;"></span>        return;  
  37.     }  
  38.        
  39.     original_SMSCTServer_ingestIncomingCTMessage(self, cmd, arg1);  
  40. }  

这个地方进行一些短信内容的解析工作,如上,1065583393这个号码进行骚扰我,每隔一两天就给我发垃圾短信,如此的话,这个号码再也不会给我发送短信啦。这里的号码就相当于黑名单,可以通过程序进行设置,然后在这里获取相应的号码,并进行过滤。

代码中的UIAlertView会对不打算接受的垃圾短信的到来进行提醒,但是不会去接受。(只是一个测试,别太介意)

参数arg1是CTMessage类型的,包含短信的发送号码,日期,内容等等信息。不过在我使用CTMmsEncoder去对短信内容进行解析时候,提示该类不存在,但是哪个NSData应该就是短信内容的data,对于每条短信的长短NSData的数据长短也不一致。

例如SMSCTServer 的playMessageSent会对发送短信成功的一些提示音进行控制, 不给与返回的话,短信发送出去也不会出现声音

[plain]  view plain copy
  1. // 控制短信发送完成播放声音  
  2. extern "C" void replaced_SMSCTServer_playMessageSent(SMSCTServer *self, SEL cmd)  
  3. {  
  4.     NSLog(@"--------------------------------replaced_SMSCTServer_playMessageSent enter ");  
  5.      
  6.     original_SMSCTServer_playMessageSent(self, cmd);  
  7. }  

hook确实可以完成很多强大的功能,私有api,framework,hook,水够深呀!

暂时先做这些吧,等有时间的时候,把每次收到短信,那暴力的提示框给干掉,世界清静了!

http://www.cnblogs.com/ydhliphonedev/archive/2011/10/23/2221965.html



首先添加coreTelephony.framework

[cpp]  view plain copy
  1. #import <UIKit/UIKit.h>    
  2. #include <notify.h>    
  3. #include <stdio.h>    
  4. #include <stdarg.h>    
  5. #include <string.h>    
  6. typedef struct __CTSMSMessage CTSMSMessage;    
  7. NSString *CTSMSMessageCopyAddress(void *, CTSMSMessage *);    
  8. NSString *CTSMSMessageCopyText(void *, CTSMSMessage *);    
  9. id CTTelephonyCenterGetDefault(void);    
  10. void CTTelephonyCenterAddObserver(id,id,CFNotificationCallback,NSString*,void*,int);    
  11. void dolog(id formatstring,...)    
  12. {    
  13.     va_list arglist;    
  14.     if (formatstring)    
  15.     {    
  16.         va_start(arglist, formatstring);    
  17.         id outstring = [[NSString alloc] initWithFormat:formatstring arguments:arglist];    
  18.         printf("%s\n", [outstring UTF8String]);    
  19.         va_end(arglist);    
  20.     }    
  21. }    
  22. static void callback(CFNotificationCenterRef center,    
  23.                      void *observer, CFStringRef name,    
  24.                      const void *object, CFDictionaryRef userInfo)    
  25. {    
  26.         
  27.     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];    
  28.     // printf("NOTIFICATION: %s\n", [name UTF8String]);    
  29.     if (!userInfo) return;    
  30.         
  31.     NSDictionary *info = (NSDictionary*)userInfo;    
  32.     int dcount = CFDictionaryGetCount(userInfo);    
  33.     id keys = [(NSDictionary*)userInfo allKeys];    
  34.     int i;    
  35.     for (i = 0; i < dcount; i++)    
  36.     {    
  37.         id key = [keys objectAtIndex:i];    
  38.         dolog(@"  %@: %@", key, [info objectForKey:key]);    
  39.     }        
  40.         
  41.         
  42.     if ([[(NSDictionary *)userInfo allKeys]    
  43.          containsObject:@"kCTSMSMessage"]) // SMS Message    
  44.     {    
  45.         CTSMSMessage *message = (CTSMSMessage *)    
  46.         [(NSDictionary *)userInfo objectForKey:@"kCTSMSMessage"];    
  47.         NSString *address = CTSMSMessageCopyAddress(NULL, message);    
  48.         NSString *text = CTSMSMessageCopyText(NULL, message);    
  49.         NSArray *lines = [text componentsSeparatedByString:@"\n"];    
  50.             
  51.         printf("  %s %d\n", [address cString], [lines count]);    
  52.         printf("  %s\n", [text cString]);    
  53.         fflush(stdout);    
  54.     }    
  55.         
  56.     [pool release];    
  57.         
  58.     return ;    
  59. }    
  60. static void signalHandler(int sigraised)    
  61. {    
  62.     printf("\nInterrupted.\n");    
  63.     exit(0);    
  64. }    
  65. int main(int argc, char **argv)    
  66. {    
  67.     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];    
  68.         
  69.     // Initialize listener by adding CT Center observer implicit    
  70.     id ct = CTTelephonyCenterGetDefault();    
  71.     CTTelephonyCenterAddObserver( ct, NULL, callback,NULL,NULL,    
  72.                                  CFNotificationSuspensionBehaviorHold);    
  73.         
  74.     // Handle Interrupts    
  75.     sig_t oldHandler = signal(SIGINT, signalHandler);    
  76.     if (oldHandler == SIG_ERR)    
  77.     {    
  78.         printf("Could not establish new signal handler");    
  79.         exit(1);    
  80.     }    
  81.         
  82.     // Run loop lets me catch notifications    
  83.     printf("Starting run loop and watching for notification.\n");    
  84.     CFRunLoopRun();    
  85.         
  86.     // Shouldn't ever get here. Bzzzt    
  87.     printf("Unexpectedly back from CFRunLoopRun()!\n");    
  88.     [pool release];    
  89. }    

你可能感兴趣的:(iphone4 短信截获)