Log in

View Full Version : Help reversing key validation algoritm


AndyDev
October 17th, 2004, 22:40
Hiya all,

I'm trying to reverse a VS.net component dll.

I was able to retrieve where the code stores the key (at the end of the dll with a MD5 signature aside, smart, eh? )

I was able also to grab the function, which makes the validation of the key.

My problem is, that I'm having trouble reversing the algo.

If anyone could help me doing it, and of course explaining how, it will be a big help.

Small explanation about the function.

text1 stores the key.
The function calculates with the key, the expiration date of the DLL, I've found a key which expires at 1/27/2047, which I marked as a comment in the code.
The code is written in C#

Code:
public static bool CheckLicense()
{
string text1 = KeyCheck.GetKey();
// text1="PRAP-6AA2A-E4T4R"; // This key will work for until 1/27/2047
int[] numArray1 = new int[0x10];
string text2 = "RVWX2AD3J4BC5KL6P7EF8MN9QUSGHTYZ-";
for (int num1 = 0; num1 < 0x10; num1++)
{
int num2 = text2.IndexOf(text1[num1]);
if (num2 < 0)
{
throw new KeyCheckException(KeyCheckExceptionStatus.InvalidKey);
}
if (((num2 == 0x20) && (num1 != 4)) && (num1 != 10))
{
throw new KeyCheckException(KeyCheckExceptionStatus.InvalidKey);
}
numArray1[num1] = num2;
}
int num3 = ((numArray1[0] << 10) + ((0x1f - numArray1[14]) << 5)) + (0x1f - numArray1[8]);
int num4 = ((numArray1[1] << 10) + (numArray1[5] << 5)) + numArray1[11];
int num5 = (((0x1f - numArray1[3]) << 10) + (numArray1[13] << 5)) + numArray1[12];
int num6 = ((numArray1[7] << 10) + ((0x1f - numArray1[9]) << 5)) + numArray1[2];
if (numArray1[6] != ((num3 >> 7) & 0x1f))
{
throw new KeyCheckException(KeyCheckExceptionStatus.InvalidKey);
}
if (numArray1[15] != ((num4 >> 9) & 0x1f))
{
throw new KeyCheckException(KeyCheckExceptionStatus.InvalidKey);
}
int num7 = ((num4 & 0x7e00) >> 9) + ((num4 & 0x1ff) << 6);
num6 ^= num3;
num5 ^= num7;
num3 ^= num4;
if (num3 != num5)
{
throw new KeyCheckException(KeyCheckExceptionStatus.InvalidKey);
}
DateTime time3 = new DateTime(2000, 1, 1);
DateTime time1 = time3.AddDays((double) num3);
return (DateTime.Now < time1);
}


Thanks all!

Silver
October 18th, 2004, 03:20
I'm confused as to what you're asking. You've pasted that code which you say is the key validation code, but you're having trouble reversing it?

Is the problem that you don't know any C/C++/C# languages, and thus you can't understand the code? It seems straightforward enough.

naides
October 18th, 2004, 09:35
I am going to perform some mind reading, as my master and guru dELTA does in these cases:

What AndyDev wants is to Reverse the algorithm ie: Given an arbitrary expiration date, like 12-31-04, generate a valid KEY, effectively reversing every step in the code. . .
Is that what you want?

dELTA
October 18th, 2004, 13:17
Nice work padawan, your next goal shall be to start capitalizing my name correctly, and after that you will be ready for the challenge of the thousand lame posters.

naides
October 18th, 2004, 15:26
Now I am ready

JMI
October 18th, 2004, 16:13
The Force is strong is this one.

Regards,

dELTA
October 18th, 2004, 16:58
Yes, he is ready to move on to the next level... Now naides, the next time someone posts something ambiguous like this, instead of simply reading their mind, suggest any random thing as their intended meaning, and then make them think this is what they actually meant by using a Jedi mind trick. Once you get the hang of it, it's actually much more convenient than the mind reading strategy, since you can then always suggest that they meant something concise, and don't have to type as much.

AndyDev
October 18th, 2004, 19:04
Sorry if I didn't explained correctly.
I know C#, so that's not the problem, my problem is, building a keygenerator, which will build valid keys for this function validation.
The keygenerator must know also how many days will the key work.
In simple words, I need to reverse this function, or what naides said
Thanks for the fast replies!

Silver
October 19th, 2004, 13:51
In a sentence:

