• Welcome to Valhalla Legends Archive.
 

Need help. Logging BNet... [NOT solved]

Started by z-stars, July 22, 2004, 01:47 PM

Previous topic - Next topic
|

z-stars

#60
Quote from: $t0rm on July 25, 2004, 09:22 AM
not on xp it isn't.

Well my softice works in xp pretty well, but its true that I don't really use it for Debugging...

z-stars

Going back to the topic, nobody knows how to make my bot log to battle.net?

dxoigmn

#62
Quote from: z-stars on July 24, 2004, 02:55 PM
Quote from: UserLoser. on July 24, 2004, 02:49 PM
You're sending two extra bytes which shouldn't be there at the very end of your 0x51 packet which is causing the IPban.  As far as the invalid version (0x101) response, do you have the newest hash files?  Are you sure you're using the expansion files and not classic?

Mhh didn't know it was invalid version response, my switch goes to the default for some reason, but about the hash files no I'm not sure, which files are the hash files?

Quote
  cout << endl;
  switch(r_SID_AUTH_CHECK.Result)
  {
  case 0x000: cout << "Passed Challenge" << endl; break;
  case 0x100: cout << "Old Game Version" << endl; break;
  case 0x001: cout << "Invalid Version" << endl; break;

  case 0x200: cout << "Invalid CDKey" << endl; break;
  case 0x201: cout << "CDKey in use" << endl; break;
  case 0x202: cout << "Banned CDKey" << endl; break;
  case 0x203: cout << "Wrong Product" << endl; break;
  default: cout << "Undefined" << endl;
  }

I don't know if this was fixed and it shouldn't really matter but you need to fix the bold part to 0x101.

dxoigmn

Quote from: z-stars on July 24, 2004, 03:12 PM
BTW, the CheckRevision call...

bCheckRevision =
     CheckRevision("C:\\Archivos de programa\\Diablo II\\Game.exe",
        "C:\\Archivos de programa\\Diablo II\\D2Client.dll",
        "C:\\Archivos de programa\\Diablo II\\BnClient.dll",
        r_SID_AUTH_INFO.ValueString,
        &dwVersion, &dwChecksum,
        CRExeInfo,
        r_SID_AUTH_INFO.IX86ver_filename);
  if(bCheckRevision == FALSE)
     cout << "ERROR: CheckRevision() Failed" << endl;
  else cout << "CheckRevision() Success" << endl;

It returns TRUE.
I posted the CheckRevision() function at the first page of the topic.

Try swapping BnClient.dll and D2Client.dll.

z-stars

