[Analyse] Wie UWPs in iOS/Android laufen lernen

(13.06.2017)

Auf iPhones und Androiden wurde in Office-Apps von Microsoft sehr viel Windows-Code entdeckt. Das berichtet Windows Central hier. Der Bericht darüber konstatiert, dass dieser Windows-Code ein „Trojanisches Pferd“ wäre. Doch worum geht es hier überhaupt?

Dennis Bednarz und Longhorn (wer auch immer das ist, es war zumindest mal der interne Codename für Windows Vista) haben sich den Code von Office-Apps mal genauer angeschaut. Durch Reverse-Engineering (etwa rückwärtsgewandte Entwicklung) konnten sie einen genaueren Blick auf den Code der Apps werfen und fanden dabei anscheinend Erstaunliches.

Sie stellten fest, dass jede App einen Teil der Registry und einige stark komprimierte DLLs mitbrachte, was zu einem etwas verlangsamten Start führte, da die DLLs beim Start der App erst entpackt werden mussten. Schlussendlich interpretierten sie das Vorhandensein der Systemdateien als „Trojanisches Pferd“.

Warum sind aber die Apps unter iOS bzw. Android so groß? Warum werden diese ganzen DLLs überhaupt erst mitgebracht? Und ist der Vorwurf des Trojanischen Pferds gerechtfertigt? Um diese Fragen beantworten zu können, mache ich heute mit Euch einen kleinen Ausflug in die Programmiererei.

Programme und Bibliotheken

Ein Programm

Einfache Programme folgen einem relativ logischen Aufbau. An erster Stelle steht die Idee, was das Programm können soll. Im Code stehen dann zuerst die dafür benötigten Variablen. Sodann folgen, oftmals verschachtelt oder mit Querverweisen versehen, einzelne Programmteile, auch Funktionen genannt. Damit auch andere Programme diese Programmfunktionen nutzen können, ist es wichtig, gerade diese Variablen und Programmfunktionen ordentlich zu definieren und auch zu beschreiben – das nennt man dann eine Schnittstelle, oder auch API.

Die Dokumentation (das „Buch“)

Besonders wichtig bei der ganzen Angelegenheit ist die saubere, nachvollziehbare Dokumentation! Es gibt Cracks, die schreiben mal eben 1.000 Code-Zeilen so runter, ohne Dokumentation. Hinzu kommt noch, dass mit steigender Fähigkeit eines Programmierers auch „Abkürzungen“ im Code programmiert werden. Eine Zeile entspricht dann, komplett ausgeschrieben, ein paar „normalen“ mit der gleichen Funktionalität.

Nach ein paar Jahren ist der Crack fort und der Nachfolger steht vor der schier unlösbaren Aufgabe, ein ganzes Arbeitsleben entschlüsseln zu müssen, weil die Dokumentation fehlt. Das ist Microsoft mit der Suchen-Ersetzen-Funktion unter Word für DOS 5.0/5.5 so ergangen. Weil die Dokumentation fehlte, mithin die Funktionsweise und die Variablen unbekannt waren, musste die ganze Funktion dann für Word für Windows 6.0 neu geschrieben werden.

Wie das Testing unter Windows funktioniert, könnt Ihr hier nachlesen:

Microsoft Windows Updates – Wie das Testing funktioniert, warum Daten gesendet werden

Viele Bücher ergeben eine Bibliothek

Viele verschiedene Funktionen/Programme werden in einer Programmbibliothek, einer eigenen Datei, zusammengefasst. Das hat dann den Vorteil, dass Programmierer bei neuen Programmen diese Funktionen nicht selbst schreiben müssen, sie können die vorhandenen einfach weiter benutzen. Das ist sehr oft von Vorteil, manchmal kann es auch ein Nachteil sein, wenn die benötigte Funktion so genau nicht vorhanden ist. Ein Typ einer Programmbibliothek (es gibt viele verschiedene) sind z.B. DLLs, Dynamic Link Libraries, was man etwa mit Dynamische Programmbibliotheken übersetzen kann.

