I'm currently doing an exercise, where I have to find a way to "pass" the level (It's a reverse engineering exercise, I decompiled it with IDA).
The level function consists of 3 while loops, from each I have to break to get to the next one. To pass the level, I have to input something that will pass through the 3 checks. Code is as follows:
while ( 1 )
{
while ( 1 )
{
while ( 1 )
{
memset(Buffer, 0, sizeof(Buffer));
stream = _acrt_iob_func(0);
fgets(Buffer, 1020, stream);
if ( strlen(Buffer) >= 0x1E )
break;
}
if ( first_check_string(Buffer) )
break;
}
if ( second_check_string(Buffer) )
break;
}
return printf(aWellDone, Buffer[0]);
}
The first_check_string function:
int __cdecl first_check_string(_BYTE *str_addr)
{
while ( *str_addr )
{
if ( (char)*str_addr < 97 || (char)*str_addr > 122 )
return 0;
if ( ((char)*str_addr - 97) % 3 )
return 0;
++str_addr;
}
return 1;
}
The second_string_check function:
BOOL __cdecl second_check_string(char *Str)
{
int v2; // [esp+4h] [ebp-8h]
char *i; // [esp+8h] [ebp-4h]
if ( strlen(Str) % 4 )
return 0;
v2 = 0;
for ( i = Str; *(_DWORD *)i; i += 4 )
v2 ^= *(_DWORD *)i;
return v2 == 1970760046;
}
For the first if
, i just have to enter a string longer than 1E
, or 30 in decimal.
The second, I have to enter only a-z character, but only ones that their ascii - 97 is divisible by 3. So only options are: a, d, g, j, m, p, s, v, y.
But there's a catch - I have to enter at least 1019 characters, since otherwise, the fgets
will get the newline 0x0A character, and the first_check_string
function will not pass.
So I enter 1019 "a"s for example.
I pass the first 2 ifs. But the 3rd if function second_check_string
requires my string to be divisble by 4, which can't be if I enter 1019 chars. And if I enter less, the first_check_string
function will encounter the 0x0A
newline char and return 0.
If anyone got any idea of how could I approach this, I would be grateful.
GENERALIZED SOLUTION
To enter a NUL 0x00
byte, we need to redirect the program to read from a file instead from the user's keyboard.
To do so, we execute the program as follows:
prog.exe < file
this makes the standard input, which fgets
uses, become the file.
In the file we can any bytes we want, including the NUL
character.
We can do so either by using a programming language to write to that file, or a hex editor (I used 010 editor).
Cheers to EVERYONE who helped me!