ios - 以编程方式断开或连接 iPhone 通话

标签 ios iphone objective-c jailbreak

我正在为 iOS 进行个人调整。我想在电话显示任何内容之前断开/连接电话。我连接到类 SBUIFullscreenAlertAdapterinitWithAlertController: 方法。当我只显示一条显示传入电话号码及其名称的消息时一切正常,但当我尝试接听电话或以编程方式断开连接时,它会崩溃并进入安全模式。

这是我的代码:

@interface SBUIFullscreenAlertAdapter
- (id)initWithAlertController:(id)arg1;
@end

@interface MPIncomingPhoneCallController
{
    struct __CTCall *_incomingCall;
}
- (id) incomingCallNumber;
- (void)stopRingingOrVibrating;
- (void)answerCall:(struct __CTCall *)arg1;
@end

%hook SBUIFullscreenAlertAdapter
- (id)initWithAlertController:(id)arg1
{
    MPIncomingPhoneCallController *phoneCall = (MPIncomingPhoneCallController*)arg1;
    [phoneCall stopRingingOrVibrating];
    if([phoneCall.incomingCallNumber isEqualToString:@"+98.........."]) {
        [phoneCall answerCall:_incomingCall];
    }
    %orig;
    return self;
}
%end

错误是它说:“使用未声明的标识符‘_incomingCall’”。

我该如何解决这个问题?有没有办法在 Hook 方法时使用私有(private)实例变量?是否有返回来电的 CTCallRef* 的函数?有没有其他方法可以做到这一点?

应该很明显,我是为越狱的iOS设备编写代码,所以使用私有(private)框架是没有问题的。

最佳答案

有更好的地方可以做到这一点 - MPTelephonyManager -(void)displayAlertForCall:(id)call。此方法位于 IncomingCall.servicebundle 二进制文件中,而不是在 SpringBoard 本身中。当有来电时,这个二进制文件会在运行时加载到 SpringBoard 中。在此之前 IncomingCall.servicebundle 未加载,因此您无法 Hook 它的方法。


Hook IncomingCall.servicebundle

为了 Hook 这个方法,首先,阅读这个How to hook methods of MPIncomingPhoneCallController? SBPluginManager 正在运行时加载 *.servicebundle 二进制文件。您需要 Hook 它的 -(Class)loadPluginBundle:(id)bundle 方法。它看起来像这样:

void displayAlertForCall_hooked(id self, SEL _cmd, id arg1);
void(*displayAlertForCall_orig)(id, SEL, id) = NULL;

%hook SBPluginManager
-(Class)loadPluginBundle:(NSBundle*)bundle
{
    Class ret = %orig;

    if ([[bundle bundleIdentifier] isEqualToString:@"com.apple.mobilephone.incomingcall"] && [bundle isLoaded])
    {
        MSHookMessageEx(objc_getClass("MPTelephonyManager"),
                        @selector(displayAlertForCall:), 
                        (IMP)displayAlertForCall_hooked, 
                        (IMP*)&displayAlertForCall_orig);
    }

    return ret;
}
%end

如您所见, Hook 会延迟到 IncomingCall.servicebundle 加载完成。我不太了解 logos/theos,但我认为它不能那样做。这就是我使用 CydiaSubstrate (MobileSubstrate) API 的原因。


Hook MPTelephonyManager

#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
typedef void* CTCallRef;
void CTCallDisconnect(CTCallRef);
void CTCallAnswer(CTCallRef);    

void displayAlertForCall_hooked(id self, SEL _cmd, id arg1)
{
    CTCallRef call = NULL;
    if (SYSTEM_VERSION_LESS_THAN(@"7.0"))
    {
        //On iOS 6 and below arg1 has CTCallRef type
        call = arg1;
    }
    else
    {
       //On iOS 7 arg1 has TUTelephonyCall* type
       call = [arg1 call];
    }

    NSString *callNumber = (NSString*)CFBridgingRelease(CTCallCopyAddress(NULL, call));
    if ([callNumber isEqualToString:@"+98.........."]) 
    {
        CTCallAnswer(call);
        //CTCallDisconnect(call);
    }

    %orig;
}

关于ios - 以编程方式断开或连接 iPhone 通话,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22531941/

相关文章:

ios - SocketRocket 不适用于 iOS 5.0

iphone - XCode UIView 在 TableView 第一个 Cell 起源之上

iphone - 从地址簿添加联系人时 EXC_BAD_ACCESS?

ios - 从 UITextView 和 NSLayoutManager 获取行信息

objective-c - objective-c : Cell text disappears after scrolling out of screen (and back)

ios - iOS 应用程序中用于调试和 Release模式的不同语言?

ios - iOS 5之前的库/缓存行为

iphone - 将 UIView 的表示保存到文件

iphone - iPhone 上的 CSS 输入按钮

ios - 如何获取视频回复列表 YouTube API Objective C