Valhalla Legends Forums Archive | Battle.net Bot Development | Key Validator

AuthorMessageTime
BlazingKnight
Can the DecodeSCKey and DecodeD2Key functions be used as a key validator?
October 9, 2003, 5:21 PM
Skywing
[quote author=BlazingKnight link=board=17;threadid=3013;start=0#msg23554 date=1065720078]
Can the DecodeSCKey and DecodeD2Key functions be used as a key validator?
[/quote]
If you mean the YobGuls versions, they provide the same kind of protection as the game installers - protection against making a typo in the key. Just because a key passes the installer check, though, does not mean that it will be accepted by the Battle.net server.
October 9, 2003, 5:38 PM
BlazingKnight
I'll take that as a yes. Ok, the next thing. I have a program running keys through the key decoder. There's an input list (original list), and an output list (processed through decoder). In the output list, the keys all come out different. How do I tell if it is valid or not. (True/False value).
October 9, 2003, 5:43 PM
Arta
You don't need to call decodecdkey. That'll do a whole bunch of stuff you don't need. Decoding a CD key has 3 main sections, the first is the one you're interested in - the checksum. It works by computing a value based on the characters in the key. If that character matches the last key character, the key is considered valid for an install. Otherwise, it's not. Here's my code for computing the checksum. This is reversed from battle.snp, so it won't work for Diablo II. I don't think I ever reversed that but Yobguls version should work fine if you can figure out which part it is :)

[code]
// Checksum
   DWORD Checksum = 3;
   for(int i = 0; i < 12; i++){
      Checksum += (Key[i] - 0x30) ^ (Checksum * 2);
   }

   Checksum %= 10;

   if(Key[12] != Checksum + 0x30){
      return false;
   }
[/code]