Thx dxoigmn, I changed the 0x001 and the switch works now, but I swapped d2client and bnetclient and it stills sends me the invalid version packet :(

dxoigmn

#65
Quote from: z-stars on July 25, 2004, 06:53 PM
Thx dxoigmn, I changed the 0x001 and the switch works now, but I swapped d2client and bnetclient and it stills sends me the invalid version packet :(

Post your code where it creates SID_AUTH_CHECK (0x51) again.

z-stars

#66
Function offsets:

const DWORD HashFunction = 0x19012400;
const DWORD DecodeCDKeyFunction = 0x19019AB0;


The function that builds the packet:

// S SID_AUTH_CHECK
// This function is supossed to build and send the fifth packet (0x51)
// At the start of this function, csFifthPacket.packet (the packet 0x51 that
// this function sends to battle.net at the end) is EMPTY.
int LTBNFifthPacket()
{
   /* Globals... */
   BEFORE_SEND;
   int n = 0;
   char * CDKeyOwner = "Me";
   /* End of Globals */

   /* First, load Battle.snp to do the hasing for us */
   HMODULE battlesnp;
   battlesnp = LoadLibrary("Battle.snp");
   if(!battlesnp) cout << "Couldn't load battle.snp" << endl;
   /* Battlesnp Loaded */


   /* CHECK REVISION */
   /* Call CheckRevision() to get the some of the values to send */
   /* The values we get are: ExeHash and Version (dwExeHash, and dwVersion) */
   /* Also, we get an ExeInfo string. (To CRExeInfo). */
   DWORD dwVersion = 0;
   DWORD dwChecksum = 0;
   char CRExeInfo[5000];
   memset(CRExeInfo, 0, 5000);
   //strcpy(CRExeInfo, ExeInfo);
   BOOL bCheckRevision = 0;
   bCheckRevision =
      CheckRevision("C:\\Archivos de programa\\Diablo II\\Game.exe",
         "C:\\Archivos de programa\\Diablo II\\BnClient.dll",
         "C:\\Archivos de programa\\Diablo II\\D2Client.dll",
         r_SID_AUTH_INFO.ValueString,
         &dwVersion, &dwChecksum,
         CRExeInfo,
         r_SID_AUTH_INFO.IX86ver_filename);
   if(bCheckRevision == FALSE)
      cout << "ERROR: Check Revision() Failed" << endl;
   else cout << "CheckRevision() Success" << endl;
   /*printf("dwVersion: %x  || dwChecksum: %x || ExeInfo: %s",
      dwVersion, dwChecksum, CRExeInfo);*/
   /* END OF CHECK REVISION */
         

   /* VARIABLES TO PUT IN THE PACKET DECLARATIONS */
   int x = 0;
   BYTE FirstByte = 0xFF; // It's always 0xFF
   BYTE PacketID = 0x51; // PacketId's 0x51
   WORD PacketLen = 136; // Packet Length is 136
   DWORD ClientToken = GetTickCount(); // I use GetTickCount() to get that
   DWORD ExeVersion = dwVersion; // From CheckRevision()
   DWORD ExeHash = dwChecksum; // From CheckRevision()
   DWORD CDKeyNumber = 2; // 1 D2 cd key, 1 Lod cd key.
   DWORD UsingOfKeys = 0; // 0

   DWORD Key1Len = 0x10; // Length of D2 CdKey: 16 (0x10)
   DWORD Key1Product = 0x06000000; // Key1 Product: 0x06000000
   DWORD Key1Num1 = x; // This is supossed to be the First Number of the first cd key.
                  // I'm not sure how to get it.
   DWORD Key1Unknown = 0; // Unknown(0)

   DWORD Key2Len = 0x10; // Same...
   DWORD Key2Product = 0x0A000000; // Key2 (LOD) Product: 0x0A000000
   DWORD Key2Num1 = x;      // Same...
   DWORD Key2Unknown = 0; // Unknown (0)
   /* END OF VARIABLES TO PUT IN THE PACKET DECLARATIONS */

   /* CALL RUNCDKEYDECODE */
   DWORD dwProduct = Key1Product;
   DWORD dwPrivate = 0;
   DWORD dwPublic = 0;
   RunCDkeyDecode(&dwProduct, &dwPublic, &dwPrivate, szD2CdKey);
   ////
   //cout << endl << "RUNCDKEYDECODE" << endl;
   //cout << "dwProduct: " << hex << dwProduct << endl;
   //cout << "dwPublic: " << hex << dwPublic << endl;
   //cout << "dwPrivate: " << hex << dwPrivate << endl;
   //cout << endl << endl;
   /* END OF CALL RUNCDKEYDECODE */

   /* CALL HASHDATA FOR CDKEY1*/
   DWORD dwHashBuffer[6];
   DWORD dwOutBuffer[5]; // This is supossed to be the CDKey1 Data.
   dwHashBuffer[0] = ClientToken; // We got this with GetTickCount()
   dwHashBuffer[1] = r_SID_AUTH_INFO.Server_Token; // Bnet sent this in the last packet
   dwHashBuffer[2] = dwProduct; // We got this with RunCDKeyDecode
   dwHashBuffer[3] = dwPublic; // We got this with RunCDKeyDecode too
   dwHashBuffer[4] = 0; // 0...
   dwHashBuffer[5] = dwPrivate; // Also, we got this with RunCDKeyDecode
   HashData(24, dwOutBuffer, dwHashBuffer);
   /* END OF CALL HASHDATA */

   /* DO THE SAME FOR CDKEY2 */
   DWORD dwProduct2 = Key2Product;
   DWORD dwPrivate2 = 0;
   DWORD dwPublic2 = 0;
   RunCDkeyDecode(&dwProduct, &dwPublic, &dwPrivate, szLODCdKey);

   DWORD dwHashBuffer2[6];
   DWORD dwOutBuffer2[5];
   dwHashBuffer[0] = GetTickCount();
   dwHashBuffer[1] = r_SID_AUTH_INFO.Server_Token;
   dwHashBuffer[2] = dwProduct2;
   dwHashBuffer[3] = dwPublic2;
   dwHashBuffer[4] = 0;
   dwHashBuffer[5] = dwPrivate2;
   HashData(24, dwOutBuffer2, dwHashBuffer2);
   /* ~~ */


   /* WRITE EVERYTHING IN THE PACKET */

   // Info about csFifthPacket class:
   // The packet itself is csFifthPacket.packet and it is a
   // dynamically allocated BYTE array.
   // The position the next function will write to is stored at
   // nByte2Write and is increased automatically with each WriteX function
   // call.
   // WriteByte writes a byte to packet. (csFifthPacket.packet).
   // WriteWord and WriteDWord take 2 arguments. The first one tells
   // if it has to convert the Word or DWord given to Little Endian before
   // putting it in packet or not. If the first argument is 0, it will
   // convert the DWORD given to Little Endian, and then put it in the
   // packet. If it is 1, it will put it in the packet directly without
   // converting it.
   // WriteString() just writes a string and a null terminator to packet.

   csFifthPacket.WriteByte(0xFF);
   csFifthPacket.WriteByte(0x51);
   // Gotta solve this bug some day...
   csFifthPacket.WriteWord(0, 134);
   
   csFifthPacket.WriteDWord(0, ClientToken);
   csFifthPacket.WriteDWord(0, ExeVersion); // From CheckRevision()
   csFifthPacket.WriteDWord(0, ExeHash);  // From CheckRevision()
   csFifthPacket.WriteDWord(0, CDKeyNumber);
   csFifthPacket.WriteDWord(0, UsingOfKeys);

   csFifthPacket.WriteDWord(0, Key1Len);
   csFifthPacket.WriteDWord(1, Key1Product);
   csFifthPacket.WriteDWord(1, dwPublic);
   csFifthPacket.WriteDWord(0, Key1Unknown);
   csFifthPacket.WriteDWord(1,dwOutBuffer[0]);
   csFifthPacket.WriteDWord(1,dwOutBuffer[1]);
   csFifthPacket.WriteDWord(1,dwOutBuffer[2]);
   csFifthPacket.WriteDWord(1,dwOutBuffer[3]);
   csFifthPacket.WriteDWord(1,dwOutBuffer[4]);

   csFifthPacket.WriteDWord(0, Key2Len);
   csFifthPacket.WriteDWord(1, Key2Product);
   csFifthPacket.WriteDWord(1, dwPrivate);
   csFifthPacket.WriteDWord(0, Key2Unknown);
   csFifthPacket.WriteDWord(1,dwOutBuffer2[0]);
   csFifthPacket.WriteDWord(1,dwOutBuffer2[1]);
   csFifthPacket.WriteDWord(1,dwOutBuffer2[2]);
   csFifthPacket.WriteDWord(1,dwOutBuffer2[3]);
   csFifthPacket.WriteDWord(1,dwOutBuffer2[4]);

   csFifthPacket.WriteString(CRExeInfo); // From CheckRevision()
   csFifthPacket.WriteString(CDKeyOwner);

   // These two sentences set the packet size word of packet to the packet
   // len. (Previously it was 136 instead 134).
   
   /* END OF WRITE EVERYTHING AT THE PACKET */

   
   /* SEND csFifthPacket.packet TO BATTLE.NET */
   n = SendPacket(csFifthPacket.packet, csFifthPacket.GetPacketLen());
   if(n == -1) error(10, "SendPacket");
   else cout << "Packet 0x51 Sent " << "Bytes: " << n << endl;
   /* END OF SEND PACKET TO BATTLE.NET */

   return n;
}


Another functions used:


void HashData(DWORD length, LPVOID outbuf, LPVOID tohash)
{
  DWORD len = length;
  __asm {
     push ecx
     push edx
     mov ecx, outbuf
     mov edx, tohash
     push len
     call HashFunction
     pop edx
     pop ecx
  }
}


void RunCDkeyDecode(DWORD *Product, DWORD *CDKeyVal1, DWORD *CDKeyVal2, const char *CDKey)
{

  __asm
  {
     push ecx
     push edx
     mov ecx, CDKey
     mov edx, Product
     push CDKeyVal2
     push CDKeyVal1
     call DecodeCDKeyFunction
     pop edx
     pop ecx
  }
}


dxoigmn

Hmm, everything looks right.  Seems like the only problem could be with your files.  Make sure you're not using modified files (Game.exe, BnClient.dll, D2Client.dll).  And dwVersion should be 0x1000A00 but in your packet logs it's not.  Check those things.

z-stars

#68
Quote from: dxoigmn on July 25, 2004, 07:42 PM
Hmm, everything looks right.  Seems like the only problem could be with your files.  Make sure you're not using modified files (Game.exe, BnClient.dll, D2Client.dll).  And dwVersion should be 0x1000A00 but in your packet logs it's not.  Check those things.


I think they aren't modified, after all, they are the files diablo II uses to log to bnet so if they work for it they should work for my bot. About the version, I dont understand why it is "00 0A 00 01" instead "00 0A 00 00" like the d2 client, I'll try to solve that, if anyone knows why could this be this, post plz.

UserLoser.

Quote from: z-stars on July 25, 2004, 08:19 PM


I think they aren't modified, after all, they are the files diablo II uses to log to bnet so if they work for it they should work for my bot. About the version, I dont understand why it is "00 0A 00 01" instead "00 0A 00 00" like the d2 client, I'll try to solve that, if anyone knows why could this be this, post plz.

Are you using the expansion files or classic files?

z-stars

Aparently, CheckRevision() puts a wrong value into dwVersion. I have tried changing it to the right value, but it still gives me "Invalid Version". But if CheckRevision() puts wrong values in dwVersion, maybe it puts wrong values in the ExeHash too. Could this be caused by the arguments I pass to CheckRevision(), or by the CheckRevision() function itself?

z-stars

#71
Quote from: UserLoser. on July 25, 2004, 08:25 PM
Quote from: z-stars on July 25, 2004, 08:19 PM


I think they aren't modified, after all, they are the files diablo II uses to log to bnet so if they work for it they should work for my bot. About the version, I dont understand why it is "00 0A 00 01" instead "00 0A 00 00" like the d2 client, I'll try to solve that, if anyone knows why could this be this, post plz.

Are you using the expansion files or classic files?


Uhm what do you mean? I've LOD installed if that's what u mean. I'm passing as arguments to CheckRevision() the path to the files d2Client, BnClient, and game.exe. (They are in D2's folder).

z-stars

I found another thing that doesn't work :(

This is the bnetdoc description of 0x51 packet:

(DWORD)       Client Token
(DWORD)       EXE Version
(DWORD)       EXE Hash
(DWORD)       Number of keys in this packet
(BOOLEAN)    Using Spawn (32-bit)

For Each Key:
(DWORD)       Key Length
(DWORD)       Product
(DWORD)       CDKEY Value 1
(DWORD)       Unknown (0)
(DWORD[5])    Hashed Key Data

(STRING)       Exe Information
(STRING)       CD Key owner name


Each key, has a "CDKEY Value 1" dword.
In the logs D2Client to Battle.net, these values are always the same. (The value 1 of the first cd key is different from the value 1 of the second cd key, but when I log to battle.net again, they never change).
But my program sends a different "CDKEY Value 1" value each time it tries to log to bnet, so I think there is some problem here...

z-stars

I go to sleep, if anyone finds out anything post it plz
Thx everyone for the help BTW.

dxoigmn

Here is what I would do.  Packet log the real client then in your client emulate that packet log exactly without connecting to battle.net.   That means fixing the values of the client salt, server salt, the equation string, the mpq file.  Make sure you use the same cdkeys as your real client too.   This should save you a load of headaches when you start debugging your cdkey stuff because battle.net will start ip banning you for several minutes.  Alternatively, you could create a test server using Arta's TestBNCS and connect locally.

|