• Welcome to Valhalla Legends Archive.
 

C++ Basic Connection

Started by Trunning, March 27, 2010, 03:25 AM

Previous topic - Next topic

Hdx

#60
Quote from: Trunning on April 28, 2010, 10:43 PM
As I said in my last post, I attempted and failed.
Post your current code, DO NOT BREAK THE FUCKING TABLES, and we can see where you're fucking up.

Quote from: Trunning on April 28, 2010, 10:43 PMIt's not like the send me a struct that contains.
(DWORD) Logon Type
(DWORD) Server Token
(DWORD) UDPValue *
(FILETIME) MPQ filetime
(STRING) IX86ver filename
(STRING) ValueString
As a matter of a fact, it does ;) (Well, you have to extract the strings, but ya)

Proud host of the JBLS server www.JBLS.org.
JBLS.org Status:
JBLS/BNLS Server Status

Trunning

I'm getting an error at runtime which is "Run-Time Check Failure #2 - Stack around the variable 'auth' was corrupted.".

#pragma comment (lib, "Ws2_32.lib")
#include <windows.h>
#include <winsock.h>
#include <string>
#include <iostream>
using namespace std;

struct BNCS_HEADER {
BYTE bHead;
BYTE bID;
WORD wLen;
};

struct SID_AUTH_INFO {
BNCS_HEADER Header;
DWORD   ProtocolID;
DWORD   PlatformID;
DWORD   ProductID;
DWORD   VerByte;
DWORD   ProductLang;
DWORD   LocalIP;
DWORD   TimeZone;
DWORD   LocaleID;
DWORD   LangID;
char *CountryAbbr;
char *CountryName;
};

int socket_connect(SOCKET sockBNCS, const char *Server, WORD Port){
LPHOSTENT host = gethostbyname(Server);
if (!host)
return -1;

SOCKADDR_IN info;
info.sin_family = AF_INET;
info.sin_addr = *((LPIN_ADDR)*host->h_addr_list);
info.sin_port = htons(Port);

if (connect(sockBNCS, (LPSOCKADDR)&info, sizeof(info)) == SOCKET_ERROR){
return -1;
}

return 0;
}

int send_SID_AUTH_INFO(SOCKET sockBNCS){
SID_AUTH_INFO pkt;
int sent = 0;
memset(&pkt, 0, sizeof(SID_AUTH_INFO));

pkt.ProtocolID = 0x00;
pkt.PlatformID = 'IX86';
pkt.ProductID = 'D2DV';
pkt.VerByte = 0x0C;
pkt.LocalIP = inet_addr("192.168.1.100");
pkt.TimeZone = 0x00;
pkt.LocaleID = GetUserDefaultLCID();
pkt.LangID = GetUserDefaultLangID();

pkt.CountryAbbr = (char*)malloc(4);
pkt.CountryName = (char*)malloc(14);
strcpy(pkt.CountryAbbr, "USA");
strcpy(pkt.CountryName, "United States");

int pkt_size = sizeof(pkt) - 8;

pkt.Header.bHead = 0xFF;
pkt.Header.bID = 0x50;
pkt.Header.wLen = pkt_size + 18;

char *buffer;

buffer = (char*)malloc(pkt.Header.wLen);
memcpy(buffer, &pkt, pkt_size);
memcpy(buffer + pkt_size, pkt.CountryAbbr, 4);
memcpy(buffer + pkt_size + 4, pkt.CountryName, 14);

sent = send(sockBNCS, (const char*)buffer, pkt.Header.wLen, NULL);
return sent;
}

