1. #1

    Registriert seit
    28.10.2011
    Beiträge
    625
    Thanked 279 Times in 168 Posts

    Standard [Java] PopupParser - "Definitionen"/"Daten" verstanden, parser aber nicht (Beispiele)

    Ich bin seit einigen Tagen dabei, den PopupParser von Knuddels zu verstehen. Wie das ganze nun aufgebaut ist, wie die Daten zur Stande kommen, ist mir bereits klar. Das ganze Datenformat ergibt schließlich einen Sinn.

    Zum Reversen habe ich mir Enigma, aber auch andere Tools wie Fernflower oder JD-GUI zur Hand genommen, der das deobfuscaten erleichtert; Method- oder Class renaming ist bei Enigma wirklich nice. Verschiedene Decompiler zu nutzen sollte auch einen Sinn ergeben: Nicht jeder kann alles hundert prozentig decompilieren, an einigen Stellen hapert es die man dann aber durch einen anderen Decompiler ausbessern kann.

    Kommen wir zum Teil der Definitionen; Diese sind gesplitted durch das Char õ, was auch in der onEnd-Methode wiedergespiegelt wird. Knuddels macht es hier natürlich etwas umständlich. Anstelle direkt alles auf õ zu splitten, gehen die Char-by-Char durch. Ich denke, dass dies ggf. auch einen Sinn ergibt.

    Fangen wir mal mit einer ganz einfachen Definition an:
    BNp~õ
    Dies erstellt ein BorderLayout auf North und besitzt Subpanels, die nachfolgend geparst werden.

    B - BorderLayout
    N - North
    p - Subpanels
    ~ - Read as Empty String (siehe decompilierte Klassen)
    õ - End
    Das ganze könnte man jetzt auch einfach anders Positionieren, in dem man anstelle von N (North) auch South, West, East angibt oder es mit einem anderen LayoutManager wie CardLayout, FlowLayout, GridLayout (Achtung, die nächsten 4 Chars sind dann aber Integer mit den rows/cols/hgap/vgap values, siehe Java-API des konstruktors) oder ScrollPane ausstattet.

    Jetzt habe ich aber etwas verbissenes. So weit arbeitet mein Parser, der in JavaScript geschrieben ist schon fast wie das Original; Leider aber verschluckt dieser sich (obwohl völlig identische Arbeitsweise) an einige wenigen Chars. Das geile daran ist, fast alle Komponenten parst er korrekt, nur den TextPanel nicht. Aufgrund des B Segments verschluckt dieser sich um einige Positionen und zeigt den Text vom "KCode"-TextPanel versetzt an.

    Das kann man sich wie folgt an der /info eines Channels vorstellen:
    Original fängt das Element wie folgt an:
    BCc°R>{linkhovercolor}<r°°>CENTER<°°>{table|85|200|20 0|85}<°_°>{tc}<°Channel-Rating:
    BorderLayout Center content Text bis Ende...

    Normalerweise ist dann der Text "°R>{linkhovercolor}<r°°>CENTER<°[... Wie auch immer ...]". Da sich der Parser aber etwas verschluckt (wozu wir jetzt gleich kommen), ist der Text tatsächlich aber "inkhovercolor}<r°°>CENTER<°[... Wie auch immer ...]"; Es fehlen hier also folgende 5 Positionen: °R>{l.

    Das Problem wird am Parser liegen, auch verstehe ich nicht, warum Knuddels dies so gemacht hat, verstehe aber, dass es auch ein Null-Layout geben kann (componente.setLayout(null)).

    Der Parser arbeitet nested und hat nur zwei Schritte, wobei der zweite insgesamt zwei Schritte beinhaltet:
    Schritt 1 - Header: Parst den Window-Title, Background, Whatever:
    Code:
    Beispiel:
    Channel Knuddelsõ
    	s (Wenn SendBack gesetzt, werden nachfolgende Strings gelesen)
    		cmvõ
    		Knuddelsõ
    	f    (Foreground RGB)
    	hÿÿÿ (Background RGB)
    	CãCp
    Schritt 2 - Components:
    Unterschritt 1 - Layout
    Unterschritt 2 - Ausrichtung (wenn Layout)
    Unterschritt 3 - Komponentdaten
    [/code]

    Jetzt kommen wir zum Parsing-Teil, der mir nicht so Logisch vorkommt. Studiert mal bitte insbesondere das Parsen von B (Layout), sowie C (Ausrichtung) und die Defaults:

    Layout-Parser
    Code:
    var running = true;
    var layout = null; // Standardmäßig ist das Layout NULL!
    var background = null;
    var foreground = null;
    var image = null;
    var image_width = null;
    var image_height = null;
    
    do {
    	running = false;
    	
    	switch(this.nextChar()) {
    		case 'B':
    			++this.position;
    		break;
    		case 'C':
    			layout = new CardLayout();
    			has_layout_position = true;
    		break;
    		case 'F':
    			layout = new FlowLayout();
    		break;
    		case 'G':
    			layout = new GridLayout(this.getChar(), this.getChar(), this.getChar(), this.getChar());
    		break;
    		case 'P':
    			/*
    				Es gibt nur drei Komponenten, auf denen weitere Subkomponenten gelegt werden:
    					- ScrollPane (DIESE)
    					- ImagePanel (Wird automatisch gesetzt, sobald Token U geparst wird)
    					- Panel (Letzteres ist immer Default, sofern kein ImagePanel oder ScrollPane)
    			*/
    			element = new ScrollPane();
    			element.setSize(this.getInteger(), this.getInteger());
    		break;
    		case 'U':
    			if(image == null) {
    				image = this.getString();
    			} else {
    				image_width = this.getInteger();
    				image_height = this.getInteger();
    			}
    
    			running = true;
    		break;
    		// Background
    		case 'b':
    			background = this.getColor();
    			running = true;
    		break;
    		// Foreground
    		case 'f':
    			foreground = this.getColor();
    			running = true;
    		break;
    		default:
    			--this.position;
    			layout = new BorderLayout();
    			has_layout_position = true; // parst dann North/South/West/East
    		break;
    	}
    } while(running);
    Ausrichtungsparser:
    Code:
    layout_position = null;
    while(!this.isEnd()) {
    	// Ausrichtung wird nur geparst, wenn es der LayoutManager zuvor vorgibt
    	if(has_layout_position) {
    		switch(this.nextChar()) {
    			case 'C':
    				++this.position;
    			break;
    			case 'E':
    				layout_position = "East";
    			break;
    			case 'N':
    				layout_position = "North";
    			break;
    			case 'S':
    				layout_position = "South";
    			break;
    			case 'W':
    				layout_position = "West";
    			break;
    			default:
    				layout_position = "Center";
    				--this.position;
    			break;
    		}
    	}
    	
    	// [...]
    }
    Und jetzt noch einmal bitte auf die content-Komponente schauen:
    BCc°R>{linkhovercolor}<r°°>CENTER<°°>{table|85|200|20 0|85}<°_°>{tc}<°Channel-Rating:
    Jetzt meine Fragen:
    • Warum wird Center geskippt?
      • Standardmäßig ist die Ausrichtung null, wie soll hier jemals der Wert "Center" erreicht werden? Wenn Center eintrifft, springt der Parser zum nächsten Char; Zum "Default" kommt er hier genauso wenig.
    • Warum wird BorderLayout geskippt, auch hier kommt nie der Default zur Stande


    Ich hoffe, mir kann da jemand weiterhelfen.

    Liegt es vielleicht an der decompilierung, dass da etwas falsch intepretiert wird?

    Unter verschiedenen Decompilern wird das ganze auch etwas anders dargestellt, siehe Screens:
    Spoiler:






    Edit:
    Ich habe nun jetzt auch mal mit insgesamt 6 verschiedenen Decompilern des Original-Applets geschaut:
    JD-Core
    Code:
    if (i != 0) {
    	switch (addMouseListener())
    	{
    	case 'N': 
    	  str2 = I.I(1320);
    	  break;
    	case 'S': 
    	  str2 = I.I(1326);
    	  break;
    	case 'E': 
    	  str2 = I.I(153);
    	  break;
    	case 'W': 
    	  str2 = I.I(1332);
    	  break;
    	case 'C': 
    	  t += 1;
    	default: 
    	  t -= 1;
    	  str2 = I.I(1019);
    	}
      }
    CFR
    Code:
    if (bl2) {
    	switch (this.addMouseListener()) {
    		case 'N': {
    			string2 = I.I((int)1320);
    			break;
    		}
    		case 'S': {
    			string2 = I.I((int)1326);
    			break;
    		}
    		case 'E': {
    			string2 = I.I((int)153);
    			break;
    		}
    		case 'W': {
    			string2 = I.I((int)1332);
    			break;
    		}
    		case 'C': {
    			++this.t;
    		}
    		default: {
    			--this.t;
    			string2 = I.I((int)1019);
    		}
    	}
    }
    jadx
    Code:
    if (obj3 != null) {
    	switch (addMouseListener()) {
    		case 'C':
    			this.f1t++;
    			break;
    		case 'E':
    			I = I.I(153);
    			break;
    		case 'N':
    			I = I.I(1320);
    			break;
    		case 'S':
    			I = I.I(1326);
    			break;
    		case 'W':
    			I = I.I(1332);
    			break;
    	}
    	this.f1t--;
    	I = I.I(1019);
    } else {
    	I = str2;
    }
    Procyon
    Code:
    Label_0384: {
    	if (b) {
    		switch (this.addMouseListener()) {
    			case 'N': {
    				s = I.I.I(1320);
    				break Label_0384;
    			}
    			case 'S': {
    				s = I.I.I(1326);
    				break Label_0384;
    			}
    			case 'E': {
    				s = I.I.I(153);
    				break Label_0384;
    			}
    			case 'W': {
    				s = I.I.I(1332);
    				break Label_0384;
    			}
    			case 'C': {
    				++this.t;
    				break;
    			}
    		}
    		--this.t;
    		s = I.I.I(1019);
    	}
    }
    JAD
    Code:
    if(flag)
    switch(addMouseListener())
    {
    case 78: // 'N'
    	s2 = I.I.I(1320);
    	break;
    
    case 83: // 'S'
    	s2 = I.I.I(1326);
    	break;
    
    case 69: // 'E'
    	s2 = I.I.I(153);
    	break;
    
    case 87: // 'W'
    	s2 = I.I.I(1332);
    	break;
    
    case 67: // 'C'
    	t++;
    	// fall through
    
    default:
    	t--;
    	s2 = I.I.I(1019);
    	break;
    }
    Geändert von Bubble Gum (19.06.2017 um 10:19 Uhr)

  2. The Following User Says Thank You to Bubble Gum For This Useful Post:

    Negok (19.06.2017)

  3. #2

    Registriert seit
    28.10.2011
    Beiträge
    625
    Thanked 279 Times in 168 Posts

    Standard AW: [Java] PopupParser - "Definitionen"/"Daten" verstanden, parser aber nicht (Beispiele)

    PUSH: Hat vielleicht jemand eine Idee?

    Mir ist da im übrigen noch etwas in den Sinn gekommen, warum "C" beim Positionsparser übersprungen wird: C bedeutet nicht nur Center, sondern auch CardLayout. Aber im Normalfall wird ja erst das Layout definiert und dann die Position.

    Genau hier kann ich zwar den "Skip" verstehen, aber dennoch kommt er ja nie an das Ergebnis "Center". Bei dem Layoutparsing kann ich allerdings nicht verstehen, warum hier "B" geskippt wird; "B" hat nirgends wo anders eine Bedeutung (nicht so wie "C").
    Geändert von Bubble Gum (21.06.2017 um 10:24 Uhr)

  4. #3
    Avatar von Tuxpower
    Registriert seit
    04.04.2016
    Beiträge
    33
    Thanked 6 Times in 6 Posts

    Standard AW: [Java] PopupParser - "Definitionen"/"Daten" verstanden, parser aber nicht (Beispiele)

    Wäre es nicht eine Idee, mal in den Javascript-Client reinzuschauen? Ich nutze Knuddels zwar schon länger nicht mehr. Aber wie ich aus den Themen hier ein wenig mitbekommen habe, ist der Java-Client den du analysierst veraltet. Kann zwar natürlich auch sein, dass sie aus Gründen der Kompabilität eine 1:1 Implementierung des Java-Clients in JavaScript durchgeführt haben. Vielleicht jedoch auch nicht, und es ergeben sich neue Erkenntnisse für dich.

  5. The Following User Says Thank You to Tuxpower For This Useful Post:

    Negok (21.07.2017)

  6. #4

    Registriert seit
    28.10.2011
    Beiträge
    625
    Thanked 279 Times in 168 Posts

    Standard AW: [Java] PopupParser - "Definitionen"/"Daten" verstanden, parser aber nicht (Beispiele)

    Den HTMLChat kannst du knicken, das ganze ist viel zu hart obfuscated und vor allem stacked-evaled (Funktionen werden verschachtelt aufgerufen, wo die Zuweisung durch die harte Obfuscation von uns nicht easy abgerufen werden kann).

    Mich würde aber auch mal interessieren, ob die einen fertigen Obfuscator dafür genommen haben oder sich ihren eigenen geschrieben habe (was ich allerdings nicht so sehr glaube).

  7. #5

    Registriert seit
    13.02.2011
    Beiträge
    54
    Thanked 79 Times in 49 Posts

    Standard AW: [Java] PopupParser - "Definitionen"/"Daten" verstanden, parser aber nicht (Beispiele)


  8. #6

    Registriert seit
    28.10.2011
    Beiträge
    625
    Thanked 279 Times in 168 Posts

    Standard AW: [Java] PopupParser - "Definitionen"/"Daten" verstanden, parser aber nicht (Beispiele)

    Das ganze wird definitiv nicht mit webpack gepackt Das erkennt man relativ einfach am ganzen Stil.

Ähnliche Themen

  1. Antworten: 1
    Letzter Beitrag: 29.12.2013, 14:31
  2. Antworten: 2
    Letzter Beitrag: 29.09.2012, 15:24
  3. Hacker-Angriff auf "World of WarCraft" und "Diablo 3"!
    Von Waterpolo im Forum Gaming-News
    Antworten: 3
    Letzter Beitrag: 10.08.2012, 23:35
  4. "Project Fiona" von "RAZER" im exklusiven Hands-On!
    Von RavoxX im Forum Internet und Technik
    Antworten: 2
    Letzter Beitrag: 17.01.2012, 17:39
Diese Seite nutzt Cookies, um das Nutzererlebnis zu verbessern. Klicken Sie hier, um das Cookie-Tracking zu deaktivieren.