#include #include #include #include #include #include #include #define TRACE 0 /* In place DSA-ECB encryption */ void encryptData(const unsigned char *key, unsigned char *msg, size_t len) { mbedtls_des_context ctx; mbedtls_des_init(&ctx); while (len >= 8) { mbedtls_des_setkey_enc(&ctx, key); mbedtls_des_crypt_ecb(&ctx, msg, msg); msg += 8; len -= 8; } #if TRACE if (len) printf("encryptData: Skipping last %d bytes.\n"); #endif mbedtls_des_free(&ctx); } /* In place DSA-ECB decryption */ void decryptData(const unsigned char *key, unsigned char *msg, size_t len) { mbedtls_des_context ctx; mbedtls_des_init(&ctx); while (len >= 8) { mbedtls_des_setkey_enc(&ctx, key); mbedtls_des_crypt_ecb(&ctx, msg, msg); msg += 8; len -= 8; } #if TRACE if (len) printf("decryptData: Skipping last %d bytes.\n"); #endif mbedtls_des_free(&ctx); } /* MAC address MD5 hash */ void hashMACAddress(const BYTE *msg, size_t len, BYTE *out) { unsigned char tmp[16]; char *buf; if (msg == NULL || !len || out == NULL) return; buf = (char *)malloc(3 * len); sprintf(buf, "%02X", msg[0]); for (size_t i = 1; i < len; i++) sprintf(buf + 2 + 3 * (i - 1), "-%02X", msg[i]); #if TRACE printf("Hashing interface %s\n", buf); #endif mbedtls_md5((unsigned char *)buf, 3 * len - 1, tmp); for (size_t i = 0; i < 16; i++) { sprintf(buf, "%02x", tmp[i]); out[2 * i] = buf[0]; out[2 * i + 1] = buf[1]; } #if TRACE printf("MD5 hash %.32s\n", out); #endif free(buf); } /* Volume serial MD5 hash */ void hashVolumeSerial(DWORD msg, BYTE *out) { unsigned char tmp[16]; char buf[9]; int i; sprintf(buf, "%08X", msg); #if TRACE printf("Hashing volume %s\n", buf); #endif mbedtls_md5((unsigned char *)buf, 8, tmp); for (i = 0; i < 16; i++) { sprintf(buf, "%02x", tmp[i]); out[2 * i] = buf[0]; out[2 * i + 1] = buf[1]; } #if TRACE printf("MD5 hash %.32s\n", out); #endif } /* System time MD5 hash */ void hashSystemTime(SYSTEMTIME *msg, BYTE *out) { unsigned char tmp[16]; char buf[9]; int i; sprintf(buf, "%04d%02d%02d", msg->wYear, msg->wMonth, msg->wDay); #if TRACE printf("Hashing time %s\n", buf); #endif mbedtls_md5((unsigned char *)buf, 8, tmp); for (i = 0; i < 16; i++) { sprintf(buf, "%02x", tmp[i]); out[2 * i] = buf[0]; out[2 * i + 1] = buf[1]; } #if TRACE printf("MD5 hash %.32s\n", out); #endif } const BYTE terminator[] = "\x00\xff\xff\xff\xff\xff\xff\xff"; // unknown purpose, but needs to be unique const BYTE unknown[] = "deadbeef2c2351e0b9e80029c909242d"; struct KeyNamePair { const char * key; const char * name; }; KeyNamePair knp[] = { { "LA56KHYE", "CTLT99HB0X.kga" }, { "S3MP42XB", "CTLT46HL1X.kga" }, { "A31OKL25", "CTLT11HL3X.kga" }, { "6K5YEHLA", "CTLT47H9X2.kga" }, // { "PX432SBM", "CTLT21H1X2.kga" }, // { "OKLA2153", "CTLTD2H3X2.kga" }, // { "NH5L2P13", "CTLT9SJDX2.kga" }, // { "BDC5687E", "CTLXS2Q3X2.kga" }, // { "23A3693F", "CTLO3H65X2.kga" }, // { "OAMDWHRH", "CTLMN34SX2.kga" }, // { "OTRTTRTR", "CTLNBK2HX2.kga" }, // { "OARPTNDH", "CTLLAS4HX2.kga" }, // { "MMONPHHH", "CTLPS4HTX2.kga" }, // { "AKSMRTSD", "CTLI37CVX2.kga" }, // { "F1GY89SE", "CTLUE8XYX2.kga" }, // { "L3IUZSK3", "CTLS2SR4X2.kga" }, // { "JH578SAA", "CTLT53HURX.kga" }, { "LWR232SZ", "CTD5H2W3DK.kga" }, { "XR2AG82P", "CTD1JXF23A.kga" }, //* { "P23DSU4S", "CTT78HSK12.kga" }, { "X34DSL1S", "CTD3SPO23G.kga" }, { "P32LUD17", "CTT92KD23N.kga" }, { "ZL00SEW3", "CTLE2C3BA1.kga" }, { "H34T2GW2", "CTH6K23AS7.kga" }, { "6BDF7E41", "CTA200FF2D.kga" }, // { "BX32DNEK", "CTA30CF234.kga" }, // { "J8K23NM2", "CTAE90C24A.kga" }, // { "IH68ULK0", "CTLD2JX234.kga" }, // { "GN3E92V4", "CTLA20RVB5.kga" }, //* { "M21PWSZ0", "CTLP22SV21.kga" }, // { "LQW341ME", "CTL42SW23M.kga" }, // { "K53SFR23", "CTLD14KLI5.kga" }, // { "R260D5PX", "CTL34AF61R.kga" }, // { "ZKY03YE8", "CTLT02H0X2.kga" }, // { "KYE08ZY3", "CTLT72HL2X.kga" }, }; void GenKga(const char * key, const char * filename) { DWORD ret, adapterCount, hashCount, volumeSerial; ULONG len; PIP_ADAPTER_INFO adapters, adap; PBYTE hashes, hash; CHAR buf[256]; INT drive; SYSTEMTIME time; FILE *file; printf("Generating %s\n", filename); adapterCount = 1; len = adapterCount * sizeof(IP_ADAPTER_INFO); adapters = (PIP_ADAPTER_INFO)malloc(len); if ((ret = GetAdaptersInfo(adapters, &len)) == ERROR_BUFFER_OVERFLOW) adapters = (PIP_ADAPTER_INFO)realloc(adapters, len); if (GetAdaptersInfo(adapters, &len) != NO_ERROR) { fprintf(stderr, "GetAdapterInfo failed, aborting.\n"); free(adapters); exit(1); } adapterCount = 0; adap = adapters; while (adap) { adapterCount++; adap = adap->Next; } #if TRACE printf("Adapter count: %d\n", adapterCount); #endif hashCount = adapterCount + 3; hash = hashes = (PBYTE)malloc((32 * hashCount) + 8); adap = adapters; while (adap) { if (adap->AddressLength) { hashMACAddress(adap->Address, adap->AddressLength, hash); hash += 32; } else { hashCount--; } adap = adap->Next; } free(adapters); GetSystemDirectory(buf, 256); drive = PathGetDriveNumber(buf); sprintf(buf, "%C:\\", 'A' + drive); GetVolumeInformation(buf, NULL, 0, &volumeSerial, NULL, NULL, NULL, 0); hashVolumeSerial(volumeSerial, hash); hash += 32; memcpy(hash, unknown, 32); hash += 32; GetSystemTime(&time); hashSystemTime(&time, hash); hash += 32; memcpy(hash, terminator, 8); encryptData((unsigned char *)key, (unsigned char *)hashes, (32 * hashCount) + 8); file = fopen(filename, "wb+"); fwrite(hashes, (32 * hashCount) + 8, 1, file); fclose(file); free(hashes); #if TRACE printf("\n"); #endif } int main(int argc, char *argv[]) { char szPath[MAX_PATH]; if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, szPath))) { strcat_s(szPath, "\\Creative\\SoftwareLock"); int error = SHCreateDirectoryExA(NULL, szPath, NULL); if (error == ERROR_SUCCESS || error == ERROR_FILE_EXISTS || error == ERROR_ALREADY_EXISTS) SetCurrentDirectoryA(szPath); ZeroMemory(szPath, sizeof(szPath)); } GetCurrentDirectoryA(MAX_PATH, szPath); printf("%s\n", szPath); for (int i = 0; i < sizeof(knp) / sizeof(KeyNamePair); i++) { GenKga(knp[i].key, knp[i].name); } return 0; }