int recv_SID_PING(SOCKET sockBNCS){
BNCS_HEADER header;
void *data = malloc(0x200);
int data_max = 0x200, sent;

while (true){
sent = recv(sockBNCS, (char*)&header, sizeof(header), NULL);
if (sent != sizeof(header)){
cout << "Didn't receive full header\n";
return -1;
} else if ( sent == sizeof(header))
break;
}

if (header.wLen - 4 > data_max){
free(data);
data = malloc(header.wLen - 4);
}

sent = recv(sockBNCS, (char*)&data, header.wLen - 4, NULL);
if (sent != header.wLen - 4){
cout << "\nCould not read packet data";
return -1;
}

if (header.bID == '%'){
cout << "\n\nReceived packet < 0x20 < " << header.wLen - 4 << " bytes > >";
cout << "\nServer cookie : " << data;
}

return header.wLen;
}

int recv_SID_AUTH_INFO(SOCKET sockBNCS){
BNCS_HEADER header;
void *auth = malloc(0x250);
memset(auth, 0, 0x250);
int data_max = 0x250, sent;

while (true){
sent = recv(sockBNCS, (char*)&header, sizeof(header), NULL);
if (sent != sizeof(header)){
cout << "Didn't receive full header\n";
return -1;
} else if ( sent == sizeof(header))
break;
}

if (header.wLen - 4 > data_max){
free(auth);
auth = malloc(header.wLen - 4);
}

sent = recv(sockBNCS, (char*)&auth, header.wLen - 4, NULL);
if (sent != header.wLen - 4){
cout << "\nCould not read packet data";
return -1;
}

return header.wLen;
}

int main(){
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 0), &wsaData);


SOCKET sockBNCS = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockBNCS == INVALID_SOCKET){
cout << "Failed to create socket!";
cin.ignore();
cin.get();
return -1;
}

if (socket_connect(sockBNCS, "useast.battle.net", 6112) == -1){
cout << "Failed to connect!";
cin.ignore();
cin.get();
return -1;
}

cout << "Sending protocol byte...\n";
int sent;
sent = send(sockBNCS, "\x01", 1, NULL);

if (sent > 0)
cout << "Sent < " << sent << " bytes >\n";
else
cout << "Failed to send protocol byte!\n";

cout << "Sending 0x50...\n";
sent = send_SID_AUTH_INFO(sockBNCS);
cout << "Sent < " << sent << " bytes >\n";

if (recv_SID_PING(sockBNCS) == -1){
cin.ignore();
cin.get();
closesocket(sockBNCS);
WSACleanup();
}

if (recv_SID_AUTH_INFO(sockBNCS) == -1){
cin.ignore();
cin.get();
closesocket(sockBNCS);
WSACleanup();
}

cin.ignore();
cin.get();
closesocket(sockBNCS);
WSACleanup();
return 0;
}

Hdx

Why the hell are you duplicating code?
The whole, Receive the header, then receive the data should be in your main() function, NOT in your recv_ functions.

Proud host of the JBLS server www.JBLS.org.
JBLS.org Status:
JBLS/BNLS Server Status

l)ragon


TIME_ZONE_INFORMATION tz_Time;
GetTimeZoneInformation(&tz_Time);

pkt.TimeZone = tz_Time.Bias;
*^~·.,¸¸,.·´¯`·.,¸¸,.-·~^*ˆ¨¯¯¨ˆ*^~·.,l)ragon,.-·~^*ˆ¨¯¯¨ˆ*^~·.,¸¸,.·´¯`·.,¸¸,.-·~^*

Trunning

#64
Made another attempt, I'm unsure if my struct is right ( Don't know what data type to use for MPQTime ), let alone if I'm suppose to use one.

#pragma comment (lib, "Ws2_32.lib")
#include <windows.h>
#include <winsock.h>
#include <string>
#include <iostream>
using namespace std;

struct BNCS_HEADER {
BYTE bHead;
BYTE bID;
WORD wLen;
};

struct SID_AUTH_INFO {
BNCS_HEADER Header;
DWORD   ProtocolID;
DWORD   PlatformID;
DWORD   ProductID;
DWORD   VerByte;
DWORD   ProductLang;
DWORD   LocalIP;
DWORD   TimeZone;
DWORD   LocaleID;
DWORD   LangID;
char *CountryAbbr;
char *CountryName;
};

