God damnet
32-bit ints != 64-bit ints
I was using a 32-bit in when I should of used a 64-bit in.
I fixed that. Now I'm on the final loop of WC3 decoding.
uint32_t eax, ecx, edx;
uint32_t location;
e = 0;
for(c = 0; c < 120; c++){
eax = c & 0x1F;
ecx = e & 0x1F;
edx = 3 - (edi >> 5);
location = 12 - ((e >> 5) << 2);
ebp = values[location / 4];
ebp = (ebp & (1 << ecx)) >> ecx;
values[edx] = ((ebp & 1) << eax) | (~(1 << eax) & values[edx]);
printf("%08X %08X %08X %08X\n", values[0], values[1], values[2], values[3]);
e = (e + 11) % 120;
}
Not working correctly. I'll look at it more later. But now, i'm at the mall hoping the owner of the WiFi i'm on [SSID: Uv been hAcked] will try and hack/talk to me
#ifndef CDKEYS_C
#define CDKEYS_C
#define hexvalue(n) (((n) & 0x0F) + (((n) & 0x0F) < 10 ? 0x30 : 0x37))
#define numvalue(n) (toupper(n) - (isdigit(n) ? 0x30 : 0x37))
#include "cdkeys.h"
uint8_t *orig_key = "246789BCDEFGHJKMNPRTVWXZ";
uint8_t *war3_key = "246789BCDEFGHJKMNPRTVWXYZ";
uint8_t star_seq[12] = {6, 0, 2, 9, 3, 11, 1, 7, 5, 4, 10, 8};
uint8_t wcd2_seq[16] = {5, 6, 0, 1, 2, 3, 4, 9, 1, 11, 12, 13, 14, 15, 7, 8};
uint8_t TranslateTable[] = {
0x09, 0x04, 0x07, 0x0F, 0x0D, 0x0A, 0x03, 0x0B, 0x01, 0x02, 0x0C, 0x08,
0x06, 0x0E, 0x05, 0x00, 0x09, 0x0B, 0x05, 0x04, 0x08, 0x0F, 0x01, 0x0E,
0x07, 0x00, 0x03, 0x02, 0x0A, 0x06, 0x0D, 0x0C, 0x0C, 0x0E, 0x01, 0x04,
0x09, 0x0F, 0x0A, 0x0B, 0x0D, 0x06, 0x00, 0x08, 0x07, 0x02, 0x05, 0x03,
0x0B, 0x02, 0x05, 0x0E, 0x0D, 0x03, 0x09, 0x00, 0x01, 0x0F, 0x07, 0x0C,
0x0A, 0x06, 0x04, 0x08, 0x06, 0x02, 0x04, 0x05, 0x0B, 0x08, 0x0C, 0x0E,
0x0D, 0x0F, 0x07, 0x01, 0x0A, 0x00, 0x03, 0x09, 0x05, 0x04, 0x0E, 0x0C,
0x07, 0x06, 0x0D, 0x0A, 0x0F, 0x02, 0x09, 0x01, 0x00, 0x0B, 0x08, 0x03,
0x0C, 0x07, 0x08, 0x0F, 0x0B, 0x00, 0x05, 0x09, 0x0D, 0x0A, 0x06, 0x0E,
0x02, 0x04, 0x03, 0x01, 0x03, 0x0A, 0x0E, 0x08, 0x01, 0x0B, 0x05, 0x04,
0x02, 0x0F, 0x0D, 0x0C, 0x06, 0x07, 0x09, 0x00, 0x0C, 0x0D, 0x01, 0x0F,
0x08, 0x0E, 0x05, 0x0B, 0x03, 0x0A, 0x09, 0x00, 0x07, 0x02, 0x04, 0x06,
0x0D, 0x0A, 0x07, 0x0E, 0x01, 0x06, 0x0B, 0x08, 0x0F, 0x0C, 0x05, 0x02,
0x03, 0x00, 0x04, 0x09, 0x03, 0x0E, 0x07, 0x05, 0x0B, 0x0F, 0x08, 0x0C,
0x01, 0x0A, 0x04, 0x0D, 0x00, 0x06, 0x09, 0x02, 0x0B, 0x06, 0x09, 0x04,
0x01, 0x08, 0x0A, 0x0D, 0x07, 0x0E, 0x00, 0x0C, 0x0F, 0x02, 0x03, 0x05,
0x0C, 0x07, 0x08, 0x0D, 0x03, 0x0B, 0x00, 0x0E, 0x06, 0x0F, 0x09, 0x04,
0x0A, 0x01, 0x05, 0x02, 0x0C, 0x06, 0x0D, 0x09, 0x0B, 0x00, 0x01, 0x02,
0x0F, 0x07, 0x03, 0x04, 0x0A, 0x0E, 0x08, 0x05, 0x03, 0x06, 0x01, 0x05,
0x0B, 0x0C, 0x08, 0x00, 0x0F, 0x0E, 0x09, 0x04, 0x07, 0x0A, 0x0D, 0x02,
0x0A, 0x07, 0x0B, 0x0F, 0x02, 0x08, 0x00, 0x0D, 0x0E, 0x0C, 0x01, 0x06,
0x09, 0x03, 0x05, 0x04, 0x0A, 0x0B, 0x0D, 0x04, 0x03, 0x08, 0x05, 0x09,
0x01, 0x00, 0x0F, 0x0C, 0x07, 0x0E, 0x02, 0x06, 0x0B, 0x04, 0x0D, 0x0F,
0x01, 0x06, 0x03, 0x0E, 0x07, 0x0A, 0x0C, 0x08, 0x09, 0x02, 0x05, 0x00,
0x09, 0x06, 0x07, 0x00, 0x01, 0x0A, 0x0D, 0x02, 0x03, 0x0E, 0x0F, 0x0C,
0x05, 0x0B, 0x04, 0x08, 0x0D, 0x0E, 0x05, 0x06, 0x01, 0x09, 0x08, 0x0C,
0x02, 0x0F, 0x03, 0x07, 0x0B, 0x04, 0x00, 0x0A, 0x09, 0x0F, 0x04, 0x00,
0x01, 0x06, 0x0A, 0x0E, 0x02, 0x03, 0x07, 0x0D, 0x05, 0x0B, 0x08, 0x0C,
0x03, 0x0E, 0x01, 0x0A, 0x02, 0x0C, 0x08, 0x04, 0x0B, 0x07, 0x0D, 0x00,
0x0F, 0x06, 0x09, 0x05, 0x07, 0x02, 0x0C, 0x06, 0x0A, 0x08, 0x0B, 0x00,
0x0F, 0x04, 0x03, 0x0E, 0x09, 0x01, 0x0D, 0x05, 0x0C, 0x04, 0x05, 0x09,
0x0A, 0x02, 0x08, 0x0D, 0x03, 0x0F, 0x01, 0x0E, 0x06, 0x07, 0x0B, 0x00,
0x0A, 0x08, 0x0E, 0x0D, 0x09, 0x0F, 0x03, 0x00, 0x04, 0x06, 0x01, 0x0C,
0x07, 0x0B, 0x02, 0x05, 0x03, 0x0C, 0x04, 0x0A, 0x02, 0x0F, 0x0D, 0x0E,
0x07, 0x00, 0x05, 0x08, 0x01, 0x06, 0x0B, 0x09, 0x0A, 0x0C, 0x01, 0x00,
0x09, 0x0E, 0x0D, 0x0B, 0x03, 0x07, 0x0F, 0x08, 0x05, 0x02, 0x04, 0x06,
0x0E, 0x0A, 0x01, 0x08, 0x07, 0x06, 0x05, 0x0C, 0x02, 0x0F, 0x00, 0x0D,
0x03, 0x0B, 0x04, 0x09, 0x03, 0x08, 0x0E, 0x00, 0x07, 0x09, 0x0F, 0x0C,
0x01, 0x06, 0x0D, 0x02, 0x05, 0x0A, 0x0B, 0x04, 0x03, 0x0A, 0x0C, 0x04,
0x0D, 0x0B, 0x09, 0x0E, 0x0F, 0x06, 0x01, 0x07, 0x02, 0x00, 0x05, 0x08
};
uint32_t cdkeys_instr(uint8_t *string, uint8_t find){
uint8_t *location = strchr(string, toupper(find));
return (location == NULL ? -1 : location - string);
}
/*******************************************************
*Converts and ASCII strign of number into a long.
*Used in Starcraft Key decoding.
*******************************************************/
uint32_t cdkeys_strtol(uint8_t *number, uint32_t length, uint32_t base){
uint8_t *temp = safe_malloc(length);
memcpy(temp, number, length);
temp[length] = 0;
uint32_t ret = strtol(temp, NULL, base);
free(temp);
return ret;
}
BOOLEAN cdkeys_verifystarcraft(uint8_t *key){
uint32_t sum = 3;
uint32_t i = 0;
if(strlen(key) != 13) return FALSE;
for(i = 0; i < 12; i++)
sum += (key[i] - '0') ^ (sum << 1);
return (sum % 10 == key[12] - '0');
}
/*****************************************************************************
*Reterives the Public, Private, and Product values from an 'old style'
*Starcraft cdkey, AE: the 13-digit numerical key.
*****************************************************************************/
BOOLEAN cdkeys_getstarcraftvalues(uint8_t *key, uint32_t *public_key, uint32_t *private_key, uint32_t *product){
if(cdkeys_verifystarcraft(key) == FALSE) return FALSE;
uint32_t hashkey = 0x13AC9741;
uint8_t sequance[12] = {6, 0, 2, 9, 3, 11, 1, 7, 5, 4, 10, 8};
uint8_t *temp_key = safe_malloc(13);
int32_t c;
for(c = 11; c >= 0; c--){
if(key[sequance[c]] <= '7'){
temp_key[c] = key[sequance[c]] ^ (uint8_t)(hashkey & 7);
hashkey >>= 3;
}else
temp_key[c] = key[sequance[c]] ^ (uint8_t)(c & 1);
}
*product = cdkeys_strtol(temp_key, 2, 10);
*public_key = cdkeys_strtol(temp_key+2, 7, 10);
*private_key = cdkeys_strtol(temp_key+9, 3, 10);
free(temp_key);
return (product != 0 && public_key != 0 && private_key != 0 ? TRUE : FALSE);
}
BOOLEAN cdkeys_verifydiablo(uint8_t *key, uint8_t **decoded){
if(strlen(key) != 16) return FALSE;
uint8_t *temp_key = safe_malloc(16);
uint8_t i;
uint32_t n = 0;
uint32_t checksum = 0;
uint32_t r = 1;
for(i = 0; i < 16; i +=2){
n = (cdkeys_instr(orig_key, key[i + 1]) + (cdkeys_instr(orig_key, key[i]) * 24));
if(n >= 0x100){
n -= 0x100;
checksum |= r;
}
r <<= 1;
temp_key[i] = hexvalue(n >> 4);
temp_key[i + 1] = hexvalue(n);
}
n = 3;
for(i = 0; i < 16; i++)
n += numvalue(temp_key[i]) ^ n * 2;
if((n & 0xFF) != checksum){
free(temp_key);
return FALSE;
}
if(decoded != NULL) *decoded = temp_key;
else free(temp_key);
return TRUE;
}
BOOLEAN cdkeys_getdiablovalues(uint8_t *key, uint32_t *public_key, uint32_t *private_key, uint32_t *product){
uint8_t *temp_key = safe_malloc(16);
if(cdkeys_verifydiablo(key, &temp_key) == FALSE){
free(temp_key);
return FALSE;
}
uint32_t hashkey = 0x13AC9741;
uint16_t i;
uint8_t n;
uint8_t c;
for(i = 15; i < 16; i--){
n = (i > 8 ? i - 9 : 7 + i);
c = temp_key[n];
temp_key[n] = temp_key[i];
temp_key[i] = c;
}
for(i = 15; i < 16; i--){
if(temp_key[i] <= '7'){
temp_key[i] ^= (hashkey & 7);
hashkey >>= 3;
}else if(temp_key[i] < 'A')
temp_key[i] ^= (i & 1);
}
*product = cdkeys_strtol(temp_key, 2, 16);
*public_key = cdkeys_strtol(temp_key+2, 6, 16);
*private_key = cdkeys_strtol(temp_key+8, 8, 16);
free(temp_key);
return ((product != 0) && (public_key != 0) && (private_key != 0));
}
BOOLEAN cdkeys_getwarcraftvalues(uint8_t *key, uint32_t *public_key, uint32_t *private_key, uint32_t *product){
uint8_t *table = safe_malloc(52);
uint32_t *values = safe_malloc(16);
uint32_t c = 0;
uint8_t d = 0;
uint64_t e;
uint32_t f = 30;
uint32_t g;
uint32_t h;
for(c = 0; c < 26; c++){
d = cdkeys_instr(war3_key, toupper(key[c]));
table[f] = (d / 5);
f = (f + 49) % 52;
table[f] = (d % 5);
f = (f + 49) % 52;
}
for(c = 51; c < 52; c--){
for(d = 3; d < 4; d--){
e = (uint64_t)values[d] * 5;
values[d] = table[c] + (uint32_t)e;
table[c] = (uint8_t)(e >> 32);
}
}
f = 24;
d = 2;
for(c = 0x1D0; c < 0x1D1; c -= 0x10){
f = (f + 28) % 32;
g = (values[d / 8] & (0x0F << f)) >> f;
h = 24;
for(e = 29; e < 30; e--){
h = (h + 28) % 32;
if(e != (c / 0x10))
g = TranslateTable[((values[3 - (e >> 3)] & (0x0F << h)) >> h) ^ TranslateTable[g + c] + c];
}
values[d / 8] = ((TranslateTable[g + c] & 0x0F) << f) | ~(0x0F << f) & values[d / 8];
d++;
}
uint32_t eax, ecx, edx;
uint32_t location;
e = 0;
for(c = 0; c < 120; c++){
eax = c & 0x1F;
ecx = e & 0x1F;
edx = 3 - (edi >> 5);
location = 12 - ((e >> 5) << 2);
ebp = values[location / 4];
ebp = (ebp & (1 << ecx)) >> ecx;
values[edx] = ((ebp & 1) << eax) | (~(1 << eax) & values[edx]);
printf("%08X %08X %08X %08X\n", values[0], values[1], values[2], values[3]);
e = (e + 11) % 120;
}
/*for(edi = 0; edi < 120; edi++)
{
eax = edi & 0x1F;
ecx = esi & 0x1F;
edx = 3 - (edi >>> 5);
int location = 12 - ((esi >>> 5) << 2);
ebp = IntFromByteArray.LITTLEENDIAN.getInteger(Copy, location);
ebp = (ebp & (1 << ecx)) >>> ecx;
keyTable[edx] = ((ebp & 1) << eax) | (~(1 << eax) & keyTable[edx]);
esi = (esi + 11) % 120;
System.out.format("%03d %d %08X %08X %08X %08X %08X\n", location, edx, ebp, keyTable[0], keyTable[1], keyTable[2], keyTable[3]);
}
*/
for(c = 0; c < 4; c++){
printf("%08X ", values[c]);
}
}
#endif
once I get it finished I will clean it up, I'm going to clean code, and willing to sacrifice a bit of effiancy to do it. So please don't complain to me about it.