The rest of the decoding gets the key's values to send to Battle.net, but since we don't know how to validate those, there's not much point in decoding them if you're only writing a validator.
October 9, 2003, 8:57 PM
BlazingKnight
Can you give that to me in VB please. Sorry for not mentioning the language.
October 9, 2003, 9:07 PM
iago
[quote author=BlazingKnight link=board=17;threadid=3013;start=0#msg23576 date=1065733625]
Can you give that to me in VB please. Sorry for not mentioning the language.

[/quote]

[code]// Checksum
DWORD Checksum = 3;
for(int i = 0; i < 12; i++){
Checksum += (Key[i] - 0x30) ^ (Checksum * 2);
}

Checksum %= 10;

if(Key[12] != Checksum + 0x30){
return false;
}[/code]

It shoudl be something similar to this:
[code]dim Checksum as integer
Checksum = 3
for i = 0 to 11
Checksum = val(mid(key, i, 1)) xor (Checksum * 2)
next i

Checksum = Checksum mod 10

if Checksum != mid(key, 13, 1) then
fail;
else
pass;
end if[/code]

But keep in mind there's a 1/10 chance it'll pass this for a random key...
October 9, 2003, 10:04 PM
BlazingKnight
Thanks for converting iago. Heres what I have for my code as of now.

Do
Dim i As Integer
Dim i2 As Integer
Dim Checksum As Integer
Checksum = 0
Dim Key As String
Key = lstKeys.List(i2)
For i = 0 To 11
Checksum = Val(Mid(Key, i, 1)) Xor (Checksum * 2)
Next i
Checksum = Checksum Mod 10
If Checksum <> Mid(Key, 13, 1) Then
lstInvalid.AddItem Key
Else
lstValid.AddItem Key
End If
i2 = i2 + 1
Loop Until i2 = lstKeys.ListCount

I messed w/ it, but I get an "Invalid procedure call or argument" error on the line.
Checksum = Val(Mid(Key, i, 1)) Xor (Checksum * 2)

I couldn't fix it mainly becuase I don't know what XOr and Mod mean. Please fill in the blanks for me. (Thanks)
October 9, 2003, 11:48 PM
Zakath
xor is "exclusive or."

I.e. "a xor b," also expressed as "a ^ b"

a | b | a ^ b
----------------
0 | 0 | 0
0 | 1 | 1
1 | 0 | 1
1 | 1 | 0

That illustrates the usage of xor. You really SHOULD know what it is, it's rather integral to programming.
October 10, 2003, 12:01 AM
BlazingKnight
That didn't really make any sense to me. What about Mod?
October 10, 2003, 12:34 AM
iago
mod is Modulus Division, which is like the division but it returns the remainder instead of the product.

And I probably did the "mid" backwards, I haven't used it for years.
October 10, 2003, 1:06 AM
BlazingKnight
Mid(String, Start, Stop) / Mid(strInput, 1, 4
October 10, 2003, 1:08 AM
BlazingKnight
I talked w/ Zakath in the channel. He broke it down for me some. For those who are still curious, I'll stupify it a little more for the people on my level. >.<

If you have an If/Then statement and your comparing two variables, only 1 of the variables can be true to have a true output. So...

If a = True XOr b = True then
False Output
ElseIf a = Flse XOr b = False Then
False Output
ElseIf a = True XOr b = False Then
True Output
End If

Where as a regular If/Then statement would allow you to have two true variables to have a true output. Thanks Zakath.
October 10, 2003, 4:54 AM
Arta
[code]
If you have an If/Then statement and your comparing two variables, only 1 of the variables can be true to have a true output. So...
[/code]

That's an OR statement. In other words, if either condition is true, the 'output' is true. If you want to change that so that both have to be true, simply use an AND statment. I've never used XOR in a conditional check and I'm not sure what the point in that would be. Is it even possible in most languages? It's more commonly used to manipulate the bits in a byte, ie:

11 XOR 5 = 14

because:

1011 (11)
0101 (5)
1110 (XOR'd - 14)

You can think of 1 as true and 0 as false if that helps.
October 10, 2003, 1:23 PM
Soul Taker
[quote author=iago link=board=17;threadid=3013;start=0#msg23585 date=1065737052]
[quote author=BlazingKnight link=board=17;threadid=3013;start=0#msg23576 date=1065733625]
Can you give that to me in VB please. Sorry for not mentioning the language.

[/quote]

[code]// Checksum
DWORD Checksum = 3;
for(int i = 0; i < 12; i++){
Checksum += (Key[i] - 0x30) ^ (Checksum * 2);
}

Checksum %= 10;

if(Key[12] != Checksum + 0x30){
return false;
}[/code]

It shoudl be something similar to this:
[code]dim Checksum as integer
Checksum = 3
for i = 0 to 11
Checksum = val(mid(key, i, 1)) xor (Checksum * 2)
next i

Checksum = Checksum mod 10

if Checksum != mid(key, 13, 1) then
fail;
else
pass;
end if[/code]

But keep in mind there's a 1/10 chance it'll pass this for a random key...
[/quote]
Shouldn't != be <> in VB
October 10, 2003, 2:38 PM
Arta
Yes.
October 10, 2003, 8:42 PM
iago
Note this line:
[quote]It should be something similar to this:[/quote]


I haven't done any visual basic in a long, long time.. I was close :)
October 10, 2003, 9:25 PM
CupHead
Got bored, wrote this inefficient thing to generate all "valid" keys.

[code]
#include <iostream.h>
#include <fstream.h>
#include <string.h>
#include <stdlib.h>

#define DWORD unsigned long

__inline bool Checksum(char * Key);

int main()
{
   char Key[14];
   char TempBuf[6]; char TempBuf2[5]; char TempBuf3[6]; char TempBuf4[5];
   int TempInt;
   ofstream OutFile;
   OutFile.open("keys.txt");

   long i; long j; long k;
   for ( i = 0; i < 5000; i++ )
   {
      for ( j = 0; j < 100000; j++ )
      {
         for ( k = 0; k < 10000; k++ )
         {
            strcpy(TempBuf4, "0000");
            strcpy(TempBuf3, "00000");

            _ltoa(k, TempBuf2, 10);
            TempInt = strlen(TempBuf2);
            strcpy(&TempBuf4[4 - TempInt], TempBuf2);
            strcpy(&Key[9], TempBuf4);

            strcpy(TempBuf4, "0000");

            _ltoa(i, TempBuf2, 10);
            TempInt = strlen(TempBuf2);
            strcpy(&TempBuf4[4 - TempInt], TempBuf2);
            strcpy(&Key[0], TempBuf4);

            _ltoa(j, TempBuf, 10);
            TempInt = strlen(TempBuf);
            strcpy(&TempBuf3[5 - TempInt], TempBuf);
            strcpy(&Key[4], TempBuf3);

            if ( Checksum( Key ) )
               OutFile << Key << endl;
         }
      }
   }

   OutFile.close();
   return 0;
}

__inline bool Checksum(char * Key)
{
   DWORD dChecksum = 3;
   for(int i = 0; i < 12; i++){
      dChecksum += (Key[i] - 0x30) ^ (dChecksum * 2);
   }

   dChecksum %= 10;

   if(Key[12] != dChecksum + 0x30){
      return false;
   }
   return true;
}
[/code]
October 10, 2003, 10:48 PM
BlazingKnight
Yes. It was another one of vL's pointless test's to see if the reader was versatile enough in programming to understand it. Could you please put that validator in VB please.
October 11, 2003, 1:15 AM
Hitmen
You might notice most of them don't particularly like VB, so most code you will get will be in C++ unless anyone feels like "translating" it.
October 11, 2003, 1:21 AM
Adron
Weeding out the morons is a good thing.
October 11, 2003, 1:26 AM
CupHead
There, fully and correctly functioning VB validation code.

[code]
Public Function Checksum(ByVal CDKey As String) As Boolean
Dim TheChecksum As Long, i As Byte
TheChecksum = 3

For i = 1 To 12
TheChecksum = TheChecksum + ((Asc(Mid(CDKey, i, 1)) - &H30) Xor (TheChecksum * 2))
Next i

TheChecksum = TheChecksum Mod 10

If Asc(Mid(CDKey, 13, 1)) <> (TheChecksum + &H30) Then
Checksum = False
Exit Function
End If

Checksum = True
End Function
[/code]
October 11, 2003, 2:00 AM
BlazingKnight
Thanks CupHead. I owe ya :)
October 12, 2003, 8:45 PM
Grok
[quote author=BlazingKnight link=board=17;threadid=3013;start=15#msg23948 date=1065991542]
Thanks CupHead. I owe ya :)
[/quote]

The question becomes ... will you ever pay him?
October 13, 2003, 12:54 PM
BlazingKnight
Aim: MrTunaBreeze
Talk to me about payment.
October 13, 2003, 6:14 PM
iago
If Asc(Mid(CDKey, 13, 1)) <> (TheChecksum + &H30) Then
-- compared to --
if(CDKey[12] - 0x30 == TheChecksum)

Who says VB is nicer? :-P

October 13, 2003, 6:46 PM

Search