struct SERVER_SAI {
BNCS_HEADER Header;
DWORD LogonType;
DWORD ServerToken;
DWORD UDPVal;
DWORD MPQTime;
string Ver;
string Val;
};

int socket_connect(SOCKET sockBNCS, const char *Server, WORD Port){
LPHOSTENT host = gethostbyname(Server);
if (!host)
return -1;

SOCKADDR_IN info;
info.sin_family = AF_INET;
info.sin_addr = *((LPIN_ADDR)*host->h_addr_list);
info.sin_port = htons(Port);

if (connect(sockBNCS, (LPSOCKADDR)&info, sizeof(info)) == SOCKET_ERROR){
return -1;
}

return 0;
}

int send_SID_AUTH_INFO(SOCKET sockBNCS){
SID_AUTH_INFO pkt;
int sent = 0;
memset(&pkt, 0, sizeof(SID_AUTH_INFO));

pkt.ProtocolID = 0x00;
pkt.PlatformID = 'IX86';
pkt.ProductID = 'D2DV';
pkt.VerByte = 0x0C;
pkt.LocalIP = inet_addr("192.168.1.100");
pkt.TimeZone = 0x00;
pkt.LocaleID = GetUserDefaultLCID();
pkt.LangID = GetUserDefaultLangID();

pkt.CountryAbbr = (char*)malloc(4);
pkt.CountryName = (char*)malloc(14);
strcpy(pkt.CountryAbbr, "USA");
strcpy(pkt.CountryName, "United States");

int pkt_size = sizeof(pkt) - 8;

pkt.Header.bHead = 0xFF;
pkt.Header.bID = 0x50;
pkt.Header.wLen = pkt_size + 18;

char *buffer;

buffer = (char*)malloc(pkt.Header.wLen);
memcpy(buffer, &pkt, pkt_size);
memcpy(buffer + pkt_size, pkt.CountryAbbr, 4);
memcpy(buffer + pkt_size + 4, pkt.CountryName, 14);

sent = send(sockBNCS, (const char*)buffer, pkt.Header.wLen, NULL);
return sent;
}

int main(){
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 0), &wsaData);


SOCKET sockBNCS = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockBNCS == INVALID_SOCKET){
cout << "Failed to create socket!";
cin.ignore();
cin.get();
return -1;
}

if (socket_connect(sockBNCS, "useast.battle.net", 6112) == -1){
cout << "Failed to connect!";
cin.ignore();
cin.get();
return -1;
}

cout << "Sending protocol byte...\n";
int sent;
sent = send(sockBNCS, "\x01", 1, NULL);

if (sent > 0)
cout << "Sent < " << sent << " bytes >\n";
else
cout << "Failed to send protocol byte!\n";

cout << "Sending 0x50...\n";
sent = send_SID_AUTH_INFO(sockBNCS);
cout << "Sent < " << sent << " bytes >\n";

BNCS_HEADER header;
void *data = malloc(0x200);
int data_max = 0x200;

while (true){
sent = recv(sockBNCS, (char*)&header, sizeof(header), NULL);
if (sent != sizeof(header)){
cout << "Didn't receive full header\n";
cin.ignore();
cin.get();
closesocket(sockBNCS);
WSACleanup();
} else if ( sent == sizeof(header))
break;
}

if (header.wLen - 4 > data_max){
free(data);
data = malloc(header.wLen - 4);
}

sent = recv(sockBNCS, (char*)&data, header.wLen - 4, NULL);
if (sent != header.wLen - 4){
cout << "\nCould not read packet data";
cin.ignore();
cin.get();
closesocket(sockBNCS);
WSACleanup();
}

if (header.bID == '%'){
cout << "\n\nReceived packet < 0x20 < " << header.wLen - 4 << " bytes > >";
cout << "\nServer cookie : " << data;
}

