// Kraken Decryptor Source Code // By MHL and Greg, 2008 #include #include #define ROR64(v, b) (((v) >> ((b))) | ((v) << (64 - (b)))) typedef struct MSG_HDR { unsigned char type[2]; unsigned short ver; int length; } MSG_HDR; typedef struct PACKET { unsigned int key0; unsigned int key4; int key8; MSG_HDR msg; int chksum; unsigned char data[1]; } PACKET; void decrypt_math(unsigned char * data, int key8, int ** keys) { int a = key8 * 2; int b, c, e; unsigned int d; int count = 2; PACKET * pckt = (PACKET *) data; do { b = (pckt->key0 << 4) + *(int *)&keys[2]; d = pckt->key0; c = (d >> 5) + *(int *)&keys[3]; pckt->key4 -= (b ^ (a + pckt->key0) ^ c); e = ((pckt->key4 >> 5) + *(int *)&keys[1]); b = ((pckt->key4 << 4) + *(int *)&keys[0]) ^ e; c = a + pckt->key4; a -= key8; pckt->key0 -= (b ^ c); } while (--count); } void decrypt(unsigned char * data, int len, int key0, int key4, int key8) { int keys[4]; unsigned char * ptr = data; keys[0] = key0; keys[1] = key4; keys[2] = ((key4 >> 0x13) & 0x1FFF) | (key0 << 0x0D); keys[3] = (key4 << 0xD) | ((key0 >> 0x13) & 0x1FFF); int idx = len / 8; int rem = len % 8; if (len >= 8) { do { decrypt_math(ptr, key8, (int **)&keys); ptr += 8; } while (--idx); } if (rem > 0) { unsigned char *a = (unsigned char *) &key0; unsigned char *b = (unsigned char *) &key8; for (int i=0; imsg; /* Generate the payload key */ value_part = ROR64(((unsigned long long)hdr->key0<<32)|(unsigned long long)hdr->key4,13); payload_key = (value_part>>32)&0xFFFFFFFF; if (hdr->key8 != 0) { decrypt((unsigned char *)msg, 12, hdr->key0, hdr->key4, hdr->key8); if (msg->length != 0 && msg->length + 24 == len) { if (msg->type[0] == 0x2) /* server reply */ { value_part = ROR64(((unsigned long long)hdr->key0<<32)|(unsigned long long)hdr->key4,17); payload_key = (value_part>>32)&0xFFFFFFFF; } decrypt((unsigned char *)&hdr->data, msg->length, hdr->key0, hdr->key4, payload_key); } } }