BINK1998 Upgrade Bit

This commit is contained in:
Andrew 2023-06-10 19:38:22 +03:00
parent f11552509a
commit d4d50d9885
5 changed files with 36 additions and 18 deletions

1
.idea/vcs.xml generated
View File

@ -2,6 +2,5 @@
<project version="4"> <project version="4">
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" /> <mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$/build/_deps/nlohmann_json-src" vcs="Git" />
</component> </component>
</project> </project>

View File

@ -7,6 +7,7 @@
/* Unpacks the Windows XP-like Product Key. */ /* Unpacks the Windows XP-like Product Key. */
void BINK1998::Unpack( void BINK1998::Unpack(
QWORD (&pRaw)[2], QWORD (&pRaw)[2],
BOOL &pUpgrade,
DWORD &pSerial, DWORD &pSerial,
DWORD &pHash, DWORD &pHash,
QWORD &pSignature QWORD &pSignature
@ -14,8 +15,11 @@ void BINK1998::Unpack(
// We're assuming that the quantity of information within the product key is at most 114 bits. // We're assuming that the quantity of information within the product key is at most 114 bits.
// log2(24^25) = 114. // log2(24^25) = 114.
// Serial = Bits [0..30] -> 31 bits // Upgrade = Bit 0
pSerial = FIRSTNBITS(pRaw[0], 31); pUpgrade = FIRSTNBITS(pRaw[0], 1);
// Serial = Bits [1..30] -> 30 bits
pSerial = NEXTSNBITS(pRaw[0], 30, 1);
// Hash = Bits [31..58] -> 28 bits // Hash = Bits [31..58] -> 28 bits
pHash = NEXTSNBITS(pRaw[0], 28, 31); pHash = NEXTSNBITS(pRaw[0], 28, 31);
@ -27,6 +31,7 @@ void BINK1998::Unpack(
/* Packs the Windows XP-like Product Key. */ /* Packs the Windows XP-like Product Key. */
void BINK1998::Pack( void BINK1998::Pack(
QWORD (&pRaw)[2], QWORD (&pRaw)[2],
BOOL pUpgrade,
DWORD pSerial, DWORD pSerial,
DWORD pHash, DWORD pHash,
QWORD pSignature QWORD pSignature
@ -36,7 +41,7 @@ void BINK1998::Pack(
// 64 * 2 = 128 // 64 * 2 = 128
// Signature [114..59] <- Hash [58..31] <- Serial [30..1] <- Upgrade [0] // Signature [114..59] <- Hash [58..31] <- Serial [30..1] <- Upgrade [0]
pRaw[0] = FIRSTNBITS(pSignature, 5) << 59 | FIRSTNBITS(pHash, 28) << 31 | pSerial; pRaw[0] = FIRSTNBITS(pSignature, 5) << 59 | FIRSTNBITS(pHash, 28) << 31 | pSerial << 1 | pUpgrade;
pRaw[1] = NEXTSNBITS(pSignature, 51, 5); pRaw[1] = NEXTSNBITS(pSignature, 51, 5);
} }
@ -50,16 +55,21 @@ bool BINK1998::Verify(
BN_CTX *numContext = BN_CTX_new(); BN_CTX *numContext = BN_CTX_new();
QWORD pRaw[2]{}, QWORD pRaw[2]{},
pSignature = 0; pSignature;
DWORD pSerial = 0, DWORD pData,
pHash = 0; pSerial,
pHash;
BOOL pUpgrade;
// Convert Base24 CD-key to bytecode. // Convert Base24 CD-key to bytecode.
unbase24((BYTE *)pRaw, pKey); unbase24((BYTE *)pRaw, pKey);
// Extract RPK, hash and signature from bytecode. // Extract RPK, hash and signature from bytecode.
Unpack(pRaw, pSerial, pHash, pSignature); Unpack(pRaw, pUpgrade, pSerial, pHash, pSignature);
pData = pSerial << 1 | pUpgrade;
/* /*
* *
@ -107,7 +117,7 @@ bool BINK1998::Verify(
BN_bn2lebin(y, yBin, FIELD_BYTES); BN_bn2lebin(y, yBin, FIELD_BYTES);
// Assemble the SHA message. // Assemble the SHA message.
memcpy((void *)&msgBuffer[0], (void *)&pSerial, 4); memcpy((void *)&msgBuffer[0], (void *)&pData, 4);
memcpy((void *)&msgBuffer[4], (void *)xBin, FIELD_BYTES); memcpy((void *)&msgBuffer[4], (void *)xBin, FIELD_BYTES);
memcpy((void *)&msgBuffer[4 + FIELD_BYTES], (void *)yBin, FIELD_BYTES); memcpy((void *)&msgBuffer[4 + FIELD_BYTES], (void *)yBin, FIELD_BYTES);
@ -139,6 +149,7 @@ void BINK1998::Generate(
BIGNUM *genOrder, BIGNUM *genOrder,
BIGNUM *privateKey, BIGNUM *privateKey,
DWORD pSerial, DWORD pSerial,
BOOL pUpgrade,
char (&pKey)[25] char (&pKey)[25]
) { ) {
BN_CTX *numContext = BN_CTX_new(); BN_CTX *numContext = BN_CTX_new();
@ -151,6 +162,9 @@ void BINK1998::Generate(
QWORD pRaw[2]{}, QWORD pRaw[2]{},
pSignature = 0; pSignature = 0;
// Data segment of the RPK.
DWORD pData = pSerial << 1 | pUpgrade;
do { do {
EC_POINT *r = EC_POINT_new(eCurve); EC_POINT *r = EC_POINT_new(eCurve);
@ -175,7 +189,7 @@ void BINK1998::Generate(
BN_bn2lebin(y, yBin, FIELD_BYTES); BN_bn2lebin(y, yBin, FIELD_BYTES);
// Assemble the SHA message. // Assemble the SHA message.
memcpy((void *)&msgBuffer[0], (void *)&pSerial, 4); memcpy((void *)&msgBuffer[0], (void *)&pData, 4);
memcpy((void *)&msgBuffer[4], (void *)xBin, FIELD_BYTES); memcpy((void *)&msgBuffer[4], (void *)xBin, FIELD_BYTES);
memcpy((void *)&msgBuffer[4 + FIELD_BYTES], (void *)yBin, FIELD_BYTES); memcpy((void *)&msgBuffer[4 + FIELD_BYTES], (void *)yBin, FIELD_BYTES);
@ -216,10 +230,11 @@ void BINK1998::Generate(
BN_bn2lebinpad(s, (BYTE *)&pSignature, BN_num_bytes(s)); BN_bn2lebinpad(s, (BYTE *)&pSignature, BN_num_bytes(s));
// Pack product key. // Pack product key.
Pack(pRaw, pSerial, pHash, pSignature); Pack(pRaw, pUpgrade, pSerial, pHash, pSignature);
if (options.verbose) { if (options.verbose) {
fmt::print("Generation results:\n"); fmt::print("Generation results:\n");
fmt::print(" Upgrade: 0x{:08x}\n", pUpgrade);
fmt::print(" Serial: 0x{:08x}\n", pSerial); fmt::print(" Serial: 0x{:08x}\n", pSerial);
fmt::print(" Hash: 0x{:08x}\n", pHash); fmt::print(" Hash: 0x{:08x}\n", pHash);
fmt::print(" Signature: 0x{:08x}\n", pSignature); fmt::print(" Signature: 0x{:08x}\n", pSignature);

View File

@ -10,12 +10,14 @@
class BINK1998 { class BINK1998 {
static void Unpack( static void Unpack(
QWORD (&pRaw)[2], QWORD (&pRaw)[2],
BOOL &pUpgrade,
DWORD &pSerial, DWORD &pSerial,
DWORD &pHash, DWORD &pHash,
QWORD &pSignature QWORD &pSignature
); );
static void Pack( static void Pack(
QWORD (&pRaw)[2], QWORD (&pRaw)[2],
BOOL pUpgrade,
DWORD pSerial, DWORD pSerial,
DWORD pHash, DWORD pHash,
QWORD pSignature QWORD pSignature
@ -34,6 +36,7 @@ public:
BIGNUM *genOrder, BIGNUM *genOrder,
BIGNUM *privateKey, BIGNUM *privateKey,
DWORD pSerial, DWORD pSerial,
BOOL pUpgrade,
char (&pKey)[25] char (&pKey)[25]
); );
}; };

View File

@ -270,7 +270,7 @@ int CLI::BINK1998() {
char *cRaw = BN_bn2dec(bnrand); char *cRaw = BN_bn2dec(bnrand);
sscanf(cRaw, "%d", &oRaw); sscanf(cRaw, "%d", &oRaw);
nRaw += (oRaw &= 0xF423F); // ensure our serial is less than 999999 nRaw += (oRaw % 999999); // ensure our serial is less than 999999
if (options.verbose) { if (options.verbose) {
fmt::print("> PID: {:09d}\n", nRaw); fmt::print("> PID: {:09d}\n", nRaw);
@ -278,10 +278,12 @@ int CLI::BINK1998() {
// generate a key // generate a key
BN_sub(privateKey, genOrder, privateKey); BN_sub(privateKey, genOrder, privateKey);
nRaw <<= 1;
// Specify whether an upgrade version or not
bool bUpgrade = false;
for (int i = 0; i < total; i++) { for (int i = 0; i < total; i++) {
BINK1998::Generate(eCurve, genPoint, genOrder, privateKey, nRaw, pKey); BINK1998::Generate(eCurve, genPoint, genOrder, privateKey, nRaw, bUpgrade, pKey);
CLI::print_product_key(pKey); CLI::print_product_key(pKey);
fmt::print("\n\n"); fmt::print("\n\n");
@ -304,7 +306,7 @@ int CLI::BINK2002() {
for (int i = 0; i < total; i++) { for (int i = 0; i < total; i++) {
DWORD pAuthInfo; DWORD pAuthInfo;
RAND_bytes((BYTE *)&pAuthInfo, 4); RAND_bytes((BYTE *)&pAuthInfo, 4);
pAuthInfo &= 0x3ff; pAuthInfo &= BITMASK(10);
if (options.verbose) { if (options.verbose) {
fmt::print("> AuthInfo: {}\n", pAuthInfo); fmt::print("> AuthInfo: {}\n", pAuthInfo);

View File

@ -77,10 +77,8 @@ struct Options {
MODE applicationMode; MODE applicationMode;
}; };
extern Options options;
// Type definitions // Type definitions
typedef bool BOOL; typedef uint32_t BOOL;
typedef uint8_t BYTE; typedef uint8_t BYTE;
typedef uint16_t WORD; typedef uint16_t WORD;
typedef uint32_t DWORD; typedef uint32_t DWORD;
@ -91,6 +89,7 @@ typedef unsigned __int128 OWORD;
#endif #endif
// Global variables // Global variables
extern Options options;
// util.cpp // util.cpp
int BN_bn2lebin(const BIGNUM *a, unsigned char *to, int tolen); // Hello OpenSSL developers, please tell me, where is this function at? int BN_bn2lebin(const BIGNUM *a, unsigned char *to, int tolen); // Hello OpenSSL developers, please tell me, where is this function at?