Valhalla Legends Archive

Programming => Battle.net Bot Development => Topic started by: brew on September 16, 2007, 09:19 PM

Title: CDKey hashing
Post by: brew on September 16, 2007, 09:19 PM
Help, I am not getting a valid cdkey hash! I don't really know where it screws up at....

#define ROL(nr, shift) ((nr << shift) | (nr >> (32 - shift)))

void HashCDKey(char *OutBuf, unsigned long ClientToken, unsigned long ServerToken,
unsigned long ProductVal, unsigned long PublicVal, unsigned long PrivateVal) {
DWORD dwHashBuff[6];
DWORD dwHashResult[5];
dwHashBuff[0] = ClientToken;
dwHashBuff[1] = ServerToken;
dwHashBuff[2] = ProductVal;
dwHashBuff[3] = PublicVal;
dwHashBuff[4] = 0;
dwHashBuff[5] = PrivateVal;
HashData((void *)dwHashBuff, 24, (void *)dwHashResult);
memcpy(OutBuf, dwHashResult, 20);
}


void HashData(void* lpSource, int nLength, void* lpResult) {
   BYTE bBuffer[1024];
   DWORD a, b, c, d, e, g, * lpdwBuffer;
   ZeroMemory(bBuffer, sizeof(bBuffer));
   CopyMemory(bBuffer, lpSource, nLength);
   lpdwBuffer = (LPDWORD) bBuffer;
   for (int i = 0; i < 64; i++)
      lpdwBuffer[i+16] = ROL(1, (lpdwBuffer[i] ^ lpdwBuffer[i+8] ^
                             lpdwBuffer[i+2] ^ lpdwBuffer[i+13]) % 32);
   a = 0x67452301lu;
   b = 0xefcdab89lu;
   c = 0x98badcfelu;
   d = 0x10325476lu;
   e = 0xc3d2e1f0lu;
   for (i = 0; i < (20 * 1); i++)
   {
      g = lpdwBuffer[i] + ROL(a,5) + e + ((b & c) | (~b & d)) + 0x5a827999lu;
      e = d;
      d = c;
      c = ROL(b,30);
      b = a;
      a = g;
   }
   for (; i < (20 * 2); i++)
   {
      g = (d ^ c ^ b) + e + ROL(g,5) + lpdwBuffer[i] + 0x6ed9eba1lu;
      e = d;
      d = c;
      c = ROL(b,30);
      b = a;
      a = g;
   }
   for (; i < (20 * 3); i++)
   {
      g = lpdwBuffer[i] + ROL(g,5) + e + ((c & b) | (d & c) | (d & b)) -
          0x70e44324lu;
      e = d;
      d = c;
      c = ROL(b,30);
      b = a;
      a = g;
   }
   for (; i < (20 * 4); i++)
   {
      g = (d ^ c ^ b) + e + ROL(g,5) + lpdwBuffer[i] - 0x359d3e2alu;
      e = d;
      d = c;
      c = ROL(b,30);
      b = a;
      a = g;
   }

   lpdwBuffer = (LPDWORD) lpResult;
   lpdwBuffer[0] = 0x67452301lu + g;
   lpdwBuffer[1] = 0xefcdab89lu + b;
   lpdwBuffer[2] = 0x98badcfelu + c;
   lpdwBuffer[3] = 0x10325476lu + d;
   lpdwBuffer[4] = 0xc3d2e1f0lu + e;
   return;
}


For the cdkey I am using 1275402843823, and the client/server tokens are both 1.
I get the results 17 ae 98 52 04 ef 56 with my function, and 4A 6A 64 5F 9A 25 64 3C 62 BD E9 4C 8F 27 E6 0B 3B E0 1C 91 with bncsutil.
:/

[Kp edit: broke up long line.  When will you people learn?]
Title: Re: CDKey hashing
Post by: Yegg on September 16, 2007, 10:36 PM
I haven't done any of this stuff in quite some time, but I think you should use a slightly modified version of HashData that a friend and I worked on a while back.

void data_hash (unsigned long *result, const void *src, const int len) {
    unsigned long a = 0x67452301lu;
    unsigned long b = 0xefcdab89lu;
    unsigned long c = 0x98badcfelu;
    unsigned long d = 0x10325476lu;
    unsigned long e = 0xc3d2e1f0lu;
    unsigned long g;
    int i;

    unsigned char bBuffer [320] = {0};
    memcpy (bBuffer, src, len);
    unsigned long *lpdwBuffer = (unsigned long *) bBuffer;

    for (i = 0; i < 80; ++i) {
if (i < 64)
lpdwBuffer [i + 16] = ROL (1, (lpdwBuffer [i] ^ lpdwBuffer [i + 8] ^ lpdwBuffer [i + 2] ^ lpdwBuffer [i + 13]) % 32);
if (i < 20)
g = lpdwBuffer[i] + ROL (a, 5) + e + ((b & c) | (~b & d)) + 0x5a827999lu;
else if (i < 40)
g = (d ^ c ^ b) + e + ROL (g, 5) + lpdwBuffer[i] + 0x6ed9eba1lu;
else if (i < 60)
g = lpdwBuffer[i] + ROL (g, 5) + e + ((c & b) | (d & c) | (d & b)) - 0x70e44324lu;
else
g = (d ^ c ^ b) + e + ROL (g, 5) + lpdwBuffer[i] - 0x359d3e2alu;
e = d;
d = c;
c = ROL (b, 30);
b = a;
a = g;
    }

    result [0] = 0x67452301lu + g;
    result [1] = 0xefcdab89lu + b;
    result [2] = 0x98badcfelu + c;
    result [3] = 0x10325476lu + d;
    result [4] = 0xc3d2e1f0lu + e;
}


I'm not sure how much more "efficient" you want to call it, but since you seem to be into the "best method" for things, I figured you'd be interested in this.

Here's an example of how to use it to hash a password:

unsigned char *password_hash (const char *pass, unsigned long clientkey, unsigned long serverkey) {
    unsigned long result [7] = {clientkey, serverkey};
    unsigned char *hash = malloc (20);

    data_hash (result + 2, pass, strlen (pass));
    data_hash (result + 2, result, 28);

    memcpy (hash, result + 2, 20);
   
    return hash;
}
Title: Re: CDKey hashing
Post by: brew on September 16, 2007, 11:26 PM
Wow, thank you for that function. It works just as well (if not better) then it looks. Much more cleaner alternative to calcHashBuf and HashData (I forget where I found those...) BTW, I found my hashing problem now that I was able to rule out making a mistake with the actual hashing of the data (had another look at my public/private values).

EDIT***
IIRC you made a 11-12 line starcraft cdkey decoder function a while back, could you post that?
Title: Re: CDKey hashing
Post by: Hdx on September 17, 2007, 12:19 PM
int c;
int hashkey = 0x13AC9741;
int seq[] = {6, 0, 2, 9, 3, 11, 1, 7, 5, 4, 10, 8};
char[] key = new char[12];
for (short i = 11; i >= 0; i--) {
c = cdkey.charAt(seq[i]);
if (c <= '7') {
c ^= (byte) (hashkey & 7);
hashkey >>>= 3;
} else c ^= (byte)(i & 1);
key[i] = (char)c;
}
Should be simple to convert to c
~Hdx
Title: Re: CDKey hashing
Post by: Yegg on September 17, 2007, 03:21 PM
According to standard, I believe what Hdx posted is C++, but it's pretty much the same method I used.
Title: Re: CDKey hashing
Post by: devcode on September 17, 2007, 04:24 PM
The code you posted is C++ as well.

Quote from: Yegg on September 17, 2007, 03:21 PM
According to standard, I believe what Hdx posted is C++, but it's pretty much the same method I used.
Title: Re: CDKey hashing
Post by: Hdx on September 17, 2007, 06:16 PM
You guts should know better, almost everything i post is Java <3s
I was working with JBLS at the time and figured I'd go in an nab this part out for you.
~Hdx
Title: Re: CDKey hashing
Post by: Yegg on September 17, 2007, 08:50 PM
Quote from: devcode on September 17, 2007, 04:24 PM
The code you posted is C++ as well.

Explain how? I'm not a pro with C/++, but I'm not sure how my code is C++.
Title: Re: CDKey hashing
Post by: brew on September 17, 2007, 09:38 PM
There is no signed right shift operator in the ANSI C standard IIRC
Title: Re: CDKey hashing
Post by: Yegg on September 17, 2007, 09:46 PM
Quote from: brew on September 17, 2007, 09:38 PM
There is no signed right shift operator in the ANSI C standard IIRC

I can't find anything to back that up. If there is no right shift, then why would there be a left shift?
Title: Re: CDKey hashing
Post by: Barabajagal on September 17, 2007, 10:29 PM
Right Signed Shift != Right Shift.
Title: Re: CDKey hashing
Post by: Kp on September 17, 2007, 11:22 PM
C does not need a >>> operator, because C has proper unsigned types.  Java needs both >> and >>> because it insists on using only signed types.  C can use >> to mean signed or unsigned, depending on the type of the variable being shifted.  Just look at the assembly for shifting a signed int versus shifting an unsigned int.
Title: Re: CDKey hashing
Post by: Barabajagal on September 17, 2007, 11:45 PM
In which case, Blake's code is not C. Hint: It's Java.
Title: Re: CDKey hashing
Post by: devcode on September 17, 2007, 11:57 PM
Well for one, you have

unsigned long *lpdwBuffer = (unsigned long *) bBuffer;

this wont compile in C since you have to declare all variables before you do any real work. In other news, warden decryption iz a beotch.

Quote from: Yegg on September 17, 2007, 08:50 PM
Quote from: devcode on September 17, 2007, 04:24 PM
The code you posted is C++ as well.

Explain how? I'm not a pro with C/++, but I'm not sure how my code is C++.
Title: Re: CDKey hashing
Post by: Camel on September 18, 2007, 02:51 AM
Quote from: devcode on September 17, 2007, 11:57 PMunsigned long *lpdwBuffer = (unsigned long *) bBuffer;

this wont compile in C since you have to declare all variables before you do any real work. In other news, warden decryption iz a beotch.

Strictly speaking, that isn't ANSI C. I'm not aware of any C compilers that are still maintained and still enforce that silly rule without specific instructions to do so ('strict mode').
Title: Re: CDKey hashing
Post by: Yegg on September 18, 2007, 08:42 AM
Quote from: devcode on September 17, 2007, 11:57 PM
Well for one, you have

unsigned long *lpdwBuffer = (unsigned long *) bBuffer;

this wont compile in C since you have to declare all variables before you do any real work. In other news, warden decryption iz a beotch.

You're implying that there is more than one reason why my code is C++. What are the others ones?
Title: Re: CDKey hashing
Post by: devcode on September 18, 2007, 08:45 AM
Didn't mean to add the "Well, for one". One of the most common windows compilers, MSVC6 does enforce that rule and it's a good rule to follow.
Title: Re: CDKey hashing
Post by: rabbit on September 18, 2007, 08:50 AM
IIRC, GCC says something about it as well.  I'm not sure if it's an error or a warning, but it still doesn't like unpredeclared variables.
Title: Re: CDKey hashing
Post by: Yegg on September 18, 2007, 09:12 AM
Quote from: rabbit on September 18, 2007, 08:50 AM
IIRC, GCC says something about it as well.  I'm not sure if it's an error or a warning, but it still doesn't like unpredeclared variables.

