Regardons ce que fait la fonction main
:
4438 <main> 4438: 3150 9cff add #0xff9c, sp 443c: 3f40 b444 mov #0x44b4 "Enter the password to continue.", r15 4440: b012 6645 call #0x4566 <puts> 4444: 0f41 mov sp, r15 4446: b012 8044 call #0x4480 <get_password> 444a: 0f41 mov sp, r15 444c: b012 8a44 call #0x448a <check_password> 4450: 0f93 tst r15 4452: 0520 jnz #0x445e <main+0x26> 4454: 3f40 d444 mov #0x44d4 "Invalid password; try again.", r15 4458: b012 6645 call #0x4566 <puts> 445c: 093c jmp #0x4470 <main+0x38> 445e: 3f40 f144 mov #0x44f1 "Access Granted!", r15 4462: b012 6645 call #0x4566 <puts> 4466: 3012 7f00 push #0x7f 446a: b012 0245 call #0x4502 <INT> 446e: 2153 incd sp 4470: 0f43 clr r15 4472: 3150 6400 add #0x64, sp
Cette fois ci, pas d'appel à une fonction create_password()
comme dans le niveau précédent (New Orleans). On regarde donc directement la fonction check_password()
:
448a <check_password> 448a: bf90 6c7b 0000 cmp #0x7b6c, 0x0(r15) 4490: 0d20 jnz $+0x1c 4492: bf90 3548 0200 cmp #0x4835, 0x2(r15) 4498: 0920 jnz $+0x14 449a: bf90 4625 0400 cmp #0x2546, 0x4(r15) 44a0: 0520 jne #0x44ac <check_password+0x22> 44a2: 1e43 mov #0x1, r14 44a4: bf90 305b 0600 cmp #0x5b30, 0x6(r15) 44aa: 0124 jeq #0x44ae <check_password+0x24> 44ac: 0e43 clr r14 44ae: 0f4e mov r14, r15 44b0: 3041 ret
La fonction prend l'adresse où est stockée le mot de passe entré par l'utilisateur dans le registre r15
. Puis elle compare deux à deux les caractères stockés à cette adresse avec des constantes. Le mot de passe est donc sous nos yeux, on fait un peu attention à l'endianness et on trouve facilement le password :
>>> "6c7b35484625305b".decode("hex") 'l{5HF%0['