Выбрать главу

*(eax)++;

} while (1);

label_0:

printf ("Password Incorrect!\n");

return eax;

}

Correct the sscanf part and parell part, both of them were generated incorrectly:

int32_t check (char * s, void* envp)

{

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 == 0x10)

parell(s, envp);

}

printf("Password Incorrect!\n");

return 0;

}

no more info, we have to reverse parell() again.

#include <stdint.h>

uint32_t parell (char * s, char * arg_ch) {

sscanf (s, %d, &var_4h);

if (dummy (var_4h, arg_ch) == 0)

return 0;

for (var_bp_8h = 0; var_bp_8h <= 9; ++var_bp_8h){

if (var_4h & 1 == 0){

printf("Password OK!\n");

exit(0);

}

}

return 0;

}

well, there is a new check condition in parell() -- dummy (var_4h, arg_ch) == 0. then reverse dummy!

[0x080484b4]> pdd@sym.dummy

/* r2dec pseudo code output */

/* ./crackme0x06 @ 0x80484b4 */

#include <stdint.h>

int32_t dummy (char ** s1) {

int32_t var_8h;

int32_t var_4h;

char * s2;

size_t * n;

var_4h = 0;

do {

eax = 0;

edx = eax*4;

eax = s1;

if (*((edx + eax)) == 0) {

goto label_0;

}

eax = var_4h;

ecx = eax*4;

edx = s1;

eax = &var_4h;

*(eax)++;

eax = *((ecx + edx));

eax = strncmp (eax, 3, "LOLO");

} while (eax != 0);

var_8h = 1;

goto label_1;

label_0:

var_8h = 0;

label_1:

eax = 0;

return eax;

}

looks like a loop to process string. we can beautify it.

[0x080484b4]> pdd@sym.dummy

/* r2dec pseudo code output */

/* ./crackme0x06 @ 0x80484b4 */

#include <stdint.h>

int32_t dummy (char ** s1) {

for (var_4h = 0; strncmp(s1[var_4h], "LOLO", 3) != 0; var_4h++){

if (s1[i] == NULL)

return 0;

}

return 1;

}

There are 3 constraints to crackme_0x06:

   • Digit Sum

   • Odd Number

   • should have an environment variable whose name started with "LOL".

$ ./crackme0x06

IOLI Crackme Level 0x06

Password: 12346

Password Incorrect!

$ export LOLAA=help

$ ./cracke0x06

IOLI Crackme Level 0x06

Password: 12346

Password OK!

a weird "wtf?" string.

$ rabin2 -z ./crackme0x07

[Strings]

nth paddr vaddr len size section type string

―――――――――――――――――――――――――――――――――――――――――――――――――――――――

0 0x000007a8 0x080487a8 4 5 .rodata ascii LOLO

1 0x000007ad 0x080487ad 20 21 .rodata ascii Password Incorrect!\n

2 0x000007c5 0x080487c5 13 14 .rodata ascii Password OK!\n

3 0x000007d3 0x080487d3 5 6 .rodata ascii wtf?\n

4 0x000007d9 0x080487d9 24 25 .rodata ascii IOLI Crackme Level 0x07\n

5 0x000007f2 0x080487f2 10 11 .rodata ascii Password:

again, no password string or compare in main(). I put the simplified pseudo code here. var_78h is likely to a char *pointer (string) .

#include <stdint.h>

int32_t main (int32_t arg_10h) {

printf ("IOLI Crackme Level 0x07\n");

printf ("Password: ");

scanf (%s, &var_78h);

return fcn_080485b9 (&var_78h, arg_10h);

}

due to the symbol info lost, neither aa nor aaa show the name of functions. we can double check this in "flagspace". Radare2 use fcn_080485b9 as the function name. It's a common case in reverse engineering that we don't have any symbol info of the binary.

[0x080487fd]> fs symbols

[0x080487fd]> f

0x08048400 33 entry0

0x0804867d 92 main

0x080487a4 4 obj._IO_stdin_used

decompile the fcn_080485b9():

[0x080485b9]> pdfc

; CALL XREF from main @ 0x80486d4

/ 118: fcn.080485b9 (char *s, int32_t arg_ch);

| ; var char *var_dh @ ebp-0xd

| ; var signed int var_ch { >= 0xffffffffffffffff} @ ebp-0xc

| ; var uint32_t var_8h @ ebp-0x8

| ; var int32_t var_bp_4h @ ebp-0x4

| ; arg char *s @ ebp+0x8

| ; arg int32_t arg_ch @ ebp+0xc

| ; var char *format @ esp+0x4

| ; var int32_t var_sp_8h @ esp+0x8

| 0x080485b9 55 push ebp

| 0x080485ba 89e5 mov ebp, esp

| 0x080485bc 83ec28 sub esp, 0x28

| 0x080485bf c745f8000000. mov dword [var_8h], 0

| 0x080485c6 c745f4000000. mov dword [var_ch], 0

| ; CODE XREF from fcn.080485b9 @ 0x8048628

| .-> 0x080485cd 8b4508 mov eax, dword [s]

| : 0x080485d0 890424 mov dword [esp], eax ; const char *s

| : 0x080485d3 e8d0fdffff call sym.imp.strlen ; size_t strlen(const char *s)

| : 0x080485d8 3945f4 cmp dword [var_ch], eax

| ,==< 0x080485db 734d jae 0x804862a

| |: 0x080485dd 8b45f4 mov eax, dword [var_ch]