• Welcome to Valhalla Legends Archive.
 

Packet 0x51 and CDKey hashing

Started by KBL_BlackIce, February 05, 2003, 05:30 PM

Previous topic - Next topic

KBL_BlackIce

Hey.  I have been trying to figure out exactly how the CDKey is hashed for battle.net packet 0x51.  I can find CDKey hashing for packet 0x36, but 0x51 seems to elude me.  Can anyone help me with the hashing algorithm?  Thanks.

If you would like to see code that I am using, just say so and I will display it here

Note: I AM using the InsertDWORD and similar routines (VB6) as a base for my own routines.

tA-Kane

#1
I'm not familiar with the hashing method used in 0x51, I used BNLS  ::)

Anyways, have you tried using double-hashed data? That would be my first guess...
Macintosh programmer and enthusiast.
Battle.net Bot Programming: http://www.bash.org/?240059
I can write programs. Can you right them?

http://www.clan-mac.com
http://www.eve-online.com

soccerist

I too would like to learn more about the hashing algorithm.  

Can anyone tell me more about what these two values are in the 0x51 packet?  

Version Hash
CDKEY Value 1

Thx.

tA-Kane

#3
I'm not sure how to generate the version hash, but the CDKey Value 1 is Value1 from DecodeCDKey().
Macintosh programmer and enthusiast.
Battle.net Bot Programming: http://www.bash.org/?240059
I can write programs. Can you right them?

http://www.clan-mac.com
http://www.eve-online.com

tA-Kane

#4
QuoteGet source
I'm not really into stealing other people's source code, shy of any encryption/hashing algorithms.

For example, I won't take the (pseudo) source of

HashedData = HashData(Value1 & Value2 & String & etc)

However, I would be interested in (and already have) the HashData function.
Macintosh programmer and enthusiast.
Battle.net Bot Programming: http://www.bash.org/?240059
I can write programs. Can you right them?

http://www.clan-mac.com
http://www.eve-online.com

KBL_BlackIce

I dont like using other peoples source.  Currently, I am using some (not much) publicly available code for testing, and am rewriting many of the functions to my style of coding.  Specifically, the PacketBuffer class in VB is being rewritten totally.  For example, I turned the following unflexible one-socket code:

Public Function SendPacket(PacketID As Byte)
If Form1.wsbnet.State <> sckConnected Then: Exit Function
     Form1.wsbnet.SendData Chr(&HFF) & Chr(PacketID) & MakeWORD(Len(buffer) + 4) & buffer
      Debug.Print "Out: " & StrToHex(Chr(&HFF) & Chr(PacketID) & MakeWORD(Len(buffer) + 4) & buffer)
        Clear
End Function

Into this flexible (but possibly less efficiently written) code:

Public Function SendPacket(ByVal PacketID As Byte, sckID As Winsock, PacketType As PCKT)
  'First, because we will use this class for sending packets to
  'BNLS, Battle.net, and BotNet, the socket will be utilized to
  'send the packet. Second, we need to verify the sockets state
  'so that we dont generate errors trying to send data on a non-open
  'socket.
  If sckID.State <> sckConnected Then Exit Function
  
  'Got a connected socket. Lets determine how the packet should
  'be built, and build it up.
  Dim packet As String
  
  Select Case PacketType
    Case BNET
      packet = Chr(&HFF) & Chr(PacketID) & MakeWORD(Len(buffer) + 4) & buffer
      
    Case BNLS
      packet = MakeWORD(Len(buffer) + 3) & Chr(PacketID) & buffer

    Case BOTNET
    Case REALM
    Case Else
  End Select

  'Clear out the buffer for the next packet
  cBuff
  
  'And send the full packet now
  sckID.SendData packet
      
  #If DebugState Then
    Debug.Print "Out(" & PacketType & "): " & StrToHex(packet)
  #End If

End Function

So as you see, I am indeed trying to learn from currently available code, and am doing what I can to remove other peoples code as I realize exactly what is done with it.