SERVER_SAI auth;
while (true){
sent = recv(sockBNCS, (char*)&auth, sizeof(auth), NULL);
if (auth.Header.wLen - 4 != sizeof(auth)){
cout << "\n\nDidn't receive full header\n";
cin.ignore();
cin.get();
closesocket(sockBNCS);
WSACleanup();
return -1;
} else if (auth.Header.wLen - 4 == sizeof(auth))
break;
}

cout << "\n\nReceived packet < 0x50 < " << auth.Header.wLen - 4 << " bytes > >";

cin.ignore();
cin.get();
closesocket(sockBNCS);
WSACleanup();
return 0;
}

Hdx

#65
Tired, so meh.
This is where a lot of the benifits of data buffers come in.
Anyways, the output of the following code is:
QuoteSending protocol byte...
Sent 1 bytes
Received Packet ID: 0x25 Length: 0x0008 (8)
Ping 0x69321268
Pong 0x69321268
Received Packet ID: 0x50 Length: 0x0067 (103)
Received 0x50 ver-IX86-5.mpq, B=2407285681 A=2737422848 C=383046708 4 A=A^S B=B^C C=C+A A=A-B
#include "stdafx.h"
#pragma comment (lib, "Ws2_32.lib")
#include <winsock2.h>
#include <windows.h>
#include <string>
#include <iostream>
using namespace std;

struct BNCS_HEADER {
BYTE Sanity;
BYTE ID;
WORD Length;
};

struct CMSG_SID_AUTH_INFO {
DWORD   ProtocolID;
DWORD   PlatformID;
DWORD   ProductID;
DWORD   VerByte;
DWORD   ProductLang;
DWORD   LocalIP;
DWORD   TimeZone;
DWORD   LocaleID;
DWORD   LangID;
char *CountryAbbr;
char *CountryName;
};

struct SMSG_SID_AUTH_INFO {
DWORD LogonType;
DWORD ServerToken;
DWORD UDPVal;
unsigned long long ArchiveTime;
char   *ArchiveName;
char   *Seed;
};

struct CMSG_SID_PING{
DWORD PingValue;
};

struct SMSG_SID_PING{
DWORD PingValue;
};

void bncs_send(SOCKET sockBNCS, int ID, char *data, int length){
BNCS_HEADER header;
header.Sanity = 0xFF;
header.ID     = ID;
header.Length = length + sizeof(BNCS_HEADER);

send(sockBNCS, (const char*)&header, sizeof(BNCS_HEADER), NULL);
send(sockBNCS, (const char*)data, length, NULL);
}

int socket_connect(SOCKET sockBNCS, const char *Server, WORD Port){
hostent *host = gethostbyname(Server);
if (!host)
return -1;

SOCKADDR_IN info;
info.sin_family = AF_INET;
info.sin_addr = *((LPIN_ADDR)*host->h_addr_list);
info.sin_port = htons(Port);

if (connect(sockBNCS, (LPSOCKADDR)&info, sizeof(info)) == SOCKET_ERROR){
return -1;
}

return 0;
}

int send_SID_AUTH_INFO(SOCKET sockBNCS){
CMSG_SID_AUTH_INFO pkt;

int sent = 0;
memset(&pkt, 0, sizeof(CMSG_SID_AUTH_INFO));

TIME_ZONE_INFORMATION tz_Time;
GetTimeZoneInformation(&tz_Time);

pkt.ProtocolID = 0x00;
pkt.PlatformID = 'IX86';
pkt.ProductID = 'D2DV';
pkt.VerByte = 0x0C;
pkt.ProductLang = GetUserDefaultLangID();
pkt.LocalIP = inet_addr("192.168.1.100");
pkt.TimeZone = tz_Time.Bias;
pkt.LocaleID = GetUserDefaultLCID();
pkt.LangID = GetUserDefaultLangID();
pkt.CountryAbbr = (char*)malloc(4);
pkt.CountryName = (char*)malloc(14);
strcpy_s(pkt.CountryAbbr, 4, "USA");
strcpy_s(pkt.CountryName, 14, "United States");

char *buffer;
int pkt_size = sizeof(pkt) - (sizeof(char *) * 2);
int full_size = pkt_size + strlen(pkt.CountryAbbr) + strlen(pkt.CountryName) + 2;
buffer = (char*)malloc(full_size);
memset(buffer, 0, full_size);
memcpy(buffer, &pkt, pkt_size);
strcpy_s(buffer + pkt_size, 4, pkt.CountryAbbr);
strcpy_s(buffer + pkt_size + strlen(pkt.CountryAbbr) + 1, 14, pkt.CountryName);

bncs_send(sockBNCS, 0x50, buffer, full_size);
return 1;
}

