home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 1_2002.ISO / Data / Zips / Binary_Bot54213292002.psc / VLBot / CDKeyDecode.c next >
Encoding:
C/C++ Source or Header  |  2001-06-13  |  7.5 KB  |  300 lines

  1. /* Battle.net CD-Key Algorithm Source Code ⌐ YobGuls (yobguls@yobguls.2ndmail.com) 2001
  2.  * This source will decode a CD-Key from either Starcraft or Diablo 2
  3.  * into the three values that need to be sent to Battle.net to verify it */
  4. /* The first value identifies the product that the CD-key is used for, and the next
  5.  * two are part of a string of digits which is kind of like a seed that can be used
  6.  * to generate the key. */
  7.  
  8. #include <windows.h>
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11.  
  12. #include "CDKeyDecode.h"
  13.  
  14. #define ROL(nr, shift)    ((nr << shift) | (nr >> (32 - shift)))
  15.  
  16. /* Code values used in Diablo 2 CD-Key decoding */
  17.  
  18. BYTE codevalues[256] = {
  19. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  20. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  21. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  22. 0xFF, 0xFF, 0x00, 0xFF, 0x01, 0xFF, 0x02, 0x03, 0x04, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  23. 0xFF, 0xFF, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0xFF, 0x0D, 0x0E, 0xFF, 0x0F, 0x10, 0xFF,
  24. 0x11, 0xFF, 0x12, 0xFF, 0x13, 0xFF, 0x14, 0x15, 0x16, 0xFF, 0x17, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  25. 0xFF, 0xFF, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0xFF, 0x0D, 0x0E, 0xFF, 0x0F, 0x10, 0xFF,
  26. 0x11, 0xFF, 0x12, 0xFF, 0x13, 0xFF, 0x14, 0x15, 0x16, 0xFF, 0x17, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  27. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  28. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  29. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  30. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  31. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  32. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  33. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  34. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
  35.  
  36. BOOL DecodeCDKey(LPCTSTR lpszCDKey, DWORD * lpdwProductId, DWORD * lpdwValue1,
  37.                  DWORD * lpdwValue2)
  38. {
  39.    char key[1024], value[1024];
  40.    int i, length, keylength;
  41.    BOOL bValid;
  42.  
  43.    length = strlen(lpszCDKey);
  44.    keylength = 0;
  45.    for (i = 0; i < length; i++)
  46.    {
  47.       if (isalnum(lpszCDKey[i]))
  48.       {
  49.          key[keylength] = lpszCDKey[i];
  50.          keylength++;
  51.       }
  52.    }
  53.    if (keylength == 13)
  54.       bValid = DecodeStarcraftKey(key);
  55.    else if (keylength == 16)
  56.       bValid = DecodeD2Key(key);
  57.    else
  58.       return FALSE;
  59.    strncpy(value, key, 2);
  60.    value[2] = '\0';
  61.    sscanf(value, "%X", lpdwProductId);
  62.    if (keylength == 16)
  63.    {
  64.       strncpy(value, &key[2], 6);
  65.       value[6] = '\0';
  66.       sscanf(value, "%X", lpdwValue1);
  67.       strcpy(value, &key[8]);
  68.       value[8] = '\0';
  69.       sscanf(value, "%X", lpdwValue2);
  70.    }
  71.    else if (keylength == 13)
  72.    {
  73.       strncpy(value, &key[2], 7);
  74.       value[7] = '\0';
  75.       sscanf(value, "%ld", lpdwValue1);
  76.       strncpy(value, &key[9], 3);
  77.       value[3] = '\0';
  78.       sscanf(value, "%ld", lpdwValue2);
  79.    }      
  80.    return bValid;
  81. }
  82.  
  83. BOOL DecodeStarcraftKey(LPSTR key)
  84. {
  85.    DWORD r, n, n2, v, v2, keyvalue;
  86.    BYTE c1, c2, c;
  87.    BOOL bValid;
  88.    int i;
  89.  
  90.    v = 3;
  91.    for (i = 0; i < 12; i++)
  92.    {
  93.       c = key[i];
  94.       n = Get_Num_Value(c);
  95.       n2 = v * 2;
  96.       n ^= n2;
  97.       v += n;
  98.    }
  99.    v %= 10;
  100.    if (Get_Hex_Value(v) == key[12])
  101.       bValid = TRUE;
  102.    else
  103.       bValid = FALSE;
  104.    v = 194;
  105.    for (i = 11; v >= 7, i >= 0; i--)
  106.    {
  107.       c = key[i];
  108.       n = v / 12;
  109.       n2 = v % 12;
  110.       v -= 17;
  111.       c2 = key[n2];
  112.       key[i] = c2;
  113.       key[n2] = c;
  114.    }
  115.    v2 = 0x13AC9741;
  116.    for (i = 11; i >= 0; i--)
  117.    {
  118.       c = toupper(key[i]);
  119.       key[i] = c;
  120.       if (c <= '7')
  121.       {
  122.          v = v2;
  123.          c2 = v & 0xFF;
  124.          c2 &= 7;
  125.          c2 ^= c;
  126.          v >>= 3;
  127.          key[i] = c2;
  128.          v2 = v;
  129.       }
  130.       else if (c < 'A')
  131.       {
  132.          c2 = (BYTE) i;
  133.          c2 &= 1;
  134.          c2 ^= c;
  135.          key[i] = c2;
  136.       }
  137.    }
  138.    return bValid;
  139. }
  140.  
  141. BOOL DecodeD2Key(LPSTR key)
  142. {
  143.    DWORD r, n, n2, v, v2, keyvalue;
  144.    BYTE c1, c2, c;
  145.    BOOL bValid;
  146.    int i;   
  147.  
  148.    r = 1;
  149.    keyvalue = 0;
  150.    for (i = 0; i < 16; i += 2)
  151.    {
  152.       c1 = codevalues[key[i]];
  153.       n = c1 * 3;
  154.       c2 = codevalues[key[i+1]];
  155.       n = c2 + n * 8;
  156.       if (n >= 0x100)
  157.       {
  158.          n -= 0x100;
  159.          keyvalue |= r;
  160.       }
  161.       n2 = n;
  162.       n2 >>= 4;
  163.       key[i] = Get_Hex_Value(n2);
  164.       key[i+1] = Get_Hex_Value(n);
  165.       r <<= 1;
  166.    }
  167.    v = 3;
  168.    for (i = 0; i < 16; i++)
  169.    {
  170.       c = key[i];
  171.       n = Get_Num_Value(c);
  172.       n2 = v * 2;
  173.       n ^= n2;
  174.       v += n;
  175.    }
  176.    v &= 0xFF;
  177.    if (v == keyvalue)
  178.       bValid = TRUE;
  179.    else
  180.       bValid = FALSE;
  181.    for (i = 15; i >= 0; i--)
  182.    {
  183.       c = key[i];
  184.       if (i > 8)
  185.          n = i - 9;
  186.       else
  187.          n = 0xF - (8 - i);
  188.       n &= 0xF;
  189.       c2 = key[n];
  190.       key[i] = c2;
  191.       key[n] = c;
  192.    }
  193.    v2 = 0x13AC9741;
  194.    for (i = 15; i >= 0; i--)
  195.    {
  196.       c = toupper(key[i]);
  197.       key[i] = c;
  198.       if (c <= '7')
  199.       {
  200.          v = v2;
  201.          c2 = v & 0xFF;
  202.          c2 &= 7;
  203.          c2 ^= c;
  204.          v >>= 3;
  205.          key[i] = c2;
  206.          v2 = v;
  207.       }
  208.       else if (c < 'A')
  209.       {
  210.          c2 = (BYTE) i;
  211.          c2 &= 1;
  212.          c2 ^= c;
  213.          key[i] = c2;
  214.       }
  215.    }
  216.    return bValid;
  217. }
  218.  
  219. char Get_Hex_Value(DWORD v)
  220. {
  221.    v &= 0xF;
  222.    if (v < 10)
  223.       return (v + 0x30);
  224.    else
  225.       return (v + 0x37);
  226. }
  227.  
  228. int Get_Num_Value(char c)
  229. {
  230.    c = toupper(c);
  231.    if (isdigit(c))
  232.       return (c - 0x30);
  233.    else
  234.       return (c - 0x37);
  235. }
  236.  
  237. void HashData(LPVOID lpSource, int nLength, LPVOID lpResult)
  238. {
  239.    BYTE bBuffer[1024];
  240.    int i;
  241.    DWORD a, b, c, d, e, g, * lpdwBuffer;
  242.  
  243.    ZeroMemory(bBuffer, 1024);
  244.    CopyMemory(bBuffer, lpSource, nLength);
  245.    lpdwBuffer = (LPDWORD) bBuffer;
  246.  
  247.    for (i=0; i<64; i++)
  248.       lpdwBuffer[i+16] = ROL(1, (lpdwBuffer[i] ^ lpdwBuffer[i+8] ^
  249.                              lpdwBuffer[i+2] ^ lpdwBuffer[i+13]) % 32);
  250.    a = 0x67452301lu;
  251.    b = 0xefcdab89lu;
  252.    c = 0x98badcfelu;
  253.    d = 0x10325476lu;
  254.    e = 0xc3d2e1f0lu;
  255.    for (i = 0; i < (20 * 1); i++)
  256.    {
  257.       g = lpdwBuffer[i] + ROL(a,5) + e + ((b & c) | (~b & d)) + 0x5a827999lu;
  258.       e = d;
  259.       d = c;
  260.       c = ROL(b,30);
  261.       b = a;
  262.       a = g;
  263.    }
  264.    for (; i < (20 * 2); i++)
  265.    {
  266.       g = (d ^ c ^ b) + e + ROL(g,5) + lpdwBuffer[i] + 0x6ed9eba1lu;
  267.       e = d;
  268.       d = c;
  269.       c = ROL(b,30);
  270.       b = a;
  271.       a = g;
  272.    }
  273.    for (; i < (20 * 3); i++)
  274.    {
  275.       g = lpdwBuffer[i] + ROL(g,5) + e + ((c & b) | (d & c) | (d & b)) -
  276.           0x70e44324lu;
  277.       e = d;
  278.       d = c;
  279.       c = ROL(b,30);
  280.       b = a;
  281.       a = g;
  282.    }
  283.    for (; i < (20 * 4); i++)
  284.    {
  285.       g = (d ^ c ^ b) + e + ROL(g,5) + lpdwBuffer[i] - 0x359d3e2alu;
  286.       e = d;
  287.       d = c;
  288.       c = ROL(b,30);
  289.       b = a;
  290.       a = g;
  291.    }
  292.  
  293.    lpdwBuffer = (LPDWORD) lpResult;
  294.    lpdwBuffer[0] = 0x67452301lu + g;
  295.    lpdwBuffer[1] = 0xefcdab89lu + b;
  296.    lpdwBuffer[2] = 0x98badcfelu + c;
  297.    lpdwBuffer[3] = 0x10325476lu + d;
  298.    lpdwBuffer[4] = 0xc3d2e1f0lu + e;
  299.    return TRUE;
  300. }