IOMobileFramebufferGetLayerDefaultSurface无法在iOS 9

时间:2015-08-27 03:00:02

标签: ios objective-c iphone

我的主要问题是,如何对已经存在的私有API函数进行反向工程,但是在新版本的iOS中进行了修改?

我创建了一个iOS应用程序来使用IOSurface和IOMobileFramebuffer记录屏幕内容。 framebuffer用来打开它的主要功能是IOMobileFramebufferGetMainDisplay(connect)IOMobileFramebufferGetLayerDefaultSurface

这些功能自应用程序的第一个版本开始使用,它们已经在iOS 7和8的所有版本上运行。但是,在最新的iOS 9 beta版上,即beta 5,函数{{1} }不起作用。该函数不会返回0,因为它在成功打开帧缓冲区时应该返回0。

StackOverflow上的其他用户似乎也遇到了同样的问题:IOMobileFramebufferGetLayerDefaultSurface function failed on iOS 9。我们引用名为“_framebufferConnection”的IOMobileFramebufferConnection和名为“_screenSurface”的IOSurfaceRef这是当前代码:

IOMobileFramebufferGetLayerDefaultSurface

如前所述,这些功能完全适用于iOS 7-8,但在iOS 9上,第二个功能崩溃了。我还查看了两个版本符号的二进制文件并进行了比较。与iOS 8.4.1二进制文件相比,iOS 9中的第二个参数略有不同。那么,回到主要问题,我如何反向工程 IOMobileFramebufferGetMainDisplay(&_framebufferConnection); IOMobileFramebufferGetLayerDefaultSurface(_framebufferConnection, 0, &_screenSurface; ,或者看看它在iOS 9上以何种方式被修改?

4 个答案:

答案 0 :(得分:11)

为了回答问题"它是如何在iOS 9"上实际修改的,我在iOS8和iOS9(GM)上进行了一些挖掘IOMobileFramebufferGetLayerDefaultSurface。以下是我发现的结果:

<强>设定:

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实施:

  • 除了返回

  • 之外,与上述步骤相同
  • 然后尝试通过

    检索马赫端口以访问表面

    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服务时,指定连接类型的第3个参数是3而不是通常的0。几乎可以肯定,这种新的连接类型具有权限限制,可防止除Apple以外的任何人检索到一个机器端口以访问IOMFB表面。

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

希望这有助于揭开IOMFB无法再用于录制屏幕的原因。

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

答案 1 :(得分:5)

我相信@nevyn是正确的。但是,我想详细说明一下。我已经广泛地研究了这个确切的问题,并且IOMobileFramebufferGetLayerDefaultSurface函数 返回-536870201,而如果它运行函数没有任何问题它应该返回0。此错误在Internet上,但仅在用户遇到QuickTime的常规问题时才会出现。可能是Apple确实完全锁定了框架,并且需要Apple才能访问帧缓冲区。我们无法添加这些权利,因为它也必须位于配置文件中。我目前正在尝试阅读和解释反汇编并对IOMobileFramebuffer二进制文件进行一些逆向工程工作,以查看自上一个iOS版本以来是否有任何参数发生了变化。如果我发现任何事情,我一定会更新这个答案。但如果是这种情况,我建议尝试寻找另一种尝试捕获/记录屏幕内容的方法。

<强> -UPDATE -

似乎有证据表明会出现这种情况,如果你阅读this,它会显示完全相同的错误代码,这意味着该功能是&#34;不支持&#34;,并返回IOKit错误。至少我们知道这意味着什么。但是,我仍然不确定如何解决它,或使功能工作。我会继续研究这个。

更新2

我实际上在iOS 9中发现了一个全新的类,&#34; FigScreenCaptureController&#34;,它是MediaToolbox框架的一部分!但奇怪的是,Apple为什么只在iOS 9中包含这个?所以,也许有一种方法可以通过this来记录显示...我将很快深入研究这个课程。

答案 2 :(得分:2)

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

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

如果你自己签名(jtool --sign --ent),一切都运作良好。

这意味着在非JB设备上您无法使用它。但随着越狱,巨大的力量再次掌握在你手中。

答案 3 :(得分:0)

IOMobileFramebuffer完全锁定在iOS 9上,无法再从非Apple应用程序中使用。 AFAICT,这将关闭最后一个有效捕获屏幕的私有API。 ReplayKit是唯一的替代品,但不允许以编程方式访问实际的视频数据。