IOMobileFramebufferGetLayerDefaultSurface不适用于iOS 9

我的主要问题是,我怎样才能逆向工程一个已经存在的私人API函数,但已经在新版本的iOS中进行了修改?

我创build了一个iOS应用程序来使用IOSurface和IOMobileFramebufferlogging屏幕内容。 framebuffer用来打开它的主要function是IOMobileFramebufferGetMainDisplay(connect)IOMobileFramebufferGetLayerDefaultSurface

这些函数自应用程序的第一个版本开始使用,他们已经在iOS 7和8的所有版本上工作。但是,在最新的iOS 9 beta版本(testing版本5)上,函数IOMobileFramebufferGetLayerDefaultSurface不起作用。 该函数不会返回0,因为它应该当它成功地打开帧缓冲区。

这个在StackOverflow上的其他用户似乎也遇到同样的问题: IOMobileFramebufferGetLayerDefaultSurface函数在iOS 9上失败 。 我们有一个名为“_framebufferConnection”的IOMobileFramebufferConnection和一个名为“_screenSurface”的IOSurfaceRef的引用,下面是当前的代码:

IOMobileFramebufferGetMainDisplay(&_framebufferConnection); IOMobileFramebufferGetLayerDefaultSurface(_framebufferConnection, 0, &_screenSurface;

如前所述,这些工作完美的iOS 7-8,但在iOS 9上,第二个function崩溃。 我也看了两个版本的符号的二进制文件,并进行了比较。 与iOS 8.4.1二进制文件相比,iOS 9中LDR的第二个参数略有不同。 所以,回到主要问题,我怎么能反向工程IOMobileFramebufferGetLayerDefaultSurface ,或看看它是如何在iOS 9上实际上被修改?

我相信@nevyn是正确的。 不过,我想再详细说一下。 我已经广泛地研究了这个确切的问题, IOMobileFramebufferGetLayerDefaultSurface函数确实返回-536870201,而它应该返回0,如果它没有任何问题运行该函数。 这个错误是在互联网上,但只有当用户遇到QuickTime的通用问题时才会出现。 这可能是苹果确实locking了框架,并且需要一个苹果专有的权利来访问帧缓冲区。 我们无法添加这些权利,因为它也必须位于configuration文件中。 我目前正在尝试读取和解释反汇编,并在IOMobileFramebuffer二进制文件上做一些逆向工程工作,以查看自上一个iOS版本以来是否有任何参数发生了变化。 我一定会更新这个答案,如果我发现任何东西。 但是,如果是这样的话,我会build议试图find另一种尝试捕捉/logging屏幕内容的方法。

-UPDATE-

看起来好像有证据表明是这种情况,如果你阅读这个 ,它显示了完全相同的错误代码,这意味着该函数是“不受支持的”,并返回一个IOKit错误。 至less我们知道这意味着什么。 但是,我仍然不确定如何解决这个问题,或者让这个function起作用。 我会继续研究这个。

更新2

我实际上在iOS 9中发现了一个全新的类“FigScreenCaptureController”,它是MediaToolbox框架的一部分! 但奇怪的是,苹果为什么只在iOS 9中包含这个东西呢? 所以,也许会有办法通过这个来logging显示…我会很快深入地研究这个类。

为了回答“如何在iOS 9上实际修改它”的问题,我在iOS8和iOS9(GM)上做了一些深入的IOMobileFramebufferGetLayerDefaultSurface 。 这是我发现的结果:

build立:

IOMobileFramebufferRef fb; IOMobileFramebufferGetMainDisplay(&fb);

iOS8实现:

  • 通过调用kern_GetLayerDefaultSurface

  • 其中访问基础的IOConnection

    io_connect_t fbConnect = *(io_connect_t *)((char *)fb + 20)

  • 通过检索IOSurfaceID

    IOSurfaceID surfaceID; uint32_t outCount = 1; IOConnectCallScalarMethod(fbConnect, 3, {0, 0}, 2, &surfaceID, &outCount)

  • 返回IOSurfaceLookup(surfaceID)

iOS9实施:

  • 除了退货之外,与上述步骤相同

  • 然后尝试检索一个mach端口来访问表面通过

    io_service_t fbService = *(io_service_t *)((char *)fb + 16) mach_port_t surfacePort; IOServiceOpen(fbService, mach_task_self(), 3, &surfacePort)

  • 成功后,返回IOSurfaceLookupFromMachPort(surfacePort)

这是IOServiceOpen返回错误0x2c7 (不支持的函数)的最后一步。 注意,打开framebuffer服务时,指定连接types的第三个参数是3而不是通常的0 。 几乎可以肯定的是,这种新的连接types具有权限限制,可以阻止除苹果以外的任何人获取机械端口以访问IOMFB表面。

有趣的是,调用IOConnectCallScalarMethod仍然可以检索IOMFB曲面的ID。 但是,它不能再使用IOSurfaceLookup访问,因为曲面不再是全局的。 这首先是全球性的有点令人惊讶!

希望这有助于揭开为什么IOMFB不能再被用来logging屏幕的神秘色彩。

来源:我自己使用运行iOS 8.4的iPhone6和运行iOS9 GM的iPhone6 +的LLDB

IOMobileFramebuffer完全locking在iOS 9上,无法再使用非Apple应用程序。 AFAICT,这将closures最后一个私有API来高效地捕获屏幕。 ReplayKit是唯一的替代品,但不允许编程访问实际的video数据。

不完全正确 – 这只是一个权利的问题,你可以看到你是否转储kext:

 $ jtool -d __TEXT.__cstring 97.IOMobileGraphicsFamily.kext | grep com.apple 0xffffff80220c91a2: com.apple.private.allow-explicit-graphics-priority 

如果你自己签署(jtool –sign –ent),一切运作良好。

这意味着在非JB设备上,你不能使用它。 但随着越狱,巨大的权力再次在你手中。