2015-08-27 14 views
6

Meine Hauptfrage ist, wie kann ich eine private API-Funktion, die bereits existiert, aber in einer neuen Version von iOS geändert wurde, zurückentwickeln?IOMobileFramebufferGetLayerDefaultSurface funktioniert nicht auf iOS 9

Ich habe eine iOS-Anwendung erstellt, um den Bildschirminhalt mit IOSurface und IOMobileFramebuffer aufzuzeichnen. Die Hauptfunktionen, die der Framebuffer zum Öffnen verwendet, sind IOMobileFramebufferGetMainDisplay(connect) und IOMobileFramebufferGetLayerDefaultSurface.

Diese Funktionen sind seit der ersten Version der App verwendet worden, und sie haben auf allen Versionen von iOS 7 und 8 jedoch auf die neuesten iOS 9 Beta, die Beta 5 gearbeitet, funktioniert die Funktion IOMobileFramebufferGetLayerDefaultSurface nicht Arbeit. Die Funktion gibt 0 nicht zurück, wie es sollte, wenn es den Framebuffer erfolgreich öffnet.

Dieser andere Benutzer auf StackOverflow scheint auch das gleiche Problem zu haben: IOMobileFramebufferGetLayerDefaultSurface function failed on iOS 9. Hier ist der aktuelle Code Wir haben ein Verweis auf IOMobileFramebufferConnection „_framebufferConnection“ genannt und ein IOSurfaceRef „_screenSurface“ genannt:

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

Wie bereits erwähnt vor, diese perfekt funktionieren auf iOS 8.7, aber auf iOS 9, Die zweite Funktion stürzt ab. Ich habe auch die Binärdateien mit den Symbolen für beide Versionen angeschaut und verglichen. Der zweite Parameter des LDR unterscheidet sich in iOS 9 geringfügig von dem des iOS 8.4.1-Binärprogramms. Also, zurück zur Hauptfrage, wie kann ich Reverse Engineering IOMobileFramebufferGetLayerDefaultSurface, oder sehen, wie in welcher Weise es tatsächlich auf iOS 9 geändert wurde?

+0

welche ios9-version verwenden sie? –

+0

iOS 9 Beta 5. Aber das gleiche gilt für alle iOS 9 Betas/Versionen. – Pyrology

Antwort

5

Ich glaube @nevyn ist korrekt. Ich möchte jedoch ein wenig mehr ausführen. Ich habe ausführlich dieses genaue Problem untersucht, und die IOMobileFramebufferGetLayerDefaultSurface Funktion tut zurück -536870201, während es 0 zurückgeben sollte, wenn es die Funktion ohne irgendwelche Probleme ausführt. Dieser Fehler tritt im Internet auf, wird jedoch nur angezeigt, wenn Benutzer allgemeine Probleme mit QuickTime feststellen. Es könnte sein, dass Apple das Framework tatsächlich vollständig gesperrt hat und eine Apple-Berechtigung benötigt, um auf den Framebuffer zuzugreifen. Wir können diese Berechtigungen nicht hinzufügen, da sie auch im Bereitstellungsprofil enthalten sein müssen. Ich versuche derzeit, die Disassemblierung zu lesen und zu interpretieren und einige Reverse-Engineering-Arbeiten an der IOMobileFrambuffer-Binärdatei durchzuführen, um festzustellen, ob sich einige der Parameter seit der letzten iOS-Version geändert haben. Ich werde diese Antwort sicherlich aktualisieren, wenn ich etwas entdecke. Aber wenn das der Fall ist, würde ich vorschlagen, eine andere Methode zu finden, den Bildschirminhalt zu erfassen/aufzuzeichnen.

-UPDATE-

Es scheint, als ob es Anzeichen dafür, dass dies der Fall wäre, wenn Sie this lesen, es zeigt genau die gleichen Fehlercode, und es bedeutet, dass die Funktion „unsupported“ ist und gibt einen IOKit-Fehler zurück. Zumindest wissen wir jetzt, was das bedeutet. Ich bin jedoch immer noch unsicher, wie ich es beheben oder die Funktion funktionieren lassen kann. Ich werde das weiter untersuchen.

UPDATE 2

Ich habe entdeckt, eigentlich eine ganz neue Klasse in iOS 9, "FigScreenCaptureController", und es ist Teil des MediaToolbox Rahmen ist! Was das Merkwürdige ist, warum würde Apple dies nur in iOS 9 einbeziehen?Also, vielleicht wird es eine Möglichkeit geben, die Anzeige über this aufzuzeichnen ... Ich werde sehr bald in diese Klasse mehr vertiefen.

+0

hey @ anthonya1999, hast du Glück, dass du mit dem FigScreenCaptureController den Bildschirm aufnimmst? –

+0

