Fix datatypes to use platform independent values, Add command line switch scaffolding
Allow users to chose which bink/channelid they'd like to generate with Add rudimentary help system, Sanitize user input
This commit is contained in:
36
src/xp.cpp
36
src/xp.cpp
@@ -18,7 +18,7 @@
|
||||
#include "header.h"
|
||||
|
||||
/* Unpacks the Windows XP Product Key. */
|
||||
void unpackXP(ul32 *serial, ul32 *hash, ul32 *sig, ul32 *raw) {
|
||||
void unpackXP(uint32_t *serial, uint32_t *hash, uint32_t *sig, uint32_t *raw) {
|
||||
|
||||
// We're assuming that the quantity of information within the product key is at most 114 bits.
|
||||
// log2(24^25) = 114.
|
||||
@@ -39,7 +39,7 @@ void unpackXP(ul32 *serial, ul32 *hash, ul32 *sig, ul32 *raw) {
|
||||
}
|
||||
|
||||
/* Packs the Windows XP Product Key. */
|
||||
void packXP(ul32 *raw, const ul32 *serial, const ul32 *hash, const ul32 *sig) {
|
||||
void packXP(uint32_t *raw, const uint32_t *serial, const uint32_t *hash, const uint32_t *sig) {
|
||||
raw[0] = serial[0] | ((hash[0] & 1) << 31);
|
||||
raw[1] = (hash[0] >> 1) | ((sig[0] & 0x1f) << 27);
|
||||
raw[2] = (sig[0] >> 5) | (sig[1] << 27);
|
||||
@@ -51,8 +51,8 @@ bool verifyXPKey(EC_GROUP *eCurve, EC_POINT *generator, EC_POINT *publicKey, cha
|
||||
BN_CTX *context = BN_CTX_new();
|
||||
|
||||
// Convert Base24 CD-key to bytecode.
|
||||
ul32 bKey[4]{};
|
||||
ul32 pID, checkHash, sig[2];
|
||||
uint32_t bKey[4]{};
|
||||
uint32_t pID, checkHash, sig[2];
|
||||
|
||||
unbase24(bKey, cdKey);
|
||||
|
||||
@@ -68,8 +68,8 @@ bool verifyXPKey(EC_GROUP *eCurve, EC_POINT *generator, EC_POINT *publicKey, cha
|
||||
BN_set_word(e, checkHash);
|
||||
|
||||
// Reverse signature and create a new BigNum s.
|
||||
endian((byte *)sig, sizeof(sig));
|
||||
s = BN_bin2bn((byte *)sig, sizeof(sig), nullptr);
|
||||
endian((uint8_t *)sig, sizeof(sig));
|
||||
s = BN_bin2bn((uint8_t *)sig, sizeof(sig), nullptr);
|
||||
|
||||
// Create x and y.
|
||||
BIGNUM *x = BN_new();
|
||||
@@ -95,8 +95,8 @@ bool verifyXPKey(EC_GROUP *eCurve, EC_POINT *generator, EC_POINT *publicKey, cha
|
||||
// x = v.x; y = v.y;
|
||||
EC_POINT_get_affine_coordinates(eCurve, v, x, y, context);
|
||||
|
||||
byte buf[FIELD_BYTES], md[SHA_DIGEST_LENGTH], t[4];
|
||||
ul32 newHash;
|
||||
uint8_t buf[FIELD_BYTES], md[SHA_DIGEST_LENGTH], t[4];
|
||||
uint32_t newHash;
|
||||
|
||||
SHA_CTX hContext;
|
||||
|
||||
@@ -150,7 +150,7 @@ bool verifyXPKey(EC_GROUP *eCurve, EC_POINT *generator, EC_POINT *publicKey, cha
|
||||
}
|
||||
|
||||
/* Generate a valid Product Key. */
|
||||
void generateXPKey(char *pKey, EC_GROUP *eCurve, EC_POINT *generator, BIGNUM *order, BIGNUM *privateKey, ul32 *pRaw) {
|
||||
void generateXPKey(char *pKey, EC_GROUP *eCurve, EC_POINT *generator, BIGNUM *order, BIGNUM *privateKey, uint32_t *pRaw) {
|
||||
EC_POINT *r = EC_POINT_new(eCurve);
|
||||
BN_CTX *ctx = BN_CTX_new();
|
||||
|
||||
@@ -159,10 +159,10 @@ void generateXPKey(char *pKey, EC_GROUP *eCurve, EC_POINT *generator, BIGNUM *or
|
||||
BIGNUM *x = BN_new();
|
||||
BIGNUM *y = BN_new();
|
||||
|
||||
ul32 bKey[4]{};
|
||||
uint32_t bKey[4]{};
|
||||
|
||||
do {
|
||||
ul32 hash = 0, sig[2]{};
|
||||
uint32_t hash = 0, sig[2]{};
|
||||
|
||||
memset(bKey, 0, 4);
|
||||
|
||||
@@ -176,7 +176,7 @@ void generateXPKey(char *pKey, EC_GROUP *eCurve, EC_POINT *generator, BIGNUM *or
|
||||
EC_POINT_get_affine_coordinates(eCurve, r, x, y, ctx);
|
||||
|
||||
SHA_CTX hContext;
|
||||
byte md[SHA_DIGEST_LENGTH]{}, buf[FIELD_BYTES]{}, t[4]{};
|
||||
uint8_t md[SHA_DIGEST_LENGTH]{}, buf[FIELD_BYTES]{}, t[4]{};
|
||||
|
||||
// h = (First-32(SHA1(pRaw, r.x, r.y)) >> 4
|
||||
SHA1_Init(&hContext);
|
||||
@@ -225,13 +225,19 @@ void generateXPKey(char *pKey, EC_GROUP *eCurve, EC_POINT *generator, BIGNUM *or
|
||||
BN_mod_add(s, s, c, order, ctx);
|
||||
|
||||
// Convert s from BigNum back to bytecode and reverse the endianness.
|
||||
BN_bn2bin(s, (byte *)sig);
|
||||
endian((byte *)sig, BN_num_bytes(s));
|
||||
BN_bn2bin(s, (uint8_t *)sig);
|
||||
endian((uint8_t *)sig, BN_num_bytes(s));
|
||||
|
||||
// Pack product key.
|
||||
packXP(bKey, pRaw, &hash, sig);
|
||||
|
||||
printf("PID: %.8X\nHash: %.8X\nSig: %.8X %.8X\n", pRaw[0], hash, sig[1], sig[0]);
|
||||
//printf("PID: %.8X\nHash: %.8X\nSig: %.8X %.8X\n", pRaw[0], hash, sig[1], sig[0]);
|
||||
std::cout << " PID: " << std::hex << std::setw(8) << std::setfill('0') << pRaw[0] << std::endl
|
||||
<< "Hash: " << std::hex << std::setw(8) << std::setfill('0') << hash << std::endl
|
||||
<< " Sig: " << std::hex << std::setw(8) << std::setfill('0') << sig[1] << " "
|
||||
<< std::hex << std::setw(8) << std::setfill('0') << sig[2] << std::endl
|
||||
<< std::endl;
|
||||
|
||||
} while (bKey[3] >= 0x40000);
|
||||
// ↑ ↑ ↑
|
||||
// bKey[3] can't be longer than 18 bits, else the signature part will make
|
||||
|
||||
Reference in New Issue
Block a user