Dans cette épreuve, on nous fournit un exécutable Windows (qui se révèle être un fichier programmé en .NET).
La décompilation de la fonction Main() donne le code suivant:
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(); }
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.
Le code IL de cette fonction est le suivant:
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
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 !
38 L_004b: ldloc.0 39 L_004c: call System.Void System.Console::WriteLine(System.String) 40 L_0051: ret
On peut maintenant sauvegardé et lancé notre exécutable patché !
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