XPKeygen/key.cpp

114 lines
2.9 KiB
C++

//
// Created by Andrew on 09/04/2023.
//
#include "header.h"
/* Convert from byte sequence to the CD-key. */
void base24(char *cdKey, ul32 *byteSeq) {
byte rbs[16];
BIGNUM *z;
// Copy byte sequence to the reversed byte sequence.
memcpy(rbs, byteSeq, sizeof(rbs));
// Skip trailing zeroes and reverse y.
int length;
for (length = 15; rbs[length] == 0; length--);
endiannessConvert(rbs, ++length);
// Convert reversed byte sequence to BigNum z.
z = BN_bin2bn(rbs, length, nullptr);
// Divide z by 24 and convert the remainder to a CD-key char.
cdKey[25] = 0;
for (int i = 24; i >= 0; i--)
cdKey[i] = charset[BN_div_word(z, 24)];
BN_free(z);
}
/* Convert from CD-key to a byte sequence. */
void unbase24(ul32 *byteSeq, const char *cdKey) {
byte pDecodedKey[PK_LENGTH + NULL_TERMINATOR]{};
BIGNUM *y = BN_new();
BN_zero(y);
// Remove dashes from the CD-key and put it into a Base24 byte array.
for (int i = 0, k = 0; i < strlen(cdKey) && k < PK_LENGTH; i++) {
for (int j = 0; j < 24; j++) {
if (cdKey[i] != '-' && cdKey[i] == charset[j]) {
pDecodedKey[k++] = j;
break;
}
}
}
// Empty byte sequence.
memset(byteSeq, 0, 16);
// Calculate the weighed sum of byte array elements.
for (int i = 0; i < PK_LENGTH; i++) {
BN_mul_word(y, PK_LENGTH - 1);
BN_add_word(y, pDecodedKey[i]);
}
// Acquire length.
int n = BN_num_bytes(y);
// Place the generated code into the byte sequence.
BN_bn2bin(y, (byte *)byteSeq);
BN_free(y);
// Reverse the byte sequence.
endiannessConvert((byte *) byteSeq, n);
}
/* Print Product Key. */
void printProductKey(const char *pKey) {
assert(strlen(pKey) == 25);
SetConsoleTextAttribute(hConsole, 0x0A);
for (int i = 0; i < PK_LENGTH; i++) {
putchar(pKey[i]);
if (i != PK_LENGTH - 1 && i % 5 == 4) putchar('-');
}
SetConsoleTextAttribute(hConsole, 0x0F);
}
/* Print Product ID using a Product Key. */
void printProductID(const ul32 *pRaw) {
char raw[12];
char b[6], c[8];
// Cut away last bit of the product key and convert it to an ASCII-number (=raw)
sprintf(raw, "%09lu", pRaw[0] >> 1);
// Make B-part {...-640-...} -> most significant 3 digits of Raw Product Key
strncpy(b, raw, 3);
b[3] = 0;
// Make C-part {...-123456X-...} -> least significant 6 digits of Raw Product Key
strcpy(c, raw + 3);
int digit = 0;
// Reverse sum algorithm to find a check digit that would add to the rest to form a sum divisible by 7.
for (int i = 0; i < 6; i++)
digit -= c[i] - '0';
while (digit < 0)
digit += 7;
// Append check digit + null terminate.
c[6] = digit + '0';
c[7] = 0;
printf("Product ID: ");
cprintf("PPPPP-%s-%s-23XXX\n", 0x0E, b, c);
}