I assume it depends on the mode GCC is set to. Whatever the default mode is, it does not give any kind of warning for that kind of code.
Title: Re: CDKey hashing
Post by: K on September 18, 2007, 01:10 PM
Quote from: devcode on September 17, 2007, 11:57 PM
Well for one, you have

unsigned long *lpdwBuffer = (unsigned long *) bBuffer;

this wont compile in C since you have to declare all variables before you do any real work.

If you're going to be picky, you might as well be right.

This is only an issue if you're using a compiler that adheres to the C89 standard; the C99 standard allows you to define variables wherever you want.

You can test this with gcc:

#include <stdio.h>

int main(void)
{
   int i = 3;
   printf("i = %d\n", i);
   int j = 4;
   printf("j = %d\n", j);
   return 0;
}



$ gcc -Wall foo.c -o foo --std=c99 --pedantic && ./foo
i = 3
j = 4
$ gcc -Wall foo.c -o foo --std=c89 --pedantic && ./foo
foo.c: In function 'main':
foo.c:7: warning: ISO C90 forbids mixed declarations and code
i = 3
j = 4
Title: Re: CDKey hashing
Post by: devcode on September 18, 2007, 03:21 PM
I don't use free compilers like gcc. I mentioned it because VC6/IntelC++ compilers do give errors and these are the compilers I use.

Quote from: K on September 18, 2007, 01:10 PM
Quote from: devcode on September 17, 2007, 11:57 PM
Well for one, you have

unsigned long *lpdwBuffer = (unsigned long *) bBuffer;

this wont compile in C since you have to declare all variables before you do any real work.

If you're going to be picky, you might as well be right.

This is only an issue if you're using a compiler that adheres to the C89 standard; the C99 standard allows you to define variables wherever you want.

You can test this with gcc:

#include <stdio.h>

int main(void)
{
   int i = 3;
   printf("i = %d\n", i);
   int j = 4;
   printf("j = %d\n", j);
   return 0;
}



$ gcc -Wall foo.c -o foo --std=c99 --pedantic && ./foo
i = 3
j = 4
$ gcc -Wall foo.c -o foo --std=c89 --pedantic && ./foo
foo.c: In function 'main':
foo.c:7: warning: ISO C90 forbids mixed declarations and code
i = 3
j = 4

Title: Re: CDKey hashing
Post by: Yegg on September 18, 2007, 08:31 PM
Isn't C99 still C though?
Title: Re: CDKey hashing
Post by: Don Cullen on September 18, 2007, 09:37 PM
Quote from: devcode on September 17, 2007, 11:57 PMIn other news, warden decryption iz a beotch.

Devcode-

You know, if you were to post your progress so far, what you've figured out, etc, etc, etc, perhaps others who are also working on the 0x5E problem-- thanks to your notes and data-- will be able to manage to figure out how to reverse it, or at the very least will be able to contribute fresh outlooks on solutions for it.
Title: Re: CDKey hashing
Post by: devcode on September 18, 2007, 11:06 PM
I don't quite know if I should post it, I mean I'd be breeding all these Starcraft b0t warrers ;)

Quote from: Don Cullen on September 18, 2007, 09:37 PM
Quote from: devcode on September 17, 2007, 11:57 PMIn other news, warden decryption iz a beotch.

Devcode-

You know, if you were to post your progress so far, what you've figured out, etc, etc, etc, perhaps others who are also working on the 0x5E problem-- thanks to your notes and data-- will be able to manage to figure out how to reverse it, or at the very least will be able to contribute fresh outlooks on solutions for it.
Title: Re: CDKey hashing
Post by: Barabajagal on September 18, 2007, 11:13 PM
Actually... I don't think warden stopped them, since they can log in and out really quick anyway.
Title: Re: CDKey hashing
Post by: devcode on September 18, 2007, 11:19 PM
Yes, but they'd rather have bots that stay l0gged in :)