DLLs sind ganze Bücher, ganze Bibliotheken voller fertiger Funktionen und Schnittstellen, die ein Programmierer benutzen kann, um eine Software zu schreiben, die das tut, was er will. Manchmal scheint es ihm vielleicht auch so, dass das Benutzen bestimmter Teile der definierten APIs oder auch DLLs nur umständlich und unbequem ist. Er versucht dann Alternativen zu finden, um z.B. direkt auf die Hardware zugreifen zu können (was er nicht darf), oder er programmiert vermeintliche Abkürzungen, die eine Funktion ersetzen sollen. Oder er benutzt alte, überholte und nur noch aus Kompatibilitätsgründen mitgeschleifte DLLs, weil er die halt immer schon benutzt hat. Er geht damit viele Risiken ein, u.a. dass Windows abstürzt und Daten verloren gehen.

Die Haustür der Bibliothek

Dass man ein Haus sinnvollerweise durch die richtige Haustür betritt und nicht etwa die des Nachbarn nimmt, und dass man auch nicht durchs Fenster oder über den Balkon einsteigt oder sogar eine Bombe reinwirft, um reinzukommen, dürfte verständlich sein. Ein falscher Zugriff auf ein Haus, eine DLL, gibt eben im schlimmsten Fall Bauschutt zurück, oder ruft die Polizei auf den Plan und nicht die benötigten zwei Eier, die man sich eben ausborgen wollte. Aber wo sich nun die Haustür befindet, die Adresse, wo man zu klingeln hat und welche ortsüblichen Gepflogenheiten (keine Sturmmasken und Kuchen zum Einzug) man dabei einzuhalten hat, das legt die Schnittstelle fest, die API.

Sicherheitsstrukturen unter Windows

Ein Haus voller Bücher: Die Registry – Scheunentor Nummer Eins

Nun hat ja jedes Programm gewissen Variablen, Einstellungen usw. die dauerhaft gespeichert werden müssen. Früher wurde dazu eine Textdatei (z.B. *.ini, *.inf) benutzt, was aber sehr langsam und fehleranfällig war. Wo im Haus liegt nochmal der Notizzettel und ich kann Deine Sauklaue nicht lesen! Die Textdatei musste erst in ein binäres Format geändert werden. Beim Zugriff auf Informationen von Schwesterprogrammen musste also unbedingt der Pfad genau stimmen, sonst wurde die Datei vielleicht auch nicht gefunden.

Windows Registry

Windows Registry

Mit Windows NT bzw. Windows 3.1 wurde das geändert und die Registry eingeführt. Sie ist komplett binär und nur die registry.exe kompiliert sie in ein für den Menschen lesbares Format. Zusätzlich wurden mit dem Dateisystem NTFS auch Berechtigungen eingeführt, sodass auch Programme bestimmte Rechte haben konnten oder eben nicht. Diese Berechtigungen sind anders gestrickt als unter Unix/Linux/Android und viel feiner abstufbar, und darüber hinaus vererbbar an Unterordner, Child-Prozesse/Unterfunktionen.

Der Grund dafür war, dass im Betriebssystem Wildwuchs herrschte. Programme, die man installierte, installierten nach Gutdünken überall im System neue oder modifizierte DLLs. Das konnte – bei falscher Reihenfolge der Installation (ältere zuerst, dann neuere) oder auch falschem Verzeichnis! – dazu führen, dass aktuelle DLLs mit älteren Versionen überschrieben wurden, wodurch die neueren Programme abstürzten. Das ist heute so nicht mehr möglich, fremde DLLs können nicht mehr überschrieben werden. Aus dieser Zeit stammt noch die Vorstellung, sein Windows „aufräumen“ zu müssen, um es „beschleunigen“ zu können. Früher durchaus sinnvoll, heutzutage obsolet bis gefährlich.

Mit der Registry waren alle Informationen an einem Ort übersichtlich und leicht auffindbar versammelt, was aber ein grundsätzliches Problem nicht behob: Programme konnten Informationen anderer Programme auslesen oder sogar verändern. Da in der Registry auch Informationen über Berechtigungen und Netzwerke usw. gespeichert werden, stand hier weiterhin Hackern ein Scheunentor offen – Berechtigungen konnten per Hack erschlichen werden.

Der Speicher – Scheunentor Nummer Zwei