As for the HashData function/Routine, I found only c0ol's Perl sbot that utilizes the HashData.pm Perl Module, however I cannot find that module anywhere.  I Also have some other source files that happens to have hashing algo's in them, but they utilize the 0x36 packet format, and I do not know if that is compatible with the new 0x51 format.  
So, I am also interested in that function.  I will not be releasing my bot until I am satisfied with it bot in terms of usability/functionality, and the percentage of ripped code.  If I can get, notwithstanding hashing/encryption algo's, less than 2% ripped/borrowed code, I will be satisfied.

Oh, one final note.  The bot I am coding is twofold.  I do  not know C++ or C# well enough yet to be confident coding a bot with either.  I do know enough about C++ to be able to code a COM wrapper for a VB ActiveX DLL for mIRC.  That is what the bot is aimed at, a mIRC <==> Battle.Net bot. I am doing it that way because mIRC, even in the most recent release, does not release COM objects correctly. Because of that, (or maybe I am not doing something correctly myself?), I am coding a C++ wrapper that will instantiate the COM object, export the COMs routines (statically, not dynamically) and release the com object correctly when finished.

KBL_BlackIce

Ohm one other thing.  I use BNLS for everything that I can, that does NOT utilize the CDKeys.  I do not want people telling me that they wont use my bot because they dont trust a third party... whether I trust them or not.

So I used BNLS to get the Version Hash, and have been using that in my packet creation for 0x51.  I do not know if it will work yet, but I would assume that it will, because it doesnt look like it changes between 0x36 and 0x51 from what I can tell.

Zakath

#7
The version hash did not change. Nor did the method by which the CD-Key was hashed, unless I'm completely misled (my bot is currently 0x50/0x51 only).

The key is doubly hashed and then sent in the manner outlined by the BNLS protocol spec. An existing Psuedo-SHA1 hashing algorithm (of which there are many floating around) should work for 0x51.
Quote from: iago on February 02, 2005, 03:07 PM
Yes, you can't have everybody...contributing to the main source repository.  That would be stupid and create chaos.

Opensource projects...would be dumb.

KBL_BlackIce

Honestly?  Nothing better to do.  I was in the IT field doing Web Development/System Administration until May 31 of 2001, when I was laid off. Contractors were let go, of which I was one, and because of the market slowdown, I have been out of IT since.  It is unfortunate, but thems the breaks.  

So, to try and keep my skills honed, I do whatever I can to keep from getting rusty.  I am learning C++ via a Visual C++ 5 book, and alot of trial and error.

I have done some minor Visual Basic 5 and 6 stuff on my own, mostly COM objects for use with web pages.  A mailer object (for simple emails without attachments), a MORDOR<==>IRC bot (buggy and I lost the source during a drive failure, recoding it now). I started a VB based RPG game in DirectX 8, but didnt get far (you can see the title screen!)

But nothing has ever been for any business.  I am available however  =)

Skywing

#9
The SID_AUTH_CHECK and SID_CDKEY2 styles of CD-key hashing are incompatible.

Zorm

#10
If I remember correctly there is a zero between value1 and value2 in 0x51 cdkey hashing, I think thats the only difference.
"Now, gentlemen, let us do something today which the world make talk of hereafter."
- Admiral Lord Collingwood

KBL_BlackIce

#11
OK, I think I have the HashData function that will allow me to get the hash format for packet 0x51.  I have the sourcecode for BGate, and it has a hashdata function.  Is this the one that I need to hash the CDKey correctly?

void _stdcall HashData(LPVOID lpSource, int nLength, LPVOID lpResult) {
   BYTE bBuffer[1024];
   int i;
   DWORD a, b, c, d, e, g, * lpdwBuffer;

   ZeroMemory(bBuffer, 1024);
   CopyMemory(bBuffer, lpSource, nLength);
   lpdwBuffer = (LPDWORD) bBuffer;

   for (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;
}

If not, is there anywhere that I can get the hashdata function for my bot?

warz

#12
Ofcourse, http://tks.slacktech.com - provided in both visual basic, and C++

KBL_BlackIce

I downloaded every bot there, in both VB and C++, and none of them from what I see have what I am looking for.   I saw alot of BNLS stuff, which I used for a short time, but no actual hashing of the data, unless it was in an already compiled DLL, which I really dont want to use unless it is absolutely necessary.

KBL_BlackIce

#14
If that is the case, then I think the one I have is correct.  i will check it out and see if it doesnt get me IPBanned after some testing / tweaking.  Thanks for the help guys.