0x0804862c 7377 6f72 643a 2000 2564 0000 0000 0000 sword: .%d......
[0x080485ec]> wos 0x03 @ str.Sdvvzrug_RN!17
[0x080485ec]> px
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0x080485ec 496e 7661 6c69 6420 5061 7373 776f 7264 Invalid Password
0x080485fc 2100 5061 7373 776f 7264 204f 4b21 2121 !.Password OK!!!
0x0804860c 203a 2900 494f 4c49 2043 7261 636b 6d65 :).IOLI Crackme
0x0804861c 204c 6576 656c 2030 7830 330a 0050 6173 Level 0x03..Pas
0x0804862c 7377 6f72 643a 2000 2564 0000 0000 0000 sword: .%d......
[0x080485ec]>
[0x080483d0]> pdd@main
/* r2dec pseudo code output */
/* ./crackme0x04 @ 0x8048509 */
#include <stdint.h>
int32_t main (void) {
int32_t var_78h;
int32_t var_4h;
eax = 0;
eax += 0xf;
eax += 0xf;
eax >>= 4;
eax <<= 4;
printf ("IOLI Crackme Level 0x04\n");
printf ("Password: ");
eax = &var_78h;
scanf (0x8048682, eax);
eax = &var_78h;
check (eax);
eax = 0;
return eax;
}
Let's enter check.
#include <stdint.h>
int32_t check (char * s) {
char * var_dh;
uint32_t var_ch;
uint32_t var_8h;
int32_t var_4h;
char * format;
int32_t var_sp_8h;
var_8h = 0;
var_ch = 0;
do {
eax = s;
eax = strlen (eax);
if (var_ch >= eax) {
goto label_0;
}
eax = var_ch;
eax += s;
eax = *(eax);
var_dh = al;
eax = &var_4h;
eax = &var_dh;
sscanf (eax, eax, 0x8048638);
edx = var_4h;
eax = &var_8h;
*(eax) += edx;
if (var_8h == 0xf) {
printf ("Password OK!\n");
exit (0);
}
eax = &var_ch;
*(eax)++;
} while (1);
label_0:
printf ("Password Incorrect!\n");
return eax;
}
manually analyze with both the assembly and pseudo code we can simply write down the C-like code to describe this function:
#include <stdint.h>
int32_t check(char *s)
{
var_ch = 0;
var_8h = 0;
for (var_ch = 0; var_ch < strlen(s); ++var_ch)
{
var_dh = s[var_ch];
sscanf(&var_dh, %d, &var_4h); // read from string[var_ch], store to var_4h
var_8h += var_4h;
if(var_8h == 0xf)
printf("Password OK\n");
}
printf("Password Incorrect!\n");
return 0;
}
In short, it calculates the Digit Sum of a number (add a number digit by digit. for example, 96 => 9 + 6 = 15) :
./crackme0x04
IOLI Crackme Level 0x04
Password: 12345
Password OK!
./crackme0x04
IOLI Crackme Level 0x04
Password: 96
Password OK!
check again, it uses scanf() to get our input and pass it to check() as parameter.
[0x080483d0]> pdd@main
/* r2dec pseudo code output */
/* ./crackme0x05 @ 0x8048540 */
#include <stdint.h>
int32_t main (void) {
int32_t var_78h;
int32_t var_4h;
eax = 0;
eax += 0xf;
eax += 0xf;
eax >>= 4;
eax <<= 4;
printf ("IOLI Crackme Level 0x05\n");
printf ("Password: ");
eax = &var_78h;
scanf (0x80486b2, eax); // 0x80486b2 is %s
eax = &var_78h;
check (eax);
eax = 0;
return eax;
}
the check() function:
/* r2dec pseudo code output */
/* ./crackme0x05 @ 0x80484c8 */
#include <stdint.h>
int32_t check (char * s) {
char * var_dh;
uint32_t var_ch;
uint32_t var_8h;
int32_t var_4h;
char * format;
int32_t var_sp_8h;
var_8h = 0;
var_ch = 0;
do {
eax = s;
eax = strlen (eax);
if (var_ch >= eax) {
goto label_0;
}
eax = var_ch;
eax += s;
eax = *(eax);
var_dh = al;
eax = &var_4h;
eax = &var_dh;
sscanf (eax, eax, 0x8048668); // 0x8048668 is %d
edx = var_4h;
eax = &var_8h;
*(eax) += edx;
if (var_8h == 0x10) {
eax = s;
parell (eax);
}
eax = &var_ch;
*(eax)++;
} while (1);
label_0:
printf ("Password Incorrect!\n");
return eax;
}
The same, we can write our own C-like pseudo code.
#include <stdint.h>
int32_t check(char *s)
{
var_ch = 0;
var_8h = 0;
for (var_ch = 0; var_ch < strlen(s); ++var_ch)
{
var_dh = s[var_ch];
sscanf(&var_dh, %d, &var_4h); // read from string[var_ch], store to var_4h