Ein weiteres Problemkind war der Speicher. Wenn eine App böswillig oder nur schlecht programmiert war, konnte sie Speicherbereiche anderer Programme auslesen, ändern, löschen, überschreiben. Waren das Teile von Windows, ergab das einen hübschen Bluescreen. Immerhin ist es hier so, dass heute 32-Bit-Programme z.B. bei regulären, aber das Maß überschreitenden Speicherzugriffen abstürzen, d.h. von Windows beendet werden, wenn sie ihre zugewiesenen Speicherbereiche nicht einhalten. Unter älteren Windows-Versionen war das noch nicht so, da stürzte teilweise Windows gleich mit ab, wenn das Programm nicht sauber programmiert war und Windows-Systembereiche überschrieb oder löschte. Aus dieser Zeit stammt noch der alte Ruf von Windows, dass es so viel häufiger abstürzen würde, als ein Mac – heute gibt es da keinen Unterschied mehr. Windows stürzt ab, der Mac friert ein.

Arbeitsspeicher – Von Brutschi – CC BY-SA 3.0 (Wikipedia)

Ein ordentlich programmierter Virus oder Trojaner schaffte es aber, die Sicherheitsdaten zu kompromittieren, ohne entdeckt zu werden. Genauso wie ein guter Einbrecher, Mission Impossible macht es – fast – vor. Heute gibt es Virenscanner, die nicht nur die Daten auf der Festplatte scannen, sondern insbesondere auch Speicherzugriffe beobachten und dabei auf besondere „Signaturen“ (die Fingerabdrücke der Einbrecher, resp. der Viren) achten.

Das Sandbox-System

Mit Einführung der Sandbox, auch „Container“ genannt, war damit Schluss. Programme in einem Container konnten nicht mehr auf Informationen anderer Programme zugreifen, außer, sie waren öffentlich verfügbar. Ein Container ist aber nicht nur ein abgeschotteter Speicherbereich, sondern enthält gleichzeitig auch sozusagen einen Concierge, einen Hotel-Pagen. Der versorgt den Hotelgast (das Programm) mit Essen, Reinigung, dem Zimmerservice (den benötigten Funktionen und Bibliotheken, den DLLs) und bringt ihm die benötigten Informationen (Bücher aus der Bibliothek) direkt aufs Zimmer. Und bringt auch den Müll runter.

Dazu benötigt die Sandbox, der Container, auch eine eigene kleine Registry, irgendwo darf/muss die App ja ihre Anwendungsdaten speichern.

Der Vorteil von UWP-Apps

Macht der Programmierer in der Sandbox einen Fehler, stürzt die App ab, ohne Nachteile für das System, andere Apps oder gar Daten. Denn was Windows Mobile (8 und 10) so wahnsinnig stabil macht, ist das Sandbox-System, das im Gegensatz zu dem von Android oder Apple bislang auch noch nicht geknackt wurde. Damit können Apps (d.h. auch Viren! – was erklärt, warum hier Virenscanner schlicht überflüssig sind) nicht auf den Speicherbereich anderer Apps oder des Betriebssystems zugreifen. Ein Virenscanner unter Windows 10 S oder Mobile ist ein echtes Placebo:

Bei Windows 10 für den PC laufen allerdings nicht nur UWP-Apps, sondern auch reguläre 32-Bit-Programme (Desktop-Anwendungen/engl. desktop apps). Hinzu kommt auch die rigidere Rechtevergabe unter Windows, was es Viren zusätzlich schwerer macht. Das ist unter Android (Unix/Linux-basiert) etwas anders gelöst und macht dort den Einsatz eines Virenscanners eigentlich unabdingbar.

Mit den UWP-Apps sind die Entwickler also gezwungen, sich besser an die Rahmenbedingungen zu halten (Variablendefinition, sauberer Code, Speicherzugriffe, DLLs, APIs), wenn sie ein funktionierendes Programm abliefern wollen. Übrigens: Im Visual Studio sind schon eine ganze Reihe einfache Testprogramme integriert, die hier weiterhelfen.

Objekt-Strategie

Hinzu kommt noch, dass diese APIs auch gleichzeitig aus der App ein echtes Objekt machen, das komplett der Rechteverwaltung von Windows unterworfen ist. Dass diese Objekt-Strategie nicht nur Apps betrifft, sondern auch Windows selbst, dazu folgendes Beispiel:

Nach Update auf WinMobile 10.0.15063.138 konnte ich mit meinem Lumia 950 xl nicht mehr fotografieren. Ich bekam einen Berechtigungsfehler, der mich auf die Datenschutzeinstellungen verwies. Andere Apps, die die Kamera nutzten, funktionierten aber einwandfrei. Am angegebenen Ort fand ich jedoch keine App „Kamera“, der der Zugriff auf die Kamera etwa verwehrt worden wäre. Was war passiert? Nach etwas Suchen fand ich die Lösung: Die App „Kamera“ hatte keinen Zugriff mehr auf das Gerät, das Smartphone, und damit auf den benötigten Geräteteil, die Kamera, selbst. Unter Einstellungen – Datenschutz – Weitere Geräte habe ich es wieder eingeschaltet und der Spuk war vorbei. (Das könnt Ihr auch ausprobieren: Recht ausschalten, Kamera geht nicht mehr, aber Apps zum QR-Code scannen funktionieren nach wie vor.)

Windows 10 ARM wiederum wird einen sogenannten (!) Win-32-Emulator enthalten, um die Nutzung von herkömmlichen 32-Bit-Anwendungen zu ermöglichen. Diese Emulation ist aber kein echter Emulator, die etwa einen Prozessortyp simuliert/nachbaut. Aus dem Grund ist Intels Verlautbarung gegen Emulatoren, die auf Intels Patenten basieren, vorgehen zu wollen, auch uninteressant für Microsoft. Der Win32-Emulator erstellt eigentlich eine „Windows“-App bzw. „Windows“-Sandbox, sozusagen also einen eigenen Windows 10 PC, der auf dem Windows 10 ARM läuft („windows on windows“ bzw. WOW). In dieser Windows-App läuft dann die 32-Bit-Anwendung. Es ist noch nicht raus, ob in dieser Sandbox nun alle 32-Bit-Anwendungen gemeinsam laufen, oder ob es für jede 32-Bit-Anwendung eine eigene Sandbox gibt; das gibt leider auch die folgende Grafik nicht her.

Emulation von x86/Win32-Programmen auf Windows 10 ARM

App-Programmierung

Windows Store und App-Gap

Inzwischen häufen sich die Meldungen, dass immer mehr Apps in den Windows Store kommen, der lang kritisierte App-Gap wird immer kleiner. Mal davon abgesehen, dass weniger die Quantität der Apps in einem Store wichtig ist, als vielmehr die Vielfalt ([Bio]Diversität) und die Qualität, so hat der Windows Store in Sachen Qualität in vielen Punkten die Nase vorn, hinkt dafür aber bei der Vielfalt noch um einiges hinterher. Aber es ändert sich, wenn auch langsam.

Microsofts Idee, den App-Gap zu schließen

Microsofts Idee, den App-Gap zu schließen

Dass es sich überhaupt ändern kann, ist u.a. der Centennial Bridge zu verdanken. Sie portiert 32-Bit-Programme (Desktop apps) in UWP-Apps. Auch Xamarin hilft hier. Xamarin ist eine Entwicklungsumgebung, die es Entwicklern erlaubt, mit einem Tool (Xamarin) einen App-Core zu schreiben, der dann nach Bedarf mit einer iOS-, Android- oder Windows-10-Oberfläche (bei Windows nochmal unterteilt in Hub, PC, Hololens, Mobile, Xbox) versehen werden kann. Anschließend wird die App dann noch für die verwendete Plattform (64 Bit Intel, 32 Bit Intel, Android, iOS, ARM, Hololens HPU, Xbox Intel-Variante) kompiliert.

Xamarin

Xamarin erlaubt es außerdem, mit wenigen Mausklicks aus einer modernen responsive Website mittels Web-Wrapper eine UWP-App zu erstellen. Das schaffen sogar Nicht-Programmierer mit etwas Sturheit bzw. Durchhaltevermögen.

Anmerkung:

Project Islandwood: Portierung von iOS-Apps zu UWP-Apps. Bereits vorhandener Code wird zu UWP-App-Code ausgebaut.

Project Astoria: Das sah die Portierung von Android-Apps vor, die per Sideloading (also nicht über den Store!!!) auf einem Android-Emulator lauffähig gewesen wären. Dieses Projekt wurde abgesagt, da das Sideloading das System unsicher macht.

Ursprünglich wollte man damit in sehr kurzer Zeit sehr viele Apps in den Store bekommen, aber leider hat es nicht funktioniert.

Windows loves all your devices – Die andere Richtung

