przykładowy program a protokół GG

0

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ę :)

0

Hash z hasła tworzysz w ten sposób:

int hash_z_hasła=gg_login_hash("hasło", welcome.seed);

i teraz dopiero:

login.hash=hash_z_hasła;

i zanim wyślesz login doserwera musisz wysłać nagłówek:

#define GG_LOGIN60 0x0015
struct gg_header header;
header.type=GG_LOGIN60;
header.length=sizeof(login);

doklejasz header do login i wysyłaśż za jednym razem albo najpierw wysyłasz header i zaraz potem login i wtedy dopiero serwer zwraca header.type=0x3 jeśli cię zaloguje albo header.type=0x9 jeśli nie zaloguje, sprawdziłem u siebie o wrócił mi 0x3.

PS. Sorry za ewe. błędy, piszę z pamięci, ale chyba wiesz o co chodzi

1 użytkowników online, w tym zalogowanych: 0, gości: 1