void send_SID_PING(SOCKET sockBNCS, DWORD value){
printf("Pong 0x%08X\n", value);
bncs_send(sockBNCS, 0x25, (char*)&value, 4);
}

void recv_SID_PING(SOCKET sockBNCS, char *data, int length){
SMSG_SID_PING pkt;
memcpy(&pkt, data, sizeof(pkt));
printf("Ping 0x%08X\n", pkt.PingValue);
send_SID_PING(sockBNCS, pkt.PingValue);
}

void recv_SID_AUTH_INFO(SOCKET sockBNCS, char *data, int length){
SMSG_SID_AUTH_INFO pkt;
int raw_size = 20; //sizeof(pkt) - (sizeof(char *) * 2);
memcpy(&pkt, data, raw_size);

char *name_addr = data + raw_size;
int   name_len  = strlen(name_addr);
char *seed_addr = name_addr + name_len + 1;
int   seed_len  = strlen(seed_addr);

pkt.ArchiveName = (char*)malloc(name_len + 1);
strcpy_s(pkt.ArchiveName, name_len + 1, name_addr);

pkt.Seed = (char*)malloc(seed_len + 1);
strcpy_s(pkt.Seed, seed_len + 1, seed_addr);

printf("Received 0x50 %s, %s\n", pkt.ArchiveName, pkt.Seed);
}

int main(){
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 0), &wsaData);

SOCKET sockBNCS = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockBNCS == INVALID_SOCKET){
printf("Failed to create socket!\n");
cin.get();
return -1;
}

if (socket_connect(sockBNCS, "uswest.battle.net", 6112) == -1){
printf("Failed to connect!\n");
cin.get();
return -1;
}

printf("Sending protocol byte...\n");

int count;
count = send(sockBNCS, "\x01", 1, NULL);

if (count > 0)
printf("Sent %d bytes\n", count);
else
printf("Failed to send protocol byte!\n");

if(send_SID_AUTH_INFO(sockBNCS)){
BNCS_HEADER header;
char *data = (char*)malloc(0x200);
int data_max = 0x200;

while (true){
count = recv(sockBNCS, (char*)&header, sizeof(header), MSG_WAITALL);
if (count != sizeof(header)){
printf("Didn't receive full header, %d of %d\n", count, sizeof(BNCS_HEADER));
closesocket(sockBNCS);
WSACleanup();
cin.get();
return 0;
} else {
if (header.Length - 4 > data_max){
free(data);
data = (char *)malloc(header.Length - 4);
}
count = recv(sockBNCS, data, header.Length - 4, MSG_WAITALL);
if (count == SOCKET_ERROR){
count = WSAGetLastError();
printf("Receiving failed error #%d\n", count);
return 0;
}else if(count == 0 && header.Length != 4){
printf("Server closed connection\n");
return 0;
}else if(count != header.Length - 4){
printf("Failed to receive full packet ID: 0x%02X, received %d of %d\n",
header.ID, count, header.Length - 4);
return 0;
}else{
printf("Received Packet ID: 0x%02X Length: 0x%04X (%d)\n",
header.ID, header.Length, header.Length);
switch(header.ID){
case 0x25: recv_SID_PING     (sockBNCS, data, header.Length - 4); break;
case 0x50: recv_SID_AUTH_INFO(sockBNCS, data, header.Length - 4); break;
}
}
}
}
}