@ShirishKamath Ich weiß, dass dies eine späte Antwort ist, aber ich habe mich in der Klasse ein wenig umgeschaut, und Sie können Start/Stop-Capture ganz gut aufrufen, aber ich weiß nicht, wie ich es einrichten soll. (zB Video-Pfad, Bildrate, etc.) Ich werde weiter sehen, was ich damit machen kann ... – anthonya1999

0

IOMobileFrambuffer ist vollständig auf iOS 9 gesperrt und kann nicht mehr von Nicht-Apple-Apps verwendet werden. AFAICT, dies schließt die letzte private API, um den Bildschirm effizient zu erfassen. ReplayKit ist der einzige Ersatz, erlaubt aber keinen programmatischen Zugriff auf die eigentlichen Videodaten.

11

Um die Frage zu beantworten, "wie und auf welche Weise es auf iOS 9 modifiziert wurde", habe ich unter iOS8 gegen iOS9 (GM) in IOMobileFramebufferGetLayerDefaultSurface gegraben. Hier sind die Ergebnisse von dem, was ich gefunden habe:

Setup:

IOMobileFramebufferRef fb; IOMobileFramebufferGetMainDisplay(&fb);

iOS8 Umsetzung:

  • Anrufe durch kern_GetLayerDefaultSurface

  • Welche und greift erlying IOConnection

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

  • Um die IOSurfaceID über abrufen

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

  • Returns IOSurfaceLookup(surfaceID)

iOS9 Umsetzung:

  • gleichen Schritte wie oben abgesehen von der Rückkehr

  • Dann versucht einen mach Port abzurufen, die Oberfläche für den Zugriff über

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

  • Bei Erfolg Rückkehr IOSurfaceLookupFromMachPort(surfacePort)

Im letzten Schritt gibt IOServiceOpen den Fehler 0x2c7 zurück (nicht unterstützte Funktion). Beachten Sie, dass das dritte Argument, das den Verbindungstyp angibt, 3 anstelle des üblichen 0 beim Öffnen des Framebuffer-Dienstes ist. Es ist fast sicher, dass dieser neue Verbindungstyp über Zugriffsbeschränkungen verfügt, die verhindern, dass jemand außer Apple einen Mach-Port für den Zugriff auf die IOMFB-Oberfläche abrufen kann.

Was etwas interessant ist, ist, dass der Aufruf an IOConnectCallScalarMethod weiterhin funktioniert, um die ID der IOMFB-Oberfläche abzurufen. Sie können jedoch nicht mehr auf IOSurfaceLookup zugreifen, da die Oberfläche nicht mehr global ist. Es ist ein wenig überraschend, dass es überhaupt global war!

Ich hoffe, dies hilft zu entmystifizieren, warum IOMFB nicht mehr verwendet werden kann, um den Bildschirm aufzuzeichnen.

Quelle: Meine eigene Verwendung von LLDB mit einem iPhone6 ​​mit iOS 8.4 und ein iPhone6 ​​+ Lauf iOS9 GM

+0

Ich vermutete, dass Apple es irgendwie gesperrt hat ... gibt es eine andere Möglichkeit, eine IOSurface ohne IOMobileFrambuffer einzufangen oder vielleicht ein anderes Framework, um es stattdessen zu verwenden? – anthonya1999

+1

@ anthonya1999 Es gibt keine Möglichkeit, den Bildschirm aufzunehmen, während sich Ihre App im Hintergrund befindet. Wenn Sie Ihre App aufzeichnen möchten, können Sie die öffentliche Methode 'drawViewHierarchyInRect:' UIView verwenden. Diese Methode ist auch App Store sicher, obwohl ich vermute, dass das in Ihrem Fall nicht wichtig ist. – jvisenti

+0

Sehr nützliches Stück Detektivarbeit. Danke für das Posten. (Voted.) Die nächste Frage ist, gibt es eine Berechtigung (möglicherweise privat), die Apple hinzugefügt hat, so dass es Apps noch verwenden können? Falls nicht, welchen Mechanismus verwendet AirPlay für die Bildschirmspiegelung? (Siehe meine Frage dazu, wie man dies in iOS 9 unter [** versucht, Bildschirmaufnahmen mit privaten Rahmen IOSurface scheint nicht mehr in iOS 9 ** arbeiten] (http://stackoverflow.com/questions/32356981/trying -to-do-screen-capture-mit-privat-framework-iosurface-no-longer-scheint-zu? noredirect = 1 # comment53093867_32356981) –

0

nicht ganz korrekt - es ist nur eine Frage eines Anspruchs, wie Sie sehen können, wenn Sie die kext Dump:

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

Wenn Sie sich anmelden (jtool --sign - -ent) damit funktioniert alles gut.

Dies bedeutet, dass Sie auf Nicht-JB-Geräten nicht verwenden können. Aber mit einem Jailbreak ist die immense Kraft wieder in deinen Händen.

Verwandte Themen