Tuesday, April 21, 2009

KeyGenMe #4 :: C++ :: Difficulty : 4 [HARD !]

KeyGenMe Location : KeyGenMe #4 @ Crackmes.de
Solution Location : Not Solved Yet.

My hardest KeyGenMe yet !! KeyGenMe #4. It's coded in ANSI C++. Features :
(*) NOT Packed
(*) NOT Encrypted

The Rules :
(*) NO Patching
(*) NO Brute-forcing

The Tasks :
1. Try to get Status as "VALID :) !".
2. Find the algorithm for the computations involved.
3. Make keygen to VALID Key for ANY name. Please note that VALID KEYS EXIST FOR ALL NAMES.
4. Write a descent tutorial. ;)

The Hint :
==========---
Think about solving a 15-puzzle. ;)

Readers, if you solve this, please upload your solution to CrackMes.de.

My Account @ Box.net

Good news for those who are not registered to Crackmes.de ! :) Now you can download my stuffs from my box !

I have added an swf boxplorer ( box explorer ;) ) below my blog header. You can anonymously download my CrackMes, KeygenMes, their Source Codes and Solutions to other crackmes by me; and I'm not gonna charge you for that, LOL.

So, do check my box for new CrackMes, KeygenMes and Sols.

How To #1 :: Flushing input stream in C++

As I was telling in my last post (CrackMe #1), the solution by DoomsDay forced me to re-check my code for errors. I had not expected negative numbers to be valid secret codes. I had implemented the following method to reject the negative numbers from Test #1 itself. See the code below :
ReEnterCode:
XXXXInKey = getchar();
XXXXwhile( InKey != '\n' )
XXXX{
XXXXXXXXif( ( InKey >= '0' ) && ( InKey <= '9' ) )
XXXXXXXX{
XXXXXXXXXXXX// Key gets accepted and stored
XXXXXXXX}
XXXXXXXXelse
XXXXXXXXXXXXgoto ReEnterCode;

XXXXXXXInKey = getchar();XXXXXXXX// Get the next key from user
XXXX}
XXXXprintf("Test #1 : PASSED");


At first sight of the code, everything seems OK. Gets a char from user, checks if it's a digit. If it is, accepts it; else prompts user for Re-Input. But, this code fails.

Lets see why. Let's analyze for input -8.
Program receives '-'. Does not accept it. Goes to the label ReEnterCode.
There, it gets the next instruction : InKey = getchar();
And what's the next char ? '8'.
So, it continues execution with '8', which gets accepted later.

The problem occurs because the input stream is not flushed before jumping to ReEnterCode. It can be solved this way :
ReEnterCode:
XXXXInKey = getchar();
XXXXwhile( InKey != '\n' )
XXXX{
XXXXXXXXif( ( InKey >= '0' ) && ( InKey <= '9' ) )
XXXXXXXX{
XXXXXXXXXXXX// Key gets accepted and stored
XXXXXXXX}

XXXXXXXXelse
xxxxxxxx{
xxxxxxxxxxxxwhile( ( (InKey = getchar()) != '\n' ) || InKey != EOF );
XXXXXXXXXXXXgoto ReEnterCode;
xxxxxxxx}

XXXXXXXInKey = getchar();XXXXXXXX// Get the next key from user
XXXX}
XXXXprintf("Test #1 : PASSED");


I uploaded Ver.2.00 of CrackMe #1 with this problem corrected.

CrackMe #1 :: C++ :: Difficulty : 1

KeyGenMe Location : CrackMe #1 @ Crackmes.de
Solution Location : Solution by DoomsDay

So, here is my first CrackMe. It's coded in ANSI C++. Features :
(*) NOT Packed
(*) NOT Encrypted
(*) Nice Konsole look with Double Sided Arrow Animation.

The Rules :
(*) NO Patching
(*) NO Brute-forcing

The Tasks :
1. Simply find the "2" secret codes that would pass ALL the tests.
2. Reverse the complete algorithm for checking the code.
3. Write a descent tutorial.

IMPORTANT :: If you happen to find a numeric secret-code that passes Test#3 but is negative, e.g. -8, that won't be accepted. The solution by DoomsDay mentioned above considers -8 as a valid secret-code. But that's NOT acceptable. After receiving solution from DoomsDay, I checked my source code again and found that negative codes get accepted due to a problem with flushing the input.

IMPORTANT :: Explain in your solution, how you found "the" secret code that would pass Test #3. Tests #1, #2 are easy enough. NO BRUTE-FORCING.

Readers, if you solve this, please upload your solution to CrackMes.de.