iOS应用程序Display Recorder声称能够记录iOS设备的屏幕,即使它在后台.考虑到UIGetScreenImage()是私有API,当苹果运行的静态分析检测到它时,会导致应用程序提交被拒绝,他们是如何在批准的应用程序中进行记录的?

此外,该应用程序在录制时会在屏幕顶部显示一个红色条,类似于本机iOS的通话功能.

我做iOS开发者已经有一段时间了,我有点困惑于这是怎么做到的,甚至是在应用程序之外将红色条放在顶部的细节.我的印象是,当应用程序在后台运行时,我们基本上无法控制发生了什么,缺少一些关键功能(如音频播放等).

即使开发人员利用私有API/库来实现这一点,他们如何能够以审查期间未检测到的方式实现这一点?如果我遗漏了一些明显的东西,我深表歉意,这些东西是在新版iOS中引入的.

推荐答案

调查发现它与iSurface没有联系.然而,我确实发现它使用了dlsym,经过一些反向工程后,我发现:

/System/Library/Frameworks/IOKit.framework/IOKit
IOServiceGetMatchingServices
IOServiceGetMatchingService
IOServiceMatching
IOMasterPort
IOIteratorNext
IORegistryEntryCreateCFProperty
IOObjectRelease
/System/Library/Frameworks/UIKit.framework/UIKit
UIGetScreenImage
/System/Library/PrivateFrameworks/IOMobileFramebuffer.framework/IOMobileFramebuffer
IOMobileFramebufferOpen
IOMobileFramebufferGetLayerDefaultSurface
/System/Library/PrivateFrameworks/IOSurface.framework/IOSurface
IOSurfaceAcceleratorCreate
IOSurfaceAcceleratorTransferSurface
IOSurfaceLock
IOSurfaceUnlock
IOSurfaceGetWidth
IOSurfaceGetHeight
IOSurfaceCreate
IOSurfaceGetBaseAddress

所以,正如您在这里看到的,在每个框架路径之后是它从每个框架动态加载的符号字符串.这是为了避免在与私有框架进行链接时遇到麻烦.由于它是在运行时加载的,静态分析器无法判断此应用是否使用它,从而逃避检测.

看起来我最初的怀疑是正确的;它正在使用iSurface偷偷绕过沙箱限制,以获得原始屏幕访问权限.它还使用UIGetScreenImage,我认为这是生成视频的第二种方法.它还使用了一些IOKit函数和IOMobileFramebuffer函数.该应用程序似乎正在从IOMobileFramebufferGetLayerDefaultSurface函数中获取iSurface.但不太清楚它用IOKit做什么.

总之,这个应用程序使用了一些狡猾的技术来避免被静态分析器检测到:它不会链接到私有框架,而是动态地抓取符号.它使用IOSurface和IOMobileFramebuffer的组合来录制视频,或者使用UIGetScreenImage来录制其他模式.这是一个棘手的应用程序,WILL可以从应用store 下载,所以如果你想要它,最好现在就下载.

更新:

看来这个应用程序确实是从应用store 里撤出来的.如果你足够幸运,在它被拉出来之前抓到了一个副本,那就太好了.我知道我很高兴我得到了它.

苹果可能通过声明该应用使用了私有API来证明其决定的合理性,这可能被视为一个潜在的安全问题(可怕的 idea 是,一个在你输入iTunes密码时监视你的应用就是一个例子).我想知道这是否会导致他们审查过程的改变,但我们可能永远不会知道.我感兴趣的一件事是,开发人员还可能使用更多的技巧来隐藏应用程序的行为,使其不受静态分析的影响.没有一个审查过程是完美的,但他们可以做得很好.即使苹果自动拒绝链接dlsym符号的应用程序,也有一些方法可以用来绕过检测.

更新2:

显然,AppStore中现在有这个应用程序的另一个版本.它被称为"Disp Recorder",与第一个图标完全相同.图形用户界面看起来与原来的图形用户界面几乎相同,只是做了一些小改动.我还没有推翻较新的一个,但我愿意打赌,他们使用相同的技术来隐藏非法行为.一旦我推翻了新版本,我会更新这个答案.新的一款售价5美元,但如果你想在一台没有故障的设备上安装一款屏幕录制应用程序,你应该在它被拉出之前抓取它.

更新3:

看起来我对这个应用程序的工作原理非常正确.GitHub by @coolstarorg上有一个名为RecordMyScreen的开源实现.如果你仍然想知道这个应用程序是如何工作的,我建议你go 看看.

Objective-c相关问答推荐

如何判断 iPhone 现在在哪个位置(横向或纵向)?

UIAlertController:supportedInterfaceOrientations 被递归调用

多个(两个)持久存储可以与一个对象模型一起使用,同时保持一个到另一个的关系吗?

使用 [NSBundle mainBundle] pathForResource: ofType:inDirectory: 访问文件

iOS - 应用程序关闭时的核心位置和地理围栏

只有 ONE VIEW 横向模式

Objective-C (cocoa) 等价于python的endswith/beginswith

NSMutableArray 判断对象是否已经存在

从我在 iPhone 上的应用程序调用官方 *Settings* 应用程序

Objective-C:如何从子类访问父属性?

如何判断特定的 ViewController 视图当前是否可见?

如何为图层 shadowOpacity 设置动画?

UIFont 的磅值到底是多少?

从 iPhone 设备查找当前国家

Objective C 中的对象分配和初始化

Objective-C中的继承和类别有什么区别

IOS 中的圆形进度条

为什么 detailTextLabel 不可见?

AVAudioPlayer 不播放任何声音

使用正则表达式查找/替换 NSString 中的子字符串