iphone4 系统ios4电话截获

转自:http://www.cnblogs.com/ydhliphonedev/archive/2011/10/24/2223242.html

http://blog.csdn.net/laigb/article/details/6623068

开发环境: iphone4 (ios4.3.2)

使用hook截获系统处理通知事件,然后进行相应的处理来达到截获的效果。目前的截获不是很完美,黑名单中的人打电话时会先出现“嘟.."声之后才会提示所拨打的用户正在通话中……

前提:需要class-dump CoreTelephony framework,并配置hook开发环境

1. 在说截获之前,先说说dlsym的使用

我们通常会在网上看到一些函数具有我们需要的功能,然后我们在class-dump出的头文件中查找去找不到,但是使用grep在framework中确实可以搜索到相应的符号,导致使用上出现一些麻烦。此时我们就可以使用dlsym来从动态库中获取相应的函数。

2. 挂断电话的函数

 

  1.  1 // CoreTelephony framework在系统中的路径  
  2.  2 #define CTPATH  "/XCode4.0andIphoneSDK4.3/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/System/Library/Frameworks/CoreTelephony.framework/CoreTelephony"  
  3.  3   
  4.  4 // 挂断电话函数  
  5.  5 - (BOOL)disconnectCall:(id)call  
  6.  6 {  
  7.  7     void *framework = dlopen(CTPATH, RTLD_LAZY);  
  8.  8     id (*CTCallDisconnect)(id) = dlsym(framework, "CTCallDisconnect");  
  9.  9     CTCallDisconnect(call);  
  10. 10     dlclose(framework);  
  11. 11     return YES;  
  12. 12 }  

 

 

CTCallDisconnect为挂断电话的函数,但是却没有在头文件中找到相应的声明,故使用dlsym来获取函数指针,进而来使用该函数。
disconnectCall被我定义在Util.m中,做为一个object clss去使用的,不过最好还是定义成C类型的,比较方便使用。
disconnectCall作为挂断电话的函数在下面的截获实现中会使用到。
dlopen等函数在#include <dlfcn.h>头文件中, dlopen之后一定要dlclose去关闭,否则会出现一些问题。
3. 截获电话通知处理事件
CTCallCenter中有些函数是对电话的状态进行通知的,故对CTCallCenter中的handleNotificationFromConnection进行了处理,代码如下:
  1.  1 extern "C" void replaced_CTCallCenter_handleNotificationFromConnection(CTCallCenter *self, SEL cmd, void *arg1, id arg2, id arg3)  
  2.  2 {  
  3.  3 //    NSLog(@"------------------------------------------replaced_CTCallCenter_handleNotificationFromConnection, arg1 = %@, arg2 = %@, arg3 = %@", arg1, arg2, arg3);  
  4.  4       
  5.  5 //    NSLog(@"------------arg2Type = %@, arg3Type = %@", NSStringFromClass([arg2 class]), NSStringFromClass([arg3 class]));  
  6.  6       
  7.  7     NSDictionary *dic = (NSDictionary *)arg3;  
  8.  8       
  9.  9     // 此处获得电话状态,CTCallStateDialing, CTCallStateIncoming, CTCallStateConnected, CTCallStateDisconnected等,定义在CTCallCenter.h(非class-dump的头文件)中  
  10. 10     NSLog(@"-------kCTCallStatus = %@", [dic objectForKey:@"kCTCallStatus"]);  
  11. 11       
  12. 12     NSLog(@"--------currentCalls = %@, callEventHandler = %@", self.currentCalls, self.callEventHandler);  
  13. 13       
  14. 14     // 获得CTCall对象  
  15. 15     CTCall *call = [dic objectForKey:@"kCTCall"];  
  16. 16       
  17. 17 //    NSLog(@"------callId = %@, callState = %@", call.callID, call.callState);  
  18. 18       
  19. 19     // 这里可以根据kCTCallStatus来判断需要进行的操作  
  20. 20     if (call.callState == CTCallStateDialing)  
  21. 21     {   
  22. 22         NSLog(@"Call has been CTCallStateDialing");  
  23. 23     }  
  24. 24     else if (call.callState == CTCallStateIncoming)   
  25. 25     {  
  26. 26         NSLog(@"Call has just been CTCallStateIncoming");  
  27. 27         //这儿可接可挂  
  28. 28         // 挂断电话  
  29. 29         BOOL flag = [Util disconnectCall:call];  
  30. 30         NSLog(@"----------------是否挂断. flag = %d", flag);  
  31. 31     }  
  32. 32     else if(call.callState == CTCallStateConnected)  
  33. 33     {  
  34. 34         NSLog(@"Call is CTCallStateConnected");  
  35. 35     }  
  36. 36     else if (call.callState == CTCallStateDisconnected)  
  37. 37     {  
  38. 38         NSLog(@"Call is CTCallStateDisconnected");  
  39. 39     }  
  40. 40     else  
  41. 41     {  
  42. 42           
  43. 43         NSLog(@"None of the conditions");  
  44. 44           
  45. 45     }  
  46. 46       
  47. 47     original_CTCallCenter_handleNotificationFromConnection(self, cmd, arg1, arg2, arg3);  
  48. 48 }  

 

 

