Ist die Geschäftskontinuität nicht Teil der Sicherheit?
Andrea Covello
Adobe hat Folgendes zum JSXBIN-Format zu sagen:
JSXBIN Dateien sind in JavaScript kompiliert damit der Source Code nicht offenliegt…
Laut dem Dokument wird JSXBIN aus folgenden Gründen verwendet:
Dieses Labs wird aufzeigen, dass JSXBINs nichts anderes als obfuscated JSX-Dateien sind. Mit einigem Aufwand kann der Quellecode kenntlich gemacht werden und mit etwas mehr Aufwand kann der Code sogar vollständig zu einem JSX rückkonvertiert werden.
Nachdem das ESTK fertig installiert ist, schauen wir uns an, wie wir eine Binary Version einer JSX-Datei erstellen können:
CTRL+S
und speichern die Datei. Dies ist optional.CTRL+SHIFT+E
oder benutzen Sie den entsprechenden Menüpunkt unter Datei
.Öffnen Sie nun die neu erstellte JSXBIN-Datei in einem Editor wie Notepad oder Notepad++. Als erstes fällt Ihnen auf: Es handelt sich bei einer JSXBIN nicht um eine kompilierte Executionable. Wenn wir genau hinschauen, dann bemerken wir, dass es sich nur um ASCII handelt, mit der Begrenzung auf den Zeichensatz [A-Za-z0-9]. Das erinnert zwar stark an base64-Codierung, ist es aber nicht. Sie können das, wenn Sie wollen, selbst einfach überprüfen, indem Sie versuchen, den Code nach Base64 zu decodieren. Und auch wenn eine JSXBIN die selben Zeichen zur Verschlüsselung verwendet, es ist definitiv keine binäre Datei.
Dennoch, eine JSXBIN ist nichts anderes als Code Obfuscation. Es gibt sogar Wettbewerbe, in denen es darum geht, den besten Code zu tarnen oder ihn zu enttarnen. Aber zurück zu Adobes JSXBIN. Wir können nun feststellen, dass die Funktion den Code unkenntlich zu machen nicht erfüllt ist. Weil wir brauchen nur etwas Zeit, um den Code lesbar zu machen.
Die gute Nachricht: Wir haben das ESTK und können damit jeden Klartext zu Code machen. Ganz so, wie es uns beliebt. Das ist auch der erste Schritt, den ich unternommen habe, als ich die JSXBIN decodieren wollte. Hier sind die Resultate.
Vergessen wir mal schnell die JSXBIN, die wir erstellt haben und beginnen bei null. Als erstes erstellen wir ein Script ohne jeglichen Inhalt. So sehen wir, ob dem Format JSXBIN irgendwelche statischen Komponenten zugrunde liegen.
Hier der Inhalt einer JSXBIN, die aus einem leeren JSX-Script erstellt wurde.
@JSXBIN@ES@2.0@MyBn0DzABByB
In einem nächsten Schritt erstellen wir eine JSXBIN mit nur einem Buchstaben. Zum Beispiel dem kleinen a. Der Export liest wie folgt:
@JSXBIN@ES@2.0@MyBbyBn0ABJAnAjzBjBBf0DzACByB
Wiederholen Sie das selbst, bis sie nach einigen JSXBINs die statischen oder halbstatischen Teile identifizieren können.
MyB
.ByB
.Nach der Identifikation des Teils, der wohl einen Description Header darstellen soll, und der zwei Drei-Zeichen-Blöcke, die am Anfang und am Ende einer jeden JSXBIN zu finden sind, versuchen wir nun, einzelne Zeichen und ihr Zusammenspiel zu entschlüsseln.
Zum Beispiel nehmen wir unser Script mit dem a von vorhin und fügen ein weiteres a hinzu. Wir exportieren dann aa und später auch aaa und so weiter. Danach führen wir das Experiment mit jedem weiteren Zeichen fort und probieren aus, wie sich ein JSXBIN entwickelt, wenn wir die Zeichen auf mehrere Zeilen verteilen.
Erst dann wagen wir uns daran, Objekte, Variable, Kontrollstrukturen und so weiter zu decodieren. Und dann, ganz zum Schluss, werden wir eine Kombination aus alldem probieren.
Nachdem ich eine Vielzahl Scripts mit einer breiten Variation an Zeichen und Kombinationen exportiert hatte, konnte ich auf folgende Charakteristika der Obfuscation schliessen. Ein Minuskel – also ein Kleinbuchstabe -, der keinen Data Type String repräsentiert, ist stets in der Form j[B-Za]
verschlüsselt. Der Buchstabe a wird zu jB
und z wird zu ja
. Majuskel – Grossbuchstaben – sind nur leicht anders in der Form i[B-Za]
dargestellt. A wird zu iB
und Z wird zu ia
.
Weiter habe ich einen Zählerwert festgestellt, der dem verschlüsselten Wort vorangestellt wird. Dieser Wert gibt an, wie viele Zeichen das kommende Wort hat. Bei a oder nur einem Zeichen war dieser Wert als B
angegeben, bei aa oder zwei Zeichen erschien ein C
. Dazu aber mehr im Abschnitt Zählerwert.
Die Decodierung des gesamten Alphabets bringt Folgendes zu Tage:
Minuskel | Repräsentation | Majuskel | Repräsentation |
---|---|---|---|
a | jB | A | iB |
b | jC | B | iC |
c | jD | C | iD |
d | jE | D | iE |
e | jF | E | iF |
f | jG | F | iG |
g | jH | G | iH |
h | jI | H | iI |
i | jJ | I | iJ |
j | jK | J | iK |
k | jL | K | iL |
l | jM | L | iM |
m | jN | M | iN |
n | jO | N | iO |
o | jP | O | iP |
p | jQ | P | iQ |
q | jR | Q | iR |
r | jS | R | iS |
s | jT | S | iT |
t | jU | T | iU |
u | jV | U | iV |
v | jW | V | iW |
w | jX | W | iX |
x | jY | X | iY |
y | jZ | Y | iZ |
z | ja | Z | ia |
Die Werte in dieser Tabelle treffen auf Namen, Funktionen, deren Namen und so weiter zu. Im Falle eines Data Type Strings werden die Buchstaben in der selben Form wiedergegeben. Aber der Identifier ändert. Er wird zu Fe
, was wohl aussagt, dass die folgenden Zeichen Teil eines Strings sind. Wir können nun das Wort “Test” in JSXBIN schreiben, was EiUjFjTjU
ergibt, vorangesetzt ist der Zählerwert E
. Als Data Type String geschrieben ergibt Test FeEiUjFjTjU
, mit Fe
als String Marker und E
als Zählerwert.
Die folgende Tabelle zeigt auf, welche Sonderzeichen ich im Laufe der Analyse decodiert habe.
Sonderzeichen (in string) | Beschreibung | Repräsentation |
---|---|---|
“ “ | Leerzeichen | hA |
“ | Anführungszeichen | hC |
‘ | Apostroph | hH |
& | Ampersand | hG |
\ | Backslash | ic |
: | Doppelpunkt | ha |
. | Punkt | hO |
– | Bindestrich | hN |
_ | Unterstrich | if |
? | Fragezeichen | hf |
^ | Zirkumflex | ie |
` | Accent Grave | ja |
~ | Tilde | je |
´ | Accent Aigu | lU |
+ | Plus | hL |
* | Asterisk | hK |
# | Raute | hD |
% | Prozentzeichen | hF |
/ | Slash | hP |
| | Senkrechter Strich | jc |
( | Klammer auf | hI |
) | Klammer zu | jJ |
> | Grösser als | hc |
< | Kleiner als | he |
Nun können wir auch den String Test Value in JSXBIN wiedergeben: FeKiUjFjTjUhAiWjBjMjVjF
.
Nach der Identifikation von Minuskeln, Majuskeln und Sonderzeichen sowie dem Unterschied zwischen funktionellen Strings wie Variablen und Funktionsnamen und Data Type String können wir in einem nächsten Schritt Zahlen und Nummern als numerische Werte und als Part eines Data Type Strings ausmachen.
Die Prozedur ist die selbe wie oben. Zuerst ein Export mit einer einzelnen Ziffer, dann mehreren und zum Schluss Ziffern im String auf einer und auf mehreren Zeilen.
Der erste Export besteht nur aus der Ziffer 1. Das ergibt – ohne den statischen Header – folgenden Output:
MyBbyBn0ABJAnAFdB0EzABByB
Die Ziffer 1 wird also durch dB
repräsentiert. Als String, den wir im Script als “1” angeben, wird die Ziffer als hR
verschlüsselt. Daraus folgern wir:
Ziffer | Repräsentation | Numerischer String | Repräsentation |
---|---|---|---|
0 | d [dA**] | “0” | hQ |
1 | dB | “1” | hR |
2 | dC | “2” | hS |
3 | dD | “3” | hT |
4 | dE | “4” | hU |
5 | dF | “5” | hV |
6 | dG | “6” | hW |
7 | dH | “7” | hX |
8 | dI | “8” | hY |
9 | dJ | “9” | hZ |
10 | dK | “10” | hRhQ |
11 | dL | “11” | hRhR |
12 | dM | “12” | hRhS |
13 | dN | “13” | hRhT |
14 | dO | “14” | hRhU |
15 | dP | “15” | hRhV |
16 | dQ | “16” | hRhW |
17 | dR | “17” | hRhX |
18 | dS | “18” | hRhY |
19 | dT | “19” | hRhZ |
20 | dU | “20” | hShQ |
21 | dV | “21” | hShR |
22 | dW | “22” | hShS |
23 | dX | “23” | hShT |
24 | dY | “24” | hShU |
25 | dZ | “25” | hShV |
26 | dga | “26” | hShW |
27 | dgb | “27” | hShX |
28 | dgc | “28” | hShY |
29 | dgd | “29” | hShZ |
30 | dge | “30” | hShQ |
31 | dgf | “31” | hShR |
32 | dhA | “32” | hShS |
33 | dhB | “33” | hShT |
Achtung: Die obige Tabelle listet nur die verschlüsselten Zahlen, nicht aber die vorgestellten Zählerwerte.
Wir können einen klaren Unterschied zwischen Ziffern und numerischen Strings feststellen. Letzteres ist lediglich eine Aneinanderreihung der Stringwerte von 0-9. Das heisst “22192” wird mit FeFhShShZhRhS
wiedergegeben – inklusive String Marker Fe
und Zählerwert F
. Die gleiche Ziffernfolge als Zahl wird wie ein Zähler behandelt (siehe unten) und wird als d2kAiZ
wiedergegeben.
Zählerwerte nehmen in JSXBIN verschiedene Funktionen ein. Sie können die Zahl der folgenden Zeichen angeben oder die Länge eines Strings. Es ist sogar möglich, dass da einen Art Zeilennummer ist. So wie ich das verstehe haben nicht alle Zähler denselben Startpunkt. Was sie aber alle gemein haben ist der Overflow nach einem Mehrfachen von 32.
Wir haben bereits über Zählerwerte gesprochen, ohne aber auf ihre Funktionen einzugehen. Zeit, das nachzuholen. Ein einzelner Minuskel wird mit j[B-Za]
wiedergegeben. Wenn wir den Zählerwert hinzufügen, dann erscheint a als BjB
. Schauen wir uns das Wort Test an, sowohl als funktionellen String wie auch als String Data Type. Das Wort ist vier Zeichen lang und wir haben herausgefunden, dass der vorgestellte Zählerwert E
ist. Daraus folgt: Für einen String von einem Zeichen Länge gilt B
und für vier Zeichen E
.
Versuchen wir nun etwas anderes. Wir setzen das selbe Zeichen auf mehrere Zeilen und versuchen die Zeichenfolge zu finden, die in JSXBIN angibt, wo eine Zeile umbrochen wird.
Hier mein Beispiel:
"line1" "line2" "line3"
Der JSXBIN Export mit ein bisschen Formatierung zur besseren Lesbarkeit in diesem Artikel:
MyBbyBn0AD ("line1") JAnA Fe FjMjJjOjFhR ("line2") JBnA Fe FjMjJjOjFhS ("line3") JCnA Fe FjMjJjOjFhT 0DzABByB
Ignorieren wir die erste und die letzte Zeile da dort noch andere statische Elemente sein könnten. Schauen wir also auf die mittleren Zeilen. Der String, der “line[1-3]” wiedergibt lautet FeFjMjJjOjFh[R-T]
. Um den Zeilenzähler identifizieren können, müssen wir auf die ersten vier Zeichen achten. Diese stehen im Format J[A-C]nA
. Wenn da also ein Zeilenzähler ist, dann ist er im zweiten Zeichen dieses Blocks versteckt.
Das folgende Beispiel ist Teil eines Exports mit 33 Zeilen. Wir schauen uns aber nur die vier wichtigsten Zeilen des JSXBIN-Strings an. Denn hier geschieht der Overflow. Zudem habe ich einige Formatierung zur besseren Lesbarkeit hinzugefügt.
("line26") J Z nA Fe GjMjJjOjFhShW ("line27") J ga nA Fe GjMjJjOjFhShX ("line32") J gf nA Fe GjMjJjOjFhThS ("line33") J hA nA Fe GjMjJjOjFhThT
Erneut sehen wir den String Data Type Delimiter Fe
. Und wir erkennen auch, dass der erste Buchstabe einer jeden Zeile, J
, statisch bleibt. Es folgt der Zählerwert, der entweder aus einem oder zwei Zeichen bestehen kann. Der Block wird von zwei statischen Zeichen, nA
, abgeschlossen.
Besonders bemerkenswert ist hier aber, dass nach der Zahl 26 zwei Zeichen gebraucht werden um die Zahl 27 darzustellen. Und von Zeile 32 zu 33 erfolgt ein Overflow.
Sehen wir uns also an, was passiert, wenn wir die binäre Repräsentation der Zähler ansehen:
Z 01011010 ga 01100111 01100001 gf 01100111 01100110 hA 01101000 01000001
Wieso folgt auf 01011011
nicht 01011100
nach der Darstellung von Z? Das erste Byte repräsentiert das Zeichen [ in ASCII, das zweite \. Der Overflow geschieht also aus dem Grund, dass in einer JSXBIN nur [A-Za-z0-9] verwendet werden.
Die folgende Tabelle zeigt alle Zählerwerte bis zum ersten Overflow sowie einige weitere Beispiele für Overflows auf.
Zählerwert | Repräsentation |
---|---|
0 | A (unbestätigt) |
1 | B |
2 | C |
3 | D |
4 | E |
5 | F |
6 | G |
7 | H |
8 | I |
9 | J |
10 | K |
11 | L |
12 | M |
19 | T |
20 | U |
21 | V |
22 | W |
23 | X |
24 | Y |
25 | Z |
26 | ga |
27 | gb |
28 | gc |
29 | gd |
30 | ge |
31 | gf |
32 | hA |
63 | hf |
64 | iA |
95 | if |
96 | jA |
127 | jf |
128 | kA |
Nachdem wir nun einzelne Zeichen wie auch Datentypen – Data Type String oder nicht – identifizieren können, haben wir die Nummerierungsstruktur erkannt.
Jetzt wollen wir anschauen, wie Variablen deklariert werden. Das Vorgehen ist gleich wie vorhin. Wir bauen Schritt für Schritt eine stets komplexer werdende Variable auf. Das haben wir aber oben schon ausreichend demonstriert, daher kommen wir gleich zu einem komplexeren Beispiel:
var a=2; a=1; a; var b=null; b=1; var test=1; test = a;
Der Export (wieder mit Formatierung zur Lesbarkeit):
MyB byB n0AG a) JAnA Sz BjB ByB ndCft b) JBnA S ByB ndBff c) JCnA V BfyB d) JDnA Sz BjC CyB nbft e) JEnA S CyB ndBff f) JFnA Sz EjUjFjTjU DyB ndBft g) JGnA S DyB V BfyB nff AD B40Bi AC 4B0Ai AD 4C0Ai AAD AzAE ByB
Zeile | Block #1 | Block #2 | Block #3 | Block #4 | Block #5 | Block #6 |
---|---|---|---|---|---|---|
a) | JAnA | Sz | BjB | ByB | ndCft | |
A (siehe Zählerwert) | Sz taucht auf, wenn eine Variable gleichzeitig deklariert und definiert wird. | siehe Alphabet und Zählerwert | ByB Referenziert möglicherweise etwas | dC Substitution der Ziffer 2 | ||
b) | JBnA | S | ByB | ndBff | ||
B (siehe Zählerwert) | S taucht auf, wenn eine deklarierte Variable einen neuen Wert erhält. | ByB Referenziert möglicherweise etwas | dB Substitution der Ziffer 1 | |||
c) | JCnA | V | BfyB | |||
C (siehe Zählerwert) | V Taucht auf, wenn eine Variable referenziert wird | BfyB gleicht stark ByB und könnte deshalb eine Referenz zu den Daten der Variablen sein. | ||||
g) | JGnA | S | DyB | V | BfyB | nff |
G (siehe Zählerwert) | S Taucht auf, wenn eine deklarierte Variable einen neuen Wert erhält. | DyB Möglicherweise eine Referenz zur Variable test | V Taucht auf, wenn eine Variable referenziert wird | BfyB gleicht stark ByB und könnte deshalb eine Referenz zu den Daten der Variablen sein. | nff Unbekannt, gleicht aber dem letzten Block in Zeile b) stark, wenn dB entfernt wird. |
Die Zeile unter g), AD B40Bi AC 4B0Ai AD 4C0Ai AAD
, ist wichtig, aber ihre Bedeutung ist bis jetzt unbekannt. Eine ähnliche Zeile taucht immer auf, wenn Variablen verwendet werden.
Analysieren wir nun Funktionen. Wir fangen wieder mit einer leeren Funktion an und exportieren Schritt für Schritt komplexere Inhalte.
Wir fangen mit einer simplen, leeren Funktion an.
function a(){} function b(){} function c(){}
Der JSXBIN-Export:
MyB byB nAD MAn0 Dz BjB B0A MBn0 Dz BjC CAB MCn0 Dz BjD DAC 0EzAE ByB
Wenn wir das Beispiel ansehen, können wir vielleicht einige der Elemente identifizieren.
M[A-C]n0
gleicht dem des Zählerwerts.Dz
ist eine Art Indikator, der die Deklaration einer Funktion begleitet. Er ähnelt Sz
(siehe Variablen).Bj[B-D]
ist offensichtlich der Name einer Funktion.Erstellen wir nun einen Block mit leeren Funktionen, aber diesmal mit mehreren Zeilen pro Funktion.
1) function a(){ 2) 3) 4) 5) 6) } 7) function b(){ 8) 9) 10) 11) 12) }
Die Zeilennummern sind zur besseren Lesbarkeit hinzugefügt worden. Sie sind nicht Teil des Scripts.
Der Export (die Zeilennummern a) und b) sind nicht Teil des Exports)
MyB byB nAC a) MAn0 Dz BjB BAF b) MGn0 Dz BjC CAL 0EzAD ByB
Wenn wir Zeile a) mit der ersten Funktionszeile (MAn0 Dz BjB B0A
) vergleichen, sehen wir, dass die letzten zwei Zeichen sich verändert haben. Wenn wir Zeile b) mit der zweiten Funktionszeile (MBn0 Dz BjC CAB
) vergleichen, dann fällt auf, dass die letzten zwei Zeichen sich verändert haben. Der einzige Unterschied liegt darin, dass im Quellcode leere Zeichen sind.
Daher lässt sich schliessen, dass das zweite Zeichen die Zeilennummer angibt, auf der die Deklaration der Funktion (function a(){
) beginnt. Das letzte Zeichen zeigt an, wo die Funktion mit }
aufhört.
Bevor wir uns komplexere Funktionsdefinitionen ansehen werfen wir einen Blick auf Beispiele die mehr als nur eine Funktion aufrufen.
function xxa(){} xxa(); function bbb(){} bbb(); function ccc(){} ccc(); function ddd(){} eee(); function eee(){} ddd(); xxa(); bbb(); ccc(); ddd(); eee(); xxa(); bbb(); ccc(); ddd(); eee(); xxa(); bbb(); ccc(); ddd(); eee();
Der JSXBIN-Export:
MyB byB nAF MAn0 Dz DjYjYjB B0A MCn0 Dz DjCjCjC CAC MEn0 Dz DjDjDjD DAE MGn0 Dz DjEjEjE EAG MIn0 Dz DjFjFjF FAI U JBnA EjB fnf JDnA EjC fnf JFnA EjD fnf JHnA EjF fnf JJnA EjE fnf JKnA EjB fnf JLnA EjC fnf JMnA EjD fnf JNnA EjE fnf JOnA EjF fnf JPnA EjB fnf JQnA EjC fnf JRnA EjD fnf JSnA EjE fnf JTnA EjF fnf JUnA EjB fnf JVnA EjC fnf JWnA EjD fnf JXnA EjE fnf JYnA EjF fnf 0DzAG ByB
Indem wir den JSXBIN-String analysieren, können wir die erkennen, dass die Funktionsaufrufe zwischen den Funktionsdeklarationen nach unten verschoben werden. Daher werden die Deklarationen am Anfang des JSXBIN-Strings gebündelt. Dies wird bemerkbar, wenn wir das zweite Zeichen nach M
oder J
ansehen, das die Zeilennummer angibt.
Wir können auch die Struktur eines Funktionsaufrufs erkennen.
J[Zählerwert]nA
.Ej[Referenz]
).U
ist ebenfalls unbekannt.Wenn wir einen genaueren Blick auf den zweiten Block werfen und den ersten Funktionsaufruf (xxa()
) als Beispiel nehmen, sehen wir Folgendes: Die Definition der Funktion xxa()
kommt der Zeile JBnA EjB fnf
gleich. Bemerkenswert ist, dass das erste Zeichen des letzten Blocks in der Funktiosdeklaration gleich dem letzten Zeichen im zweiten Block des Funktionsaufrufs ist (in diesem Falle B
). Daher scheint dies der Referenzwert zu sein und Ej
muss folglich eine Art generische Funktionsaufrufsoperation sein.
Wie bereits angesprochen sehen wir uns nun Funktionen mit mehr Kontext an. Wir werden sehen, dass gewisse Elemente der vorherigen Sektion sich verändern werden, wenn neue Elemente hinzugefügt werden.
1) function a(){ 2) //test1 3) "alpha" 4) //test2 5) }
Die Zahlen von 1 bis 5 sind nicht Teil des Scripts sondern wurden zur besseren Lesbarkeit hinzugefügt.
Der JSXBIN-Export mit etwas Formatierung:
MyB byB nAB a) MA byB n0 AB b) JCnA FeFjBjMjQjIjB 0 c) Dz BjB BAE 0EzACByB
Wenn wir die Zeile a) mit ihrem Äquivalent aus dem ersten Beispiel (MAn0 Dz BjB BAF
) vergleichen, fallen uns grosse Unterschiede ins Auge.
A
wird byB
eingefügt.AB
ist hinzugekommen.Zwei weitere bemerkenswerte Details:
Zeile c) beinhaltet die verbleibenden Teile der Funktionsdeklaration des ersten Beispiels MAn0 Dz BjB BAF
. Das letzte Zeichen F
ist gleich der Zahl 5, welche die Zeile wiedergibt, auf der die Funktionsdeklaration endet.
Schauen wir uns nun ein Beispiel an, bei dem die Funktion auf einer anderen Zeile, einer Zeile unterhalb der Deklaration, aufgerufen wird.
1) function a(){ 2) //test1 3) "alpha" 4) //test2 5) } 6) 7) a();
Die Zahlen von 1 bis 5 sind nicht Teil des Scripts sondern wurden zur besseren Lesbarkeit hinzugefügt.
Der JSXBIN-Export mit etwas Formatierung:
MyB byB nAB a) MA byB n0 AB b) JCnA FeFjBjMjQjIjB 0 c) Dz BjB BAE d) B e) JGnA EjB fnf 0DzAC ByB
B
im letzten Block referenziert das erste Zeichen im letzten Block auf Linie c).Bis anhin waren unsere Beispiele recht einfach und hatten nicht sehr viel Inhalt. Wir werden nun die Funktion mit einer Variablendeklaration erweitern.
1) function a(){ 2) //test1 3) var non=null; 4) //test2 5) }
Die JSXBIN:
MyB byB nAB a) MA byB n0 AB b) JCnA Sz DjOjPjO BA nbft c) AB B40Bi AAB d) Az BjB CAE 0EzAD ByB
Die Zeile b) ist die Variablendefinition (siehe Variablen). Wie dort erwähnt, finden wir eine Zeile, die immer noch keine bekannte Funktionalität hat. Eine ähnliche Zeile erscheint hier als Zeile c). Eine weitere Deviation können wir in Zeile d) feststellen: Was bisher Dz
war, ist mit der Variablendeklaration zu Az
geworden.
Erweitern wir unser Beispiel:
1) function a(){ 2) //test1 3) var non=null; 4) var alpha="alpha"; 5) //test2 6) }
Die JSXBIN:
MyB byB nAB a) MA byB n0AC b) JCnA Sz DjOjPjO BA nbft c) JDnA Sz FjBjMjQjIj BCB neFjBjMjQjIjB ft d) AC C 4B0Ai A B40Bi AAC e) Az BjB DAF 0EzAE ByB
In diesem Beispiel ist die Zeile c) die neu hinzugefügte Variable "alpha"
. Die Variable betrifft auch Zeile d), die einst AB B40Bi AAB
war und jetzt AC C 4B0Ai A B40Bi AAC
ist.
B
zu C
gewechselt und könnte auch eine Art Zähler sein.C 4B0Ai A
.B
zu C
. Das könnte mit dem ersten Punkt dieser drei neuen Elemente zu tun haben.Es passiert viel wenn eine JSX in eine JSXBIN konvertiert wird. Den ganzen Algorithmus zu reversieren würde viel Zeit in Anspruch nehmen. Dies besonders, weil noch nicht alle Teile des Codes voll verstanden werden.
Eine kurze Zusammenfassung meiner bisherigen Erkenntnisse:
M[A-Z]
auf, der anzeigt, wo eine Funktion beginnt.Ej[Referenzzeichen]
.Einige Teile des Codes werden gar nicht erst in eine JSXBIN aufgenommen. Darunter sind:
;
in den InstruktionenHier ziehen wir vorerst einen Schlussstrich der Reversion von JSXBIN zu JSX. Aber mit den Erkenntnissen dieses Labs ist es möglich, ein simples Script zu schreiben, das die identifizierten Elemente in ihre Ursprungsform zurückbringt. Es kann aber sein, dass einige Elemente von diesem Script falsch interpretiert werden und somit durch falsche Werte ersetzt werden.
Dieser Artikel ist so verfasst, dass er als Basis für jeden dient, der sich diesem Projekt widmen will. Es gibt noch viel zu tun, nebst Variablenformung und Funktionsdeklaration. Zum Beispiel Kontrollstrukturen wie for
und while
sowie mathematische Operationen.
Unsere Spezialisten kontaktieren Sie gern!
Andrea Covello
Michèle Trebo
Lucie Hoffmann
Yann Santschi
Unsere Spezialisten kontaktieren Sie gern!