Dass es für Microsoft durchaus lohnend ist, Programme von Microsoft nach Android oder iOS zu portieren, erschließt sich auch bei näherem Hinsehen. Viele, viele Menschen nutzen außer einem PC noch iPhones oder iPads oder Android-Handys und -Tablets. Ein Kunde, der seine gewohnten Programme dort auch vorfindet, wird weiterhin die Microsoft-Produkte nutzen, und ist nicht gezwungen auf Alternativen, die es auch für Windows gibt, auszuweichen. Er bleibt an Microsoft gebunden. Nicht anders macht es die Telekom mit ihrer Mail-App auf dem PC – der Telekom-Kunde bleibt im Telekom-Ökosystem und wechselt nicht etwa zur Mail-App von Microsoft oder gar Outlook.

Native Programmierung

Oft bemängelt werden die extrem langen Startzeiten und auch das langsame Verhalten von gewissen Apps, so z.B. Facebook und Whatsapp. Das ist darauf zurückzuführen, dass die Programmierer keine nativen UWP-Apps programmiert haben. Sie machen es sich einfach, sie nehmen den Android- oder iOS-Code und packen einen Windows-Emulator drum herum und fertig ist die Windows App.

Umgekehrt wird natürlich auch ein Schuh daraus. Allerdings werden Windows-Apps nicht etwa in einen iOS- oder Android-Emulator verpackt. Hier wird ein etwas anderer Weg beschritten, die Programme erhalten eine eigene Registry (die haben sie als UWP-App in ihrem Container sowieso: Virtualized Registry Containers, VRC) und bekommen einen Satz an Alternativ-DLLs mitgeliefert. Das bedeutet, dass die UWP-Apps nicht mit ihren normalen DLLs arbeiten, sondern mit speziellen Android- oder iOS-DLLs, die auf der einen Seite Windows verstehen und auf der anderen Seite in iOS oder Android „übersetzen“. Das macht zwar die Programmdateien recht umfangreich, beschleunigt nach einem ersten Start allerdings das Verhalten ganz erheblich.

Diese Herangehensweise, ein Windows-Programm auf einem anderen Betriebssystem lauffähig hinzubekommen, wird schon seit Jahren auf Plattformen wie z.B. Linux, BSDs, MacOS auf Intel z.B. mit dem „Wine is not an emulator“ (WINE) so gehandhabt, ist also beileibe nichts Neues.

Das Trojanische Pferd

Die Bibliotheken, die unter Android oder iOS installiert werden, sind etwa folgende (Lib = Library = Bibliothek):

  • lib7zofficeassetdecoder – entpackt die Programmdateien beim ersten Start auf dem Gerät
  • libplat – Plat = Plattfrom, Mini-Windows-Umgebung, ohne die die App gar nicht lauffähig wäre
  • libd3d10warp – WARP = Windows Advanced Rasterization Platform, im Prinzip eine Software-Grafikkarte, die Direct3D 10.1 kann und für die Bildschirmanzeige verantwortlich ist
  • libdwrite, librichedit – write/rich edit = schreiben/formatiert schreiben
  • libmsxml, libxmllite – ms xml = Microsofts XML, xml lite = vereinfachtes XML
  • libstg und libd2d1 = dafür habe ich leider keine Infos finden können.

rojanisches Pferd – internetwissen.jimdo.com

Ob man nun diese Bibliotheken, die zur Ausführung der Office-Apps auf OS und Android notwendig sind, als Trojaner benennen kann, ist sicherlich Geschmackssache. Wer einem Trojaner aber grundsätzlich Böswilligkeit unterstellt, der hat dann damit aber unrecht. Wesentlich interessanter sind aber die Fragen, die sich aus dem bloßen Vorhandensein derselben – nennen wir es mal einen Windows-Container für Android und iOS – ergeben:

Können mit diesen DLLs alle UWP-Apps auf Android bzw. iOS lauffähig gemacht werden?
Plant Microsoft, diese Umgebung zu veröffentlichen bzw. zu beschreiben und freizugeben?

Falls ja, könnten damit sehr schnell alle möglichen Apps vom Windows Store bei Apple und Google auftauchen. Der umgekehrte Weg existiert ja bereits, siehe die Apps von Whatsapp und Facebook.

Was meint Ihr, wie realistisch ist es, in Zukunft immer mehr native Windows-UWPs-Apps auf iOS oder Android wieder zu sehen?