!!!!?????????????????????????????!!!????!!!?. !!!?. !!. ?????!?. ???????!

naides
October 19th, 2004, 14:40
Remeber that class in Linear programming you were supposed to take last quarter?
Instead you spent the afternoons smoking weed in your room at the dorm?

That is where you supposedly learn to solve problems like this one, which is NOT TRIVIAL,

this is an integer constrained linear programming problem, that uses binary and agebraic operators simultaenously. Mike is one person with this kind of expertise.
Start from the end:
You need to populate a 0x10 int array with integers that are between 0x0 to 0x19. 0x20 correspond to "-" character. With this array you generate the Key out of characters contained in string2 using the array elements as position indexes.





public static bool CheckLicense()
{
string text1 = KeyCheck.GetKey();
// text1="PRAP-6AA2A-E4T4R"; // This key will work for until 1/27/2047
int[] numArray1 = new int[0x10];
string text2 = "RVWX2AD3J4BC5KL6P7EF8MN9QUSGHTYZ-";
for (int num1 = 0; num1 < 0x10; num1++)
{
int num2 = text2.IndexOf(text1[num1]);
if (num2 < 0)
{
throw new KeyCheckException(KeyCheckExceptionStatus.InvalidK ey); Checks that all the chars in the key are contained in string2
}
if (((num2 == 0x20) && (num1 != 4)) && (num1 != 10))
{
throw new KeyCheckException(KeyCheckExceptionStatus.InvalidK ey); Checks that there is a dash in positions 0x4 and 0xA (decimal 10)
}
numArray1[num1] = num2; Fills the array
}

Now you need to know five integers num3, num4 num5 num6 and num7. They will be derived from num3, and have to satisfy all the constrains of these equations. Try to turn bitwise opeartions into algebraic operations, which are simpler to deal with. Example numArray[1] << 10 is the same as numArray[1] * 2^10 or numArray[1] * 1024

int num3 = ((numArray1[0] << 10) + ((0x1f - numArray1[14]) << 5)) + (0x1f - numArray1[8]); Now if you remeber that a number from 0 to 19 can be represented with 5 bits, and see this operations in binary instead of hex, it will be more than clear. Also remember that 0x1f is 11111 in binary
int num4 = ((numArray1[1] << 10) + (numArray1[5] << 5)) + numArray1[11];
int num5 = (((0x1f - numArray1[3]) << 10) + (numArray1[13] << 5)) + numArray1[12];
int num6 = ((numArray1[7] << 10) + ((0x1f - numArray1[9]) << 5)) + numArray1[2];
if (numArray1[6] != ((num3 >> 7) & 0x1f)) Look at the bits, {
throw new KeyCheckException(KeyCheckExceptionStatus.InvalidK ey); Internal checks, equal constrains
}
if (numArray1[15] != ((num4 >> 9) & 0x1f))
{
throw new KeyCheckException(KeyCheckExceptionStatus.InvalidK ey);
}
int num7 = ((num4 & 0x7e00) >> 9) + ((num4 & 0x1ff) << 6); You need to figure out how to turn the bitwise ands (& into algebraic operators
num6 ^= num3;
num5 ^= num7;
num3 ^= num4; these xors are killers
if (num3 != num5)
{
throw new KeyCheckException(KeyCheckExceptionStatus.InvalidK ey);
}

all you need to know is num3
DateTime time3 = new DateTime(2000, 1, 1);
DateTime time1 = time3.AddDays((double) num3);
return (DateTime.Now < time1);
}

AndyDev
October 19th, 2004, 20:05
Thanks a lot! that's exactly what I was thinking.
I will try the bool->math conversion, to make it simplier.

Thanks a lot!

naides
October 20th, 2004, 09:49
Quote:
[Originally Posted by dELTA] instead of simply reading their mind, suggest any random thing as their intended meaning, and then make them think this is what they actually meant by using a Jedi mind trick.


I just did that master. . .

What is my next mission?

JMI
October 20th, 2004, 10:10
Bring back the era of "free love." I know, a much more daunting task, but there is no "try", there is only "do" or "do not". Begin now.

Regards,

dELTA
October 20th, 2004, 11:17
Hmm, "free love"... Wasn't there some clause in the Jedi oath about us not being supposed to use our powers for dirty stuff or something like that?

JMI
October 20th, 2004, 19:05
No! It simply says that eveyone should cleanse themselves first.

Regards,

dELTA
October 21st, 2004, 09:37
Aw crap, in that case I've been missing out big-time...