Witam,
Na podstawie opisu protokołu GG z tej strony: http://dev.null.pl/ekg/docs/protocol.html napisałem sobie poniższy kod:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
struct gg_header {
int type; /* typ pakietu */
int length; /* długość reszty pakietu */
};
#define GG_WELCOME 0x0001
struct gg_welcome {
int seed; /* klucz szyfrowania hasła */
};
#define GG_LOGIN60 0x0015
struct gg_login60 {
int uin; /* mój numerek */
int hash; /* hash hasła */
int status; /* status na dzień dobry */
int version; /* moja wersja klienta */
char unknown1; /* 0x00 */
int local_ip; /* mój adres ip */
short local_port; /* port, na którym słucham */
int external_ip; /* zewnętrzny adres ip */
short external_port; /* zewnętrzny port */
char image_size; /* maksymalny rozmiar grafiki w KB */
char unknown2; /* 0xbe */
char description[71]; /* opis, nie musi wystąpić */
int time; /* czas, nie musi wystąpić */
};
int gg_login_hash(char *password, int seed)
{
unsigned int x, y, z;
y = seed;
for (x = 0; *password; password++) {
x = (x & 0xffffff00) | *password;
y ^= x;
y += x;
x <<= 8;
y ^= x;
x <<= 8;
y -= x;
x <<= 8;
y ^= x;
z = y & 0x1f;
y = (y << z) | (y >> (32 - z));
}
return y;
}
void clear(struct gg_header *header)
{
header->type = 0;
header->length = 0;
}
main()
{
int sockd;
struct sockaddr_in serv_name;
sockd = socket(AF_INET, SOCK_STREAM, 0);
serv_name.sin_family = AF_INET;
inet_aton("217.17.41.88", &serv_name.sin_addr);
serv_name.sin_port = htons(8074);
printf("[+] IP converted...\n");
printf("[ ] Connecting...");
if (connect(sockd, (struct sockaddr*)&serv_name, sizeof(serv_name)) == -1)
{
printf("\r[-] Couldn`t connect...\n");
return 0;
}
else
{
printf("\r[+] Connected!\n");
}
struct gg_header header;
clear(&header);
struct gg_welcome welcome;
if (read(sockd, &header, sizeof(header) ) )
{
printf("[+] Seed recieved!\n");
read(sockd, &welcome, header.length);
}
else
{
printf("[-] Failed recieving seed.\n");
return 0;
}
printf("0x%x %d\n", header.type, welcome.seed);
struct gg_login60 login;
char *password = "test";
gg_login_hash(password, welcome.seed);
printf("[=] Hashed password: [%s]\n", password);
login.uin = 7230595;
login.hash = password;
login.status = 0x0004;
login.version = 0x20;
login.unknown1 = 0x00;
login.local_ip = 0x00;
login.local_port = 1550;
login.external_ip = 0x00;
login.external_port = 1550;
login.image_size = "400";
login.unknown2 = 0xbe;
login.description[8] = "success\0";
printf("[ ] Sending login request...");
#define GG_LOGIN_OK 0x0003
#define GG_LOGIN_FAILED 0x0009
if (write(sockd, &login, sizeof(login) ) )
{
clear(&header);
read(sockd, &header, sizeof(header) );
printf("\r[+] Login information send - you`re logged in 0x%x!\n", header.type);
}
else
{
printf("\r[-] Failed logging...\n");
return 0;
}
struct gg_header returned;
returned.type = 0;
read(sockd, &returned, sizeof(returned) );
printf("0x%x", returned.type);
return 0;
}
Po skompilowaniu i odpaleniu program wypisuje:
[+] IP converted...
[+] Connected!...
[+] Seed recieved!
0x1 338720476
[=] Hashed password: [test]
[+] Login information send - you`re logged in 0x0!
0x0
Jednak po 'you`re logged in' powinno być wg protokołu 0x3 lub 0x9. Czy ktoś może mi napisać, gdzie popełniłem w kodzie błąd?
Wydaje mi się też, że jest błąd w fukcji hashującej hasło, bo nie hashuje go.
Z góry dziękuję :)