上面的代码会对所有的电话都进行过滤处理,电话也都打不进来的,但是会留下一个未接电话。
此处只是提供一个思路,具体的截获需要对传进来的参数等等进行一些解析,并提供一些细致的处理。
在CoreTelephony framework中还含有其他的一些函数,例如对于电话状态改变等等的都可以去细致的研究下,相信会有很大的收获

 

  1. extern NSString* const kCTSMSMessageReceivedNotification;    
  2. extern NSString* const kCTSMSMessageReplaceReceivedNotification;    
  3. extern NSString* const kCTSIMSupportSIMStatusNotInserted;    
  4. extern NSString* const kCTSIMSupportSIMStatusReady;     
  5.     
  6.     
  7.     
  8. typedef struct __CTCall CTCall;    
  9. extern NSString *CTCallCopyAddress(void*, CTCall *);    
  10.     
  11. void* CTSMSMessageSend(id server,id msg);    
  12. typedef struct __CTSMSMessage CTSMSMessage;      
  13. NSString *CTSMSMessageCopyAddress(void *, CTSMSMessage *);      
  14. NSString *CTSMSMessageCopyText(void *, CTSMSMessage *);    
  15.     
  16.     
  17. int CTSMSMessageGetRecordIdentifier(void * msg);    
  18. NSString * CTSIMSupportGetSIMStatus();      
  19. NSString * CTSIMSupportCopyMobileSubscriberIdentity();     
  20.     
  21. id  CTSMSMessageCreate(void* unknow/*always 0*/,NSString* number,NSString* text);    
  22. void * CTSMSMessageCreateReply(void* unknow/*always 0*/,void * forwardTo,NSString* text);    
  23.     
  24.     
  25. id CTTelephonyCenterGetDefault(void);    
  26. void CTTelephonyCenterAddObserver(id,id,CFNotificationCallback,NSString*,void*,int);    
  27. void CTTelephonyCenterRemoveObserver(id,id,NSString*,void*);    
  28. int CTSMSMessageGetUnreadCount(void);     
  29.     
  30. static void callback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)     
  31. {    
  32.     NSString *notifyname=(NSString *)name;    
  33.     if ([notifyname isEqualToString:@"kCTCallStatusChangeNotification"])//电话    
  34.     {    
  35.         NSDictionary *info = (NSDictionary*)userInfo;    
  36.             
  37.         NSString *state=[[info objectForKey:@"kCTCallStatus"] stringValue];    
  38.         if ([state isEqualToString:@"5"])//disconnect    
  39.             NSLog(@"未接:%@",state);    
  40.             
  41.     }    
  42.     else if ([notifyname isEqualToString:@"kCTCallIdentificationChangeNotification"])    
  43.     {    
  44. //        CTCallCenter *center = [[CTCallCenter alloc] init];    
  45. //        center.callEventHandler = ^(CTCall *call) {    
  46. //            NSLog(@"call:%@", [call description]);    
  47. //        };    
  48.             
  49.         NSDictionary *info = (NSDictionary *)userInfo;    
  50.         CTCall *call = (CTCall *)[info objectForKey:@"kCTCall"];    
  51.         NSString *caller = CTCallCopyAddress(NULL, call);    
  52.         NSLog(@"电话号码:%@",caller);    
  53.         //CTCallDisconnect(call);    
  54.         /* or one of the following functions: CTCallAnswer  
  55.          CTCallAnswerEndingActive  
  56.          CTCallAnswerEndingAllOthers  
  57.          CTCallAnswerEndingHeld  
  58.         */    
  59.             
  60.     }    
  61.     else if ([notifyname isEqualToString:@"kCTRegistrationDataStatusChangedNotification"])    
  62.     {    
  63.             
  64.     }    
  65.     else if ([notifyname isEqualToString:@"kCTSMSMessageReceivedNotification"])    
  66.     {//api 已过期    
  67.         if ([[(NSDictionary *)userInfo allKeys]      
  68.              containsObject:@"kCTSMSMessage"]) // SMS Message      
  69.         {      
  70.             CTSMSMessage *message = (CTSMSMessage *)      
  71.             [(NSDictionary *)userInfo objectForKey:@"kCTSMSMessage"];      
  72.             NSString *address = CTSMSMessageCopyAddress(NULL, message);      
  73.             NSString *text = CTSMSMessageCopyText(NULL, message);      
  74.             //NSArray *lines = [text componentsSeparatedByString:@"\n"];      
  75.                 
  76.             //printf("  %s %d\n", [address cString], [lines count]);      
  77.             //printf("  %s\n", [text cString]);      
  78.             fflush(stdout);      
  79.             
  80.         }    
  81.     }    
  82.     else if ([notifyname isEqualToString:@"kCTMessageReceivedNotification"])//收到短信    
  83.     {    
  84.         /*  
  85.          kCTMessageIdKey = "-2147483636";  
  86.          kCTMessageTypeKey = 1;   
  87.         */    
  88.             
  89.         NSDictionary *info = (NSDictionary *)userInfo;    
  90.         CFNumberRef msgID = (CFNumberRef)[info objectForKey:@"kCTMessageIdKey"];    
  91.         int result;    
  92.         CFNumberGetValue((CFNumberRef)msgID, kCFNumberSInt32Type, &result);    
  93.             
  94.         /*  
  95.         Class CTMessageCenter = NSClassFromString(@"CTMessageCenter");  
  96.         id mc = [CTMessageCenter sharedMessageCenter];  
  97.         id incMsg = [mc incomingMessageWithId: result];  
  98.           
  99.         int msgType = (int)[incMsg messageType];  
  100.           
  101.         if (msgType == 1) //experimentally detected number  
  102.         {  
  103.             id phonenumber = [incMsg sender];  
  104.               
  105.             NSString *senderNumber = (NSString *)[phonenumber canonicalFormat];  
  106.             id incMsgPart = [[incMsg items] objectAtIndex:0];  
  107.             NSData *smsData = [incMsgPart data];  
  108.             NSString *smsText = [[NSString alloc] initWithData:smsData encoding:NSUTF8StringEncoding];  
  109.         }  
  110.         */    
  111.     }    
  112.     else if ([notifyname isEqualToString:@"kCTIndicatorsSignalStrengthNotification"])//信号    
  113.     {    
  114.         /*  
  115.         kCTIndicatorsGradedSignalStrength = 2;  
  116.         kCTIndicatorsRawSignalStrength = "-101";  
  117.         kCTIndicatorsSignalStrength = 19;  
  118.         */    
  119.             
  120.     }    
  121.     else if ([notifyname isEqualToString:@"kCTRegistrationStatusChangedNotification"])//网络注册状态    
  122.     {    
  123.         /*  
  124.          kCTRegistrationInHomeCountry = 1;  
  125.          kCTRegistrationStatus = kCTRegistrationStatusRegisteredHome;  
  126.         */    
  127.             
  128.     }    
  129.     else if ([notifyname isEqualToString:@"kCTRegistrationDataStatusChangedNotification"])    
  130.     {    
  131.         /*  
  132.          kCTRegistrationDataActive = 1;  
  133.          kCTRegistrationDataAttached = 1;  
  134.          kCTRegistrationDataConnectionServices =     (  
  135.          kCTDataConnectionServiceTypeInternet,  
  136.          kCTDataConnectionServiceTypeWirelessModemTraffic,  
  137.          kCTDataConnectionServiceTypeWirelessModemAuthentication  
  138.          );  
  139.          kCTRegistrationDataContextID = 0;  
  140.          kCTRegistrationDataIndicator = kCTRegistrationDataIndicator3G;  
  141.          kCTRegistrationDataStatus = kCTRegistrationDataStatusAttachedAndActive;  
  142.          kCTRegistrationDataStatusInternationalRoaming = 1;  
  143.          kCTRegistrationRadioAccessTechnology = kCTRegistrationRadioAccessTechnologyUTRAN;  
  144.         */     
  145.     }    
  146.     else if ([notifyname isEqualToString:@"kCTRegistrationCellChangedNotification"])    
  147.     {    
  148.         /*  
  149.          kCTRegistrationGsmCellId = 93204174;  
  150.          kCTRegistrationGsmLac = 55583;  
  151.          kCTRegistrationInHomeCountry = 1;  
  152.          kCTRegistrationRadioAccessTechnology = kCTRegistrationRadioAccessTechnologyUTRAN;   
  153.         */    
  154.     }    
  155.     else if ([notifyname isEqualToString:@"kCTIndicatorRadioTransmitNotification"])    
  156.     {    
  157.         /*  
  158.         kCTRadioTransmitDCHStatus = 1;  
  159.         */     
  160.     }    
  161.     //int unread=CTSMSMessageGetUnreadCount();    
  162.     //if (unread>0)    
  163.         //NSLog(@"未读短信:%d",unread);    
  164.             
  165.     NSLog(@"名字:%@-详细:%@",notifyname,userInfo);    
  166.         
  167.          
  168. }    
  169.     
  170. static void signalHandler(int sigraised)      
  171. {      
  172.     printf("\nInterrupted.\n");      
  173.     exit(0);      
  174.   
  175. }     

执行

 

    1. id ct = CTTelephonyCenterGetDefault();    
    2.     CTTelephonyCenterAddObserver(ct, NULL, callback, NULL, NULL, CFNotificationSuspensionBehaviorHold);    
    3.     // Handle Interrupts      
    4.     sig_t oldHandler = signal(SIGINT, signalHandler);      
    5.     if (oldHandler == SIG_ERR)      
    6.     {      
    7.         printf("Could not establish new signal handler");      
    8.         exit(1);      
    9.     }     
    10.     // Run loop lets me catch notifications      
    11.     printf("Starting run loop and watching for notification.\n");      
    12.     //CFRunLoopRun();     

posted on 2013-05-06 10:15  一梦浮生2012  阅读(484)  评论(1编辑  收藏  举报