Quote from: Andy on September 18, 2007, 11:13 PM
Actually... I don't think warden stopped them, since they can log in and out really quick anyway.
Title: Re: CDKey hashing
Post by: Don Cullen on September 18, 2007, 11:24 PM
Quote from: devcode on September 18, 2007, 11:19 PM
Yes, but they'd rather have bots that stay l0gged in :)

Quote from: Andy on September 18, 2007, 11:13 PM
Actually... I don't think warden stopped them, since they can log in and out really quick anyway.

Actually, no they don't for obvious reasons (ease of ipban via squelch, or via Blizzard staff). And secondly, all they have to do is emulate the other game clients and they can stay on. "Warring" refers to flooding and loading, and those can be easily done with other game clients, and also mainly relies on rapid cycling of reconnects to avoid ipbans from squelching.

If you're referring to hacking (use of software to cheat in games), the current hacks don't even care about 0x5E, they completely bypass it. They allow StarCraft to deal with the packet on its own.

In conclusion, your concerns are essentially moot.

Quote from: Don Cullen on September 10, 2007, 09:47 PM
I'm happy to see you have that high of an opinion of yourself. Do you plan on sharing what you've found with the community, or do you plan on withholding it?

Your response:

Quote from: devcode on September 10, 2007, 09:55 PM
I promote open sourcing of details and snippets of code.

I rest my case.
Title: Re: CDKey hashing
Post by: devcode on September 19, 2007, 12:12 AM
So since there are other clients to choose from to login a bot, why worry about a SC/BW bot? :)
Title: Re: CDKey hashing
Post by: Barabajagal on September 19, 2007, 12:16 AM
I don't. I use war2.
Title: Re: CDKey hashing
Post by: Don Cullen on September 19, 2007, 12:36 AM
Quote from: devcode on September 19, 2007, 12:12 AM
So since there are other clients to choose from to login a bot, why worry about a SC/BW bot? :)

Simply because people prefer bots to have full functionality and to allow them full choice of which game client to emulate.

I also am the administrator of BNETDocs Redux, and am interested in this purely for documentation purposes.

Either stand by your word and contribute, or don't. That's entirely your choice. I'm finished trying to encourage you to contribute.

If you prefer to keep your research to yourself, and would prefer to contribute absolutely nothing to the community, even if it means completely destroying any creditability you had in the first place in regards to your claims, that's your choice. Good luck with the venue.
Title: Re: CDKey hashing
Post by: Dale on September 19, 2007, 08:11 AM
Quote from: Don Cullen on September 19, 2007, 12:36 AM
Quote from: devcode on September 19, 2007, 12:12 AM
So since there are other clients to choose from to login a bot, why worry about a SC/BW bot? :)

Simply because people prefer bots to have full functionality and to allow them full choice of which game client to emulate.

I also am the administrator of BNETDocs Redux, and am interested in this purely for documentation purposes.

Either stand by your word and contribute, or don't. That's entirely your choice. I'm finished trying to encourage you to contribute.

If you prefer to keep your research to yourself, and would prefer to contribute absolutely nothing to the community, even if it means completely destroying any creditability you had in the first place in regards to your claims, that's your choice. Good luck with the venue.

burnnnn
Title: Re: CDKey hashing
Post by: devcode on September 19, 2007, 08:42 AM
The documentation is coming soon, I just have to compile it all together and make readable for the end user.

Quote from: Don Cullen on September 19, 2007, 12:36 AM
Quote from: devcode on September 19, 2007, 12:12 AM
So since there are other clients to choose from to login a bot, why worry about a SC/BW bot? :)

Simply because people prefer bots to have full functionality and to allow them full choice of which game client to emulate.

I also am the administrator of BNETDocs Redux, and am interested in this purely for documentation purposes.

Either stand by your word and contribute, or don't. That's entirely your choice. I'm finished trying to encourage you to contribute.

If you prefer to keep your research to yourself, and would prefer to contribute absolutely nothing to the community, even if it means completely destroying any creditability you had in the first place in regards to your claims, that's your choice. Good luck with the venue.