Tatort Internet: Matrjoschka in Flash

Um Ersatz für das Flash-Filmchen zu finden, das sich gestern als Trojaner entpuppte, gebe ich „new iphone video“ bei Google ein. Schon der zweite Link verspricht ein „exklusives Preview“; er führt auf eine Webseite mit einem Video – doch was ist das? Das funktioniert schon wieder nicht!

Lesezeit: 22 Min.
In Pocket speichern
vorlesen Druckansicht
Von
  • Sergei Shevchenko
Inhaltsverzeichnis

Anders als gestern sind diesmal auch keine verdächtigen Strings in der SWF-Datei, die ich schnell mal heruntergeladen habe. Aber nach der Analyse mit swfdump wundert es mich nicht, dass da kein Film erscheint:

[HEADER]        Frame count: 1
[HEADER] Movie width: 1.00
[HEADER] Movie height: 1.00

Nur ein einziger Frame mit einer Größe von 1 x 1 Pixel – das sieht nicht danach aus, als wollte der Autor mir ein Video vorführen. Dafür enthält der Dump seitenweise sogenannten P-Code, der ziemlich schwer zu lesen ist. Das ist noch nicht so ungewöhnlich, kann man doch in ActionScript unter anderem auch Spiele und interaktive Filme programmieren.

Der P-Code ist dabei so etwas wie Assembler für CPU-Maschinenbefehle. Ähnlich wie Java oder .NET wird ActionScript nämlich in Bytecode übersetzt. Den wandelt der Just-in-Time-Compiler einer virtuellen Maschine in nativen Code um, den die CPU ausführen kann. Und wenn man diese binären Bytecode-Befehle zurückübersetzt, kommt eben dieser P-Code heraus.

Was gäbe ich jetzt für eine lauffähige Installation des Action Script Viewer von Buraks oder des Sothink SWF Decompiler, die daraus wieder so was ähnliches wie lesbares ActionScript produzieren. Aber auf diesem Rechner hier muss ich mich mit dem kostenlosen abcdump begnügen, das Adobe im Rahmen des Tamarin-Projekts veröffentlicht hat. Damit lassen sich die P-Code-Listings immerhin schon besser weiterverarbeiten als die Ausgabe von swfdump. Und bearbeiten muss man die Listings, wenn man überhaupt etwas verstehen will.

Bereits die Statistik im Kopf der Datei bestätigt meinen aufkeimenden Verdacht, dass es hier nicht mit rechten Dingen zugeht: Über 25.000 pushshort- und pushbyte-Befehle, die rund 97 Prozent des Codes ausmachen, verheißen nichts Gutes. Und die API-Analyse von abcdump bestätigt diesen Verdacht noch weiter:

class EySpSUmzVvhfxjxHBjknyJec extends Object
class EySpSUmzVvhfxjxHBjknyJec
function EySpSUmzVvhfxjxHBjknyJec():*
class EySpSUmzVvhfxjxHBjknyJec
static var DAeBnlwHPuJPkQrZogFcTVoLn:String =
"fx46RIu1kelToyIVefnbEF"

Meine Erfahrung sagt mir: Wer solche Bezeichner verwendet, hat etwas zu verbergen. Aber keine voreiligen Schlüsse! Immerhin hab ich Ähnliches auch schon in legitimem Code gesehen, etwa als ein Flash-Künstler versuchte, sein „geistiges Eigentum“ mit einem Scrambler zu sichern.

Um meine P-Code-Kenntnisse aufzufrischen, lade ich mir schnell noch die von Adobe ebenfalls veröffentlichte Beschreibung der ActionScript Virtual Machine 2 herunter. P-Code arbeitet sehr viel mit dem Stack – ähnlich wie einige steinzeitliche Taschenrechner, bei denen man zur Addition zweier Werte diese zunächst auf den Stack schieben muss. Das Folgende etwa setzt das Äquivalent einer Variablen – einen Slot – auf den Wert 0:

pushbyte 0  // push 0 on stack
convert_d // pop, convert to double, push it back
setslot 1 // pop value from stack into slot 1

Um nicht ganz verrückt zu werden, lasse ich als erstes einige Suchen&Ersetzen-Sequenzen durchlaufen und ersetze Variablennamen wie GaAnighKAUXBTVKnoMpTnQgKB, EySpSUmzVvhfxjxHBjknyJec und DAeBnlwHPuJPkQrZogFcTVoLn systematisch durch die Kurzformen Gaa, Eys und Dae. Weitere Tipps für sinnvolle Ersetzungen liefern mir praktischerweise die Decompiler-Kommentare zum Funktionskopf von Main().

var ii:Number                        /* slot_id 5 */
var i:Number /* slot_id 3 */
var j:Number /* slot_id 2 */
var bytes:flash.utils::ByteArray /* slot_id 1 */

Die Zuweisung von slot_id 3 zur Variablen i wird schon ihren tieferen Sinn haben, also folge ich ihr erst einmal. Dabei benutze ich einen Trick, der sich die systematische Formatierung des Listings zu Nutze macht. Indem ich etwa slot 3 durch i ersetze, werden alle get- und set-Befehle für dieses Feld in einem Rutsch passend geändert und aus

67    getslot         3

wird ein einfaches get i. Okay – Zeit, sich den Einstieg in den Code bei Main() mal näher anzusehen.