printf("Exiting Program!\n");
cin.get();
closesocket(sockBNCS);
WSACleanup();
return 0;
}

You are using C++, make use of some of the better aspects of C++, (mainly move away from cin/cout, and start using objects!)

Proud host of the JBLS server www.JBLS.org.
JBLS.org Status:
JBLS/BNLS Server Status

Trunning

Here is my output from your code:

Sending protocol byte...
Sent 1 bytes
Didn't receive full header, -1 of 4


But in wireshark I'm clearly getting all the data.

Hdx

That *should* only popup if you're ipbanned -1 is SOCKET_ERROR. Switch servers.

Proud host of the JBLS server www.JBLS.org.
JBLS.org Status:
JBLS/BNLS Server Status

Trunning

#68
Well settings the send()'s flags to NULL fixed it for me.

And do I have to create a new socket, for BNFTP to download the archive? Or can I skip that?

Also couple questions:

How do I obtain these values:
(DWORD) Client Token
(DWORD) EXE Version
(DWORD) EXE Hash


What are these suppose to contain:
(DWORD) CD-key's product value
(DWORD) CD-key's public value


Can you give me an exmaple of the structure SID_AUTH_INFO.

Thanks...

l)ragon

#69
Quote from: Trunning on April 29, 2010, 02:38 AM
Well settings the send()'s flags to NULL fixed it for me.

And do I have to create a new socket, for BNFTP to download the archive? Or can I skip that?

Also couple questions:

How do I obtain these values:
(DWORD) Client Token
(DWORD) EXE Version
(DWORD) EXE Hash


What are these suppose to contain:
(DWORD) CD-key's product value
(DWORD) CD-key's public value


Can you give me an exmaple of the structure SID_AUTH_INFO.

Thanks...

You can skip the BN_FTP but yes you would need another socket for it lol.
Edit: as for the cd values, you should be able to find them on the forum here somewhere, along with other various functions youll need for them.
*^~·.,¸¸,.·´¯`·.,¸¸,.-·~^*ˆ¨¯¯¨ˆ*^~·.,l)ragon,.-·~^*ˆ¨¯¯¨ˆ*^~·.,¸¸,.·´¯`·.,¸¸,.-·~^*

Trunning

I'll try finding them, and I meant SID_AUTH_CHECK in my last post.

l)ragon

Quote from: Trunning on April 29, 2010, 08:45 PM
I'll try finding them, and I meant SID_AUTH_CHECK in my last post.
thats on the forum here somewhere to.
*^~·.,¸¸,.·´¯`·.,¸¸,.-·~^*ˆ¨¯¯¨ˆ*^~·.,l)ragon,.-·~^*ˆ¨¯¯¨ˆ*^~·.,¸¸,.·´¯`·.,¸¸,.-·~^*

Trunning

I searched and found very little, but it appears I need a CheckRevision() function, that's in one of several Dll's. Or I can use BNLS (Battle.net Login Server) to do it.

I can't find any working links to download one of the Dll's.

l)ragon

#73
Quote from: Trunning on April 30, 2010, 12:48 AM
I searched and found very little, but it appears I need a CheckRevision() function, that's in one of several Dll's. Or I can use BNLS (Battle.net Login Server) to do it.

I can't find any working links to download one of the Dll's.
Your not looking hard enough, http://forum.valhallalegends.com/index.php?topic=16314.0
Edit: As for DLLs think the only ones to ever have been posted here was warden.dll and some other one both links are broken to so you need to ask around here maybe, that or use JBLS.
edit2: or write your own heh.
*^~·.,¸¸,.·´¯`·.,¸¸,.-·~^*ˆ¨¯¯¨ˆ*^~·.,l)ragon,.-·~^*ˆ¨¯¯¨ˆ*^~·.,¸¸,.·´¯`·.,¸¸,.-·~^*

Trunning

I'll make a new topic asking for one, I'm not using BNLS.

|