Cette page vous donne les différences entre la révision choisie et la version actuelle de la page.
— |
csaw2012_quals:reversing:csawqualificationeasy.exe [2017/04/09 15:33] (Version actuelle) |
||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
+ | ====== CSAWQualificationEasy.exe ====== | ||
+ | ==== Overview ==== | ||
+ | |||
+ | Dans cette épreuve, on nous fournit un exécutable Windows (qui se révèle être un fichier programmé en .NET). | ||
+ | |||
+ | ==== First step ==== | ||
+ | |||
+ | La décompilation de la fonction Main() donne le code suivant: | ||
+ | |||
+ | <file C# source.cs>private static void Main(string[] args) | ||
+ | { | ||
+ | Console.WriteLine("Okay, going to compute the key. Have to remember to write it out at the end! I keep forgetting!"); | ||
+ | |||
+ | string text = ""; | ||
+ | byte[] array = Program.encrypted; | ||
+ | |||
+ | for (int i = 0; i < array.Length; i++) | ||
+ | { | ||
+ | byte b = array[i]; | ||
+ | |||
+ | text += Convert.ToChar((int)(b ^ 255)); | ||
+ | } | ||
+ | |||
+ | Console.ReadLine(); | ||
+ | }</file> | ||
+ | |||
+ | Le problème réside simplement dans l'affichage de la sortie. | ||
+ | Pour cela, nous allons simplement patché le binaire en appelant la fonction WriteLine de la classe Console. | ||
+ | |||
+ | ==== Patch me ==== | ||
+ | |||
+ | Le code IL de cette fonction est le suivant: | ||
+ | |||
+ | <file> | ||
+ | 0 L_0000: nop | ||
+ | 1 L_0001: ldstr "Okay, going to compute the key. Have to remember to write it out at the end! I keep forgetting!" | ||
+ | 2 L_0006: call System.Void System.Console::WriteLine(System.String) | ||
+ | 3 L_000b: nop | ||
+ | 4 L_000c: ldstr "" | ||
+ | 5 L_0011: stloc.0 | ||
+ | 6 L_0012: nop | ||
+ | 7 L_0013: ldsfld System.Byte[] CSAWQualificationEasy.Program::encrypted | ||
+ | 8 L_0018: stloc.2 | ||
+ | 9 L_0019: ldc.i4.0 | ||
+ | 10 L_001a: stloc.3 | ||
+ | 11 L_001b: br.s 30 -> ldloc.3 | ||
+ | 12 L_001d: ldloc.2 | ||
+ | 13 L_001e: ldloc.3 | ||
+ | 14 L_001f: ldelem.u1 | ||
+ | 15 L_0020: stloc.1 | ||
+ | 16 L_0021: nop | ||
+ | 17 L_0022: ldloc.0 | ||
+ | 18 L_0023: ldloc.1 | ||
+ | 19 L_0024: ldc.i4 0xff | ||
+ | 20 L_0029: xor | ||
+ | 21 L_002a: call System.Char System.Convert::ToChar(System.Int32) | ||
+ | 22 L_002f: box System.Char | ||
+ | 23 L_0034: call System.String System.String::Concat(System.Object,System.Object) | ||
+ | 24 L_0039: stloc.0 | ||
+ | 25 L_003a: nop | ||
+ | 26 L_003b: ldloc.3 | ||
+ | 27 L_003c: ldc.i4.1 | ||
+ | 28 L_003d: add | ||
+ | 29 L_003e: stloc.3 | ||
+ | 30 L_003f: ldloc.3 | ||
+ | 31 L_0040: ldloc.2 | ||
+ | 32 L_0041: ldlen | ||
+ | 33 L_0042: conv.i4 | ||
+ | 34 L_0043: clt | ||
+ | 35 L_0045: stloc.s V_4 | ||
+ | 36 L_0047: ldloc.s V_4 | ||
+ | 37 L_0049: brtrue.s 12 -> ldloc.2 | ||
+ | 38 L_004b: call System.String System.Console::ReadLine() ; public static string ReadLine() | ||
+ | 39 L_0050: pop | ||
+ | 40 L_0051: ret </file> | ||
+ | |||
+ | Les dernières instructions sont les plus importantes, on fait un appel à ReadLine() (inst 38), on retire la valeur de retour de la pile (inst 39) et on quitte la fonction (inst 40). | ||
+ | Pour ajouté notre chaîne déchiffré, il faut mettre sur la pile d'évaluation notre chaîne et appelé WriteLine() (plus besoin de pop, c'est une fonction void). | ||
+ | La chaîne est dans la variable local d'indice 0, on peut le voir par la concaténation (inst 23) qui stock le résultat dans la variable locale 0 (inst 24). | ||
+ | Maintenant qu'on sait ça, il suffit juste de mettre en oeuvre ! | ||
+ | |||
+ | <file>38 L_004b: ldloc.0 | ||
+ | 39 L_004c: call System.Void System.Console::WriteLine(System.String) | ||
+ | 40 L_0051: ret </file> | ||
+ | |||
+ | On peut maintenant sauvegardé et lancé notre exécutable patché ! | ||
+ | |||
+ | <file>C:\Users\Xartrick>CSAWQualificationEasy.exe | ||
+ | Okay, going to compute the key. Have to remember to write it out at the end! I keep forgetting! | ||
+ | The key is 9c09f8416a2206221e50b98e346047b7</file> |