Created
June 25, 2023 11:54
-
-
Save shibajee/566f981049ec95eb2353736f1ba1cc61 to your computer and use it in GitHub Desktop.
Creative Sound Blaster Legacy Product Activation Source Code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <mbedtls/des.h> | |
#include <mbedtls/md5.h> | |
#include <stdio.h> | |
#include <Windows.h> | |
#include <IPHlpApi.h> | |
#include <ShlObj.h> | |
#include <Shlwapi.h> | |
#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[] = "deadbeef000000000000000000000000"; | |
struct KeyNamePair | |
{ | |
const char * key; | |
const char * name; | |
}; | |
KeyNamePair knp[] = | |
{ | |
{ "LA56KHYE", "CTLT99HB0X.kga" }, | |
{ "S3MP42XB", "CTLT46HL1X.kga" }, | |
{ "KYE08ZY3", "CTLT72HL2X.kga" }, | |
{ "A31OKL25", "CTLT11HL3X.kga" }, | |
{ "6K5YEHLA", "CTLT47H9X2.kga" }, // | |
{ "PX432SBM", "CTLT21H1X2.kga" }, // | |
{ "ZKY03YE8", "CTLT02H0X2.kga" }, // | |
{ "OKLA2153", "CTLTD2H3X2.kga" }, // | |
{ "NH5L2P13", "CTLT9SJDX2.kga" }, // | |
{ "BDC5687E", "CTLXS2Q3X2.kga" }, // | |
{ "23A3693F", "CTLO3H65X2.kga" }, // | |
{ "OAMDWHRH", "CTLMN34SX2.kga" }, // | |
{ "OTRTTRTR", "CTLNBK2HX2.kga" }, // | |
{ "OARPTNDH", "CTLLAS4HX2.kga" }, // | |
{ "OMNPMHHH", "CTLPS4HTX2.kga" }, //! | |
{ "AKSMRTSD", "CTLI37CVX2.kga" }, // | |
{ "F1GY89SE", "CTLUE8XYX2.kga" }, // | |
{ "L3IUZSK3", "CTLS2SR4X2.kga" }, // | |
{ "JH578SAA", "CTLT53HURX.kga" }, | |
{ "LWR232SZ", "CTD5H2W3DK.kga" }, | |
{ "XR2AG82P", "CTD1JXF23A.kga" }, //* | |
{ "P23DSU4S", "CTT78HSK12.kga" }, | |
{ "P32LUD17", "CTT92KD23N.kga" }, | |
{ "X34DSL1S", "CTD3SPO23G.kga" }, | |
{ "ZL00SEW3", "CTLE2C3BA1.kga" }, | |
{ "H34T2GW2", "CTH6K23AS7.kga" }, | |
{ "BX32DNEK", "CTA30CF234.kga" }, // | |
{ "6BDF7E41", "CTA200FF2D.kga" }, // | |
{ "J8K23NM2", "CTAE90C24A.kga" }, // | |
{ "IH68ULK0", "CTLD2JX234.kga" }, // | |
{ "K53SFR23", "CTLD14KLI5.kga" }, // | |
{ "LQW341ME", "CTL42SW23M.kga" }, // | |
{ "M21PWSZ0", "CTLP22SV21.kga" }, // | |
{ "GN3E92V4", "CTLA20RVB5.kga" }, //* | |
{ "R260D5PX", "CTL34AF61R.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) { | |
if (adap->Type == MIB_IF_TYPE_ETHERNET) { | |
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->Type == MIB_IF_TYPE_ETHERNET) { | |
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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment