我的主要问题是,如何对已经存在的私有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上以何种方式被修改?
答案 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是唯一的替代品,但不允许以编程方式访问实际的视频数据。