Rec iOS对话。 从哪儿开始?

每次我与手机应用程序进行对话时,我都想提醒一下。 我的设备越狱,所以没有关于appStore限制的问题。

当然我猜公共框架将不会提供任何东西。 另外,我一直在看私人框架,但没有看到任何有用的东西。

目前,我可以从麦克风录音,但是当对话开始时,麦克风处于独占模式,数据不再被接收。

任何指导?

“录音机”确实是一个非常简单的调整。 作者试图混淆他调整的重要部分(哪个函数被钩住),但这里是我发现的。

调整基本AudioToolbox.framework了一个function – 来自AudioToolbox.framework AudioConverterConvertComplexBuffer 。 Tweak在启动时加载到mediaserverd守护进程中。

首先,我们需要找出什么时候开始录制,因为即使只是播放常规的audio文件,也会调用AudioConverterConvertComplexBuffer 。 为了实现这一点,正在监听来自CTTelephonyCenter kCTCallStatusChangeNotification通知。

其次, AudioConverterConvertComplexBuffer实现。 我还没有完成它,所以我会张贴我到目前为止。 这里有一些有用的例子可以帮助你开始。

Helper类跟踪AudioConverterRef – ExtAudioFileRef对

 @interface ConverterFile : NSObject @property (nonatomic, assign) AudioConverterRef converter; @property (nonatomic, assign) ExtAudioFileRef file; @property (nonatomic, assign) BOOL failedToOpenFile; @end @implementation ConverterFile @end 

ConverterFile对象容器

 NSMutableArray* callConvertersFiles = [[NSMutableArray alloc] init]; 

AudioConverterConvertComplexBuffer原始实现

 OSStatus(*AudioConverterConvertComplexBuffer_orig)(AudioConverterRef, UInt32, const AudioBufferList*, AudioBufferList*); 

AudioConverterConvertComplexBuffer挂钩声明

 OSStatus AudioConverterConvertComplexBuffer_hook(AudioConverterRef inAudioConverter, UInt32 inNumberPCMFrames, const AudioBufferList *inInputData, AudioBufferList *outOutputData); 

挂钩

 MSHookFunction(AudioConverterConvertComplexBuffer, AudioConverterConvertComplexBuffer_hook, &AudioConverterConvertComplexBuffer_orig); 

AudioConverterConvertComplexBuffer挂钩定义

 OSStatus AudioConverterConvertComplexBuffer_hook(AudioConverterRef inAudioConverter, UInt32 inNumberPCMFrames, const AudioBufferList *inInputData, AudioBufferList *outOutputData) { //Searching for existing AudioConverterRef-ExtAudioFileRef pair __block ConverterFile* cf = nil; [callConvertersFiles enumerateObjectsUsingBlock:^(ConverterFile* obj, NSUInteger idx, BOOL *stop){ if (obj.converter == inAudioConverter) { cf = obj; *stop = YES; } }]; //Inserting new AudioConverterRef if (!cf) { cf = [[[ConverterFile alloc] init] autorelease]; cf.converter = inAudioConverter; [callConvertersFiles addObject:cf]; } //Opening new audio file if (!cf.file && !cf.failedToOpenFile) { //Obtaining input audio format AudioStreamBasicDescription desc; UInt32 descSize = sizeof(desc); AudioConverterGetProperty(cf.converter, kAudioConverterCurrentInputStreamDescription, &descSize, &desc); //Opening audio file CFURLRef url = CFURLCreateWithFileSystemPath(NULL, (CFStringRef)[NSString stringWithFormat:@"/var/mobile/Media/DCIM/Call%u.caf", [callConvertersFiles indexOfObject:cf]], kCFURLPOSIXPathStyle, false); ExtAudioFileRef audioFile = NULL; OSStatus result = ExtAudioFileCreateWithURL(url, kAudioFileCAFType, &desc, NULL, kAudioFileFlags_EraseFile, &audioFile); if (result != 0) { cf.failedToOpenFile = YES; cf.file = NULL; } else { cf.failedToOpenFile = NO; cf.file = audioFile; //Writing audio format ExtAudioFileSetProperty(cf.file, kExtAudioFileProperty_ClientDataFormat, sizeof(desc), &desc); } CFRelease(url); } //Writing audio buffer if (cf.file) { ExtAudioFileWrite(cf.file, inNumberPCMFrames, inInputData); } return AudioConverterConvertComplexBuffer_orig(inAudioConverter, inNumberPCMFrames, inInputData, outOutputData); } 

这大概是如何做的调整。 但为什么这样做呢? 当正在进行通话时, AudioConverterConvertComplexBuffer_hook将被连续呼叫。 但是在AudioConverter的参数上会有所不同。 我发现在一次通话过程中,可能有超过九种不同的AudioConverter对象传递给我们的钩子。 他们将有不同的audio格式,所以我们不能把一切写在一个文件中。 这就是为什么我们build立AudioConverterRef-ExtAudioFileRef对的数组 – 跟踪什么被保存到哪里。 此代码将创build与AudioConverterRef对象一样多的文件。 所有文件将包含不同的audio – 一个或两个将是扬声器的声音。 其他 – 麦克风。 我已经在iOS 4上testing了iPhone 4S上的这个代码,它工作。 不幸的是,只有打开扬声器才能在4S上进行通话录音。 在iPhone 5上没有这样的限制。这是在调整的描述中提到的。

剩下的事情是找出我们如何才能find两个特定的AudioConverter对象 – 一个用于扬声器audio,一个用于麦克风。 其他一切都不是问题。

而最后一件事 – mediaserverd进程是沙盒,以便于我们的调整。 我们无法在任何地方保存文件。 这就是我select文件path的原因 – 即使是从沙箱内部也可以编写。

PS即使我已经发布这个代码信贷必须去Elias Limneos。 他做到了。

您想要统计电话,还是要logging这些电话的audio? 前者很简单,只需要一个通知。 对于后者我没有find任何东西。 我做了研究,没有find任何API可以帮助我录制audio,而电话正在进行中。 我不知道谁做的。

唯一能想到的就是CommCenter。 这个守护进程与基带通信,并可能从麦克风向他发送audiostream。 这只是一个猜测,但看着CommCenter反汇编,我发现它负责redirectaudiostream的线索。 较新的Qualcomm基带和iOS只能通过使用专有QMI协议的USBpipe道相互通话。 这个协议所做的一件事就是在通话过程中处理audiostream – 这就是所谓的Core sound driver service 。 所以我唯一能想到的是反汇编CommCenter,并find一种方法来redirectaudiostream通过你的处理程序,你会logging它们。 这显然需要反向工程,QMI协议,与USB设备交谈的IOKit等丰富的知识等。我不认为有一个API会为你做这个,或者你可以用一个简单的钩子技术做到这一点。 我们正在谈论的是比obj-c更难以进行反向工程的C ++代码,而且更难以涉足。