mirror of
https://github.com/Neo-Desktop/WindowsXPKg
synced 2024-12-22 20:40:16 +02:00
use fmt.dev's fmt::print functions, factor out command line functions from main to cli.cpp
This commit is contained in:
parent
29465ffb37
commit
cd3cc31cd6
@ -19,18 +19,20 @@ CPMAddPackage(
|
|||||||
VERSION 3.11.2
|
VERSION 3.11.2
|
||||||
)
|
)
|
||||||
|
|
||||||
|
CPMAddPackage("gh:fmtlib/fmt#7.1.3")
|
||||||
|
|
||||||
CONFIGURE_FILE(keys.json keys.json COPYONLY)
|
CONFIGURE_FILE(keys.json keys.json COPYONLY)
|
||||||
|
|
||||||
#SET(BUILD_SHARED_LIBS OFF)
|
#SET(BUILD_SHARED_LIBS OFF)
|
||||||
#SET(CMAKE_EXE_LINKER_FLAGS "-static")
|
#SET(CMAKE_EXE_LINKER_FLAGS "-static")
|
||||||
ADD_EXECUTABLE(xpkey src/main.cpp src/xp.cpp src/key.cpp src/util.cpp src/cli.cpp)
|
ADD_EXECUTABLE(xpkey src/main.cpp src/xp.cpp src/key.cpp src/util.cpp src/cli.cpp)
|
||||||
TARGET_INCLUDE_DIRECTORIES(xpkey PUBLIC crypto)
|
TARGET_INCLUDE_DIRECTORIES(xpkey PUBLIC crypto)
|
||||||
TARGET_LINK_LIBRARIES(xpkey PUBLIC OpenSSL::Crypto nlohmann_json::nlohmann_json)
|
TARGET_LINK_LIBRARIES(xpkey PUBLIC OpenSSL::Crypto nlohmann_json::nlohmann_json fmt)
|
||||||
|
|
||||||
ADD_EXECUTABLE(srv2003key src/server.cpp src/key.cpp src/util.cpp src/cli.cpp)
|
ADD_EXECUTABLE(srv2003key src/server.cpp src/key.cpp src/util.cpp src/cli.cpp)
|
||||||
TARGET_INCLUDE_DIRECTORIES(srv2003key PUBLIC crypto)
|
TARGET_INCLUDE_DIRECTORIES(srv2003key PUBLIC crypto)
|
||||||
TARGET_LINK_LIBRARIES(srv2003key PUBLIC OpenSSL::Crypto nlohmann_json::nlohmann_json)
|
TARGET_LINK_LIBRARIES(srv2003key PUBLIC OpenSSL::Crypto nlohmann_json::nlohmann_json fmt)
|
||||||
|
|
||||||
ADD_EXECUTABLE(xpactivate src/confid.cpp)
|
ADD_EXECUTABLE(xpactivate src/confid.cpp)
|
||||||
TARGET_INCLUDE_DIRECTORIES(xpactivate PUBLIC crypto)
|
TARGET_INCLUDE_DIRECTORIES(xpactivate PUBLIC crypto)
|
||||||
TARGET_LINK_LIBRARIES(xpactivate PUBLIC OpenSSL::Crypto nlohmann_json::nlohmann_json)
|
TARGET_LINK_LIBRARIES(xpactivate PUBLIC OpenSSL::Crypto nlohmann_json::nlohmann_json fmt)
|
127
src/cli.cpp
127
src/cli.cpp
@ -4,20 +4,36 @@
|
|||||||
|
|
||||||
#include "header.h"
|
#include "header.h"
|
||||||
|
|
||||||
void showHelp(char *argv[]) {
|
bool loadJSON(const fs::path& filename, json *output) {
|
||||||
std::cout << "usage: " << argv[0] << std::endl << std::endl
|
if (!fs::exists(filename)) {
|
||||||
<< "\t-h --help\tshow this message" << std::endl
|
fmt::print("{} does not exist", filename.string());
|
||||||
<< "\t-v --verbose\tenable verbose output" << std::endl
|
return false;
|
||||||
<< "\t-b --binkid\tspecify which BINK identifier to load (defaults to 2E)" << std::endl
|
}
|
||||||
<< "\t-l --list\tshow which products/binks can be loaded" << std::endl
|
|
||||||
<< "\t-c --channelid\tspecify which Channel Identifier to use (defaults to 640)" << std::endl
|
std::ifstream f(filename);
|
||||||
<< std::endl << std::endl;
|
*output = json::parse(f);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Options parseCommandLine(int argc, char* argv[]) {
|
|
||||||
Options options = {
|
void showHelp(char *argv[]) {
|
||||||
|
fmt::print("usage: {} \n", argv[0]);
|
||||||
|
fmt::print("\t-h --help\tshow this message\n");
|
||||||
|
fmt::print("\t-v --verbose\tenable verbose output\n");
|
||||||
|
fmt::print("\t-f --file\tspecify which keys file to load (defaults to keys.json)\n");
|
||||||
|
fmt::print("\t-b --binkid\tspecify which BINK identifier to load (defaults to 2E)\n");
|
||||||
|
fmt::print("\t-l --list\tshow which products/binks can be loaded\n");
|
||||||
|
fmt::print("\t-c --channelid\tspecify which Channel Identifier to use (defaults to 640)\n");
|
||||||
|
fmt::print("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int parseCommandLine(int argc, char* argv[], Options* options) {
|
||||||
|
// set default options
|
||||||
|
*options = Options {
|
||||||
"2E",
|
"2E",
|
||||||
640,
|
640,
|
||||||
|
"keys.json",
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false
|
false
|
||||||
@ -27,28 +43,84 @@ Options parseCommandLine(int argc, char* argv[]) {
|
|||||||
std::string arg = argv[i];
|
std::string arg = argv[i];
|
||||||
|
|
||||||
if (arg == "-v" || arg == "--verbose") {
|
if (arg == "-v" || arg == "--verbose") {
|
||||||
options.verbose = true;
|
options->verbose = true;
|
||||||
} else if (arg == "-h" || arg == "--help") {
|
} else if (arg == "-h" || arg == "--help") {
|
||||||
options.help = true;
|
options->help = true;
|
||||||
} else if (arg == "-b" || arg == "--bink") {
|
} else if (arg == "-b" || arg == "--bink") {
|
||||||
options.binkid = argv[i+1];
|
options->binkid = argv[i+1];
|
||||||
i++;
|
i++;
|
||||||
} else if (arg == "-l" || arg == "--list") {
|
} else if (arg == "-l" || arg == "--list") {
|
||||||
options.list = true;
|
options->list = true;
|
||||||
} else if (arg == "-c" || arg == "--channelid") {
|
} else if (arg == "-c" || arg == "--channelid") {
|
||||||
int siteID;
|
int siteID;
|
||||||
if (!sscanf(argv[i+1], "%d", &siteID)) {
|
if (!sscanf(argv[i+1], "%d", &siteID)) {
|
||||||
options.error = true;
|
options->error = true;
|
||||||
} else {
|
} else {
|
||||||
options.channelID = siteID;
|
options->channelID = siteID;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
} else if (arg == "-f" || arg == "--file") {
|
||||||
|
options->keysFilename = argv[i+1];
|
||||||
|
i++;
|
||||||
} else {
|
} else {
|
||||||
options.error = true;
|
options->error = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return options;
|
return !options->error;
|
||||||
|
}
|
||||||
|
|
||||||
|
int validateCommandLine(Options* options, char *argv[], json *keys) {
|
||||||
|
if (options->help || options->error) {
|
||||||
|
if (options->error) {
|
||||||
|
fmt::print("error parsing command line options\n");
|
||||||
|
}
|
||||||
|
showHelp(argv);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options->verbose) {
|
||||||
|
fmt::print("loading {}\n", options->keysFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!loadJSON(options->keysFilename, keys)) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options->verbose) {
|
||||||
|
fmt::print("loaded {} successfully\n",options->keysFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options->list) {
|
||||||
|
for (auto el : (*keys)["Products"].items()) {
|
||||||
|
int id;
|
||||||
|
sscanf((el.value()["BINK"][0]).get<std::string>().c_str(), "%x", &id);
|
||||||
|
if (id >= 0x50) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::cout << el.key() << ": " << el.value()["BINK"] << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt::print("\n\n");
|
||||||
|
fmt::print("** Please note: any BINK ID other than 2E is considered experimental at this time **\n");
|
||||||
|
fmt::print("\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int intBinkID;
|
||||||
|
sscanf(options->binkid.c_str(), "%x", &intBinkID);
|
||||||
|
|
||||||
|
if (intBinkID >= 0x50) {
|
||||||
|
std::cout << "ERROR: BINK2002 and beyond is not supported in this application at this time" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options->channelID > 999) {
|
||||||
|
std::cout << "ERROR: refusing to create a key with a siteID greater than 999" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_product_id(DWORD *pid)
|
void print_product_id(DWORD *pid)
|
||||||
@ -57,7 +129,7 @@ void print_product_id(DWORD *pid)
|
|||||||
char b[6], c[8];
|
char b[6], c[8];
|
||||||
int i, digit = 0;
|
int i, digit = 0;
|
||||||
|
|
||||||
// Cut a away last bit of pid and convert it to an accii-number (=raw)
|
// Cut away last bit of pid and convert it to an accii-number (=raw)
|
||||||
sprintf(raw, "%iu", pid[0] >> 1);
|
sprintf(raw, "%iu", pid[0] >> 1);
|
||||||
|
|
||||||
// Make b-part {640-....}
|
// Make b-part {640-....}
|
||||||
@ -66,7 +138,7 @@ void print_product_id(DWORD *pid)
|
|||||||
|
|
||||||
// Make c-part {...-123456X...}
|
// Make c-part {...-123456X...}
|
||||||
strcpy(c, raw + 3);
|
strcpy(c, raw + 3);
|
||||||
printf("> %s\n", c);
|
fmt::print("> {}\n", c);
|
||||||
|
|
||||||
// Make checksum digit-part {...56X-}
|
// Make checksum digit-part {...56X-}
|
||||||
assert(strlen(c) == 6);
|
assert(strlen(c) == 6);
|
||||||
@ -78,14 +150,17 @@ void print_product_id(DWORD *pid)
|
|||||||
c[6] = digit + '0';
|
c[6] = digit + '0';
|
||||||
c[7] = 0;
|
c[7] = 0;
|
||||||
|
|
||||||
printf("Product ID: PPPPP-%s-%s-23xxx\n", b, c);
|
fmt::print("Product ID: PPPPP-{}-{}-23xxx\n", b, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_product_key(char *pk) {
|
void print_product_key(char *pk) {
|
||||||
int i;
|
|
||||||
assert(strlen(pk) == 25);
|
assert(strlen(pk) == 25);
|
||||||
for (i = 0; i < 25; i++) {
|
|
||||||
putchar(pk[i]);
|
std::string spk = pk;
|
||||||
if (i != 24 && i % 5 == 4) putchar('-');
|
fmt::print("{}-{}-{}-{}-{}",
|
||||||
}
|
spk.substr(0,5),
|
||||||
|
spk.substr(5,5),
|
||||||
|
spk.substr(10,5),
|
||||||
|
spk.substr(15,5),
|
||||||
|
spk.substr(20,5));
|
||||||
}
|
}
|
12
src/header.h
12
src/header.h
@ -19,10 +19,12 @@
|
|||||||
#include <random>
|
#include <random>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <filesystem>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include <fmt/core.h>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
@ -52,6 +54,9 @@
|
|||||||
#define BYDWORD(n) (DWORD)(*((n) + 0) | *((n) + 1) << 8 | *((n) + 2) << 16 | *((n) + 3) << 24)
|
#define BYDWORD(n) (DWORD)(*((n) + 0) | *((n) + 1) << 8 | *((n) + 2) << 16 | *((n) + 3) << 24)
|
||||||
#define BITMASK(n) ((1ULL << (n)) - 1)
|
#define BITMASK(n) ((1ULL << (n)) - 1)
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
// Confirmation ID generator constants
|
// Confirmation ID generator constants
|
||||||
#define SUCCESS 0
|
#define SUCCESS 0
|
||||||
#define ERR_TOO_SHORT 1
|
#define ERR_TOO_SHORT 1
|
||||||
@ -98,14 +103,17 @@ void print_product_id(DWORD *pid);
|
|||||||
struct Options {
|
struct Options {
|
||||||
std::string binkid;
|
std::string binkid;
|
||||||
int channelID;
|
int channelID;
|
||||||
|
std::string keysFilename;
|
||||||
bool verbose;
|
bool verbose;
|
||||||
bool help;
|
bool help;
|
||||||
bool list;
|
bool list;
|
||||||
bool error;
|
bool error;
|
||||||
};
|
};
|
||||||
|
|
||||||
Options parseCommandLine(int argc, char* argv[]);
|
int parseCommandLine(int argc, char* argv[], Options* output);
|
||||||
void showHelp(char *argv[]);
|
int validateCommandLine(Options* options, char* argv[], json* output);
|
||||||
|
void showHelp(char* argv[]);
|
||||||
|
bool loadJSON(const fs::path& filename, json *output);
|
||||||
|
|
||||||
// xp.cpp
|
// xp.cpp
|
||||||
bool verifyXPKey(
|
bool verifyXPKey(
|
||||||
|
84
src/main.cpp
84
src/main.cpp
@ -5,58 +5,17 @@
|
|||||||
#include "header.h"
|
#include "header.h"
|
||||||
|
|
||||||
char pCharset[] = "BCDFGHJKMPQRTVWXY2346789";
|
char pCharset[] = "BCDFGHJKMPQRTVWXY2346789";
|
||||||
const std::string filename = "keys.json";
|
|
||||||
|
|
||||||
using json = nlohmann::json;
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
Options options = parseCommandLine(argc, argv);
|
Options options;
|
||||||
|
|
||||||
if (options.help || options.error) {
|
if (!parseCommandLine(argc, argv, &options)) {
|
||||||
if (options.error) {
|
fmt::print("error parsing command line\n");
|
||||||
std::cout << "error parsing command line options" << std::endl;
|
return !options.error ? 0 : 1;
|
||||||
}
|
|
||||||
showHelp(argv);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.verbose) {
|
json keys;
|
||||||
std::cout << "loading " << filename << std::endl;
|
if (validateCommandLine(&options, argv, &keys) < 0) {
|
||||||
}
|
|
||||||
|
|
||||||
std::ifstream f(filename);
|
|
||||||
json keys = json::parse(f);
|
|
||||||
|
|
||||||
if (options.verbose) {
|
|
||||||
std::cout << "loaded " << filename << " successfully" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.list) {
|
|
||||||
for (auto el : keys["Products"].items()) {
|
|
||||||
int id;
|
|
||||||
sscanf((el.value()["BINK"][0]).get<std::string>().c_str(), "%x", &id);
|
|
||||||
if (id >= 0x50) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
std::cout << el.key() << ": " << el.value()["BINK"] << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << std::endl << std::endl
|
|
||||||
<< "** Please note: any BINK ID other than 2E is considered experimental at this time **"
|
|
||||||
<< std::endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int intBinkID;
|
|
||||||
sscanf(options.binkid.c_str(), "%x", &intBinkID);
|
|
||||||
|
|
||||||
if (intBinkID >= 0x50) {
|
|
||||||
std::cout << "ERROR: BINK2002 and beyond is not supported in this application at this time" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.channelID > 999) {
|
|
||||||
std::cout << "ERROR: refusing to create a key with a siteID greater than 999" << std::endl;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,19 +34,18 @@ int main(int argc, char *argv[]) {
|
|||||||
BN_dec2bn(&privateKey, keys["BINK"][BINKID]["priv"].get<std::string>().c_str());
|
BN_dec2bn(&privateKey, keys["BINK"][BINKID]["priv"].get<std::string>().c_str());
|
||||||
|
|
||||||
if (options.verbose) {
|
if (options.verbose) {
|
||||||
std::cout << "-----------------------------------------------------------" << std::endl
|
fmt::print("----------------------------------------------------------- \n");
|
||||||
<< "Loaded the following curve constraints: BINK[" << BINKID << "]" << std::endl
|
fmt::print("Loaded the following curve constraints: BINK[{}]\n", BINKID);
|
||||||
<< "-----------------------------------------------------------" << std::endl
|
fmt::print("----------------------------------------------------------- \n");
|
||||||
<< " P: " << keys["BINK"][BINKID]["p"].get<std::string>() << std::endl
|
fmt::print(" P: {}\n", keys["BINK"][BINKID]["p"].get<std::string>());
|
||||||
<< " a: " << keys["BINK"][BINKID]["a"].get<std::string>() << std::endl
|
fmt::print(" a: {}\n", keys["BINK"][BINKID]["a"].get<std::string>());
|
||||||
<< " b: " << keys["BINK"][BINKID]["b"].get<std::string>() << std::endl
|
fmt::print(" b: {}\n", keys["BINK"][BINKID]["b"].get<std::string>());
|
||||||
<< "Gx: " << keys["BINK"][BINKID]["g"]["x"].get<std::string>() << std::endl
|
fmt::print("Gx: {}\n", keys["BINK"][BINKID]["g"]["x"].get<std::string>());
|
||||||
<< "Gy: " << keys["BINK"][BINKID]["g"]["y"].get<std::string>() << std::endl
|
fmt::print("Gy: {}\n", keys["BINK"][BINKID]["g"]["y"].get<std::string>());
|
||||||
<< "Kx: " << keys["BINK"][BINKID]["pub"]["x"].get<std::string>() << std::endl
|
fmt::print("Kx: {}\n", keys["BINK"][BINKID]["pub"]["x"].get<std::string>());
|
||||||
<< "Ky: " << keys["BINK"][BINKID]["pub"]["y"].get<std::string>() << std::endl
|
fmt::print("Ky: {}\n", keys["BINK"][BINKID]["pub"]["y"].get<std::string>());
|
||||||
<< " n: " << keys["BINK"][BINKID]["n"].get<std::string>() << std::endl
|
fmt::print(" n: {}\n", keys["BINK"][BINKID]["n"].get<std::string>());
|
||||||
<< " k: " << keys["BINK"][BINKID]["priv"].get<std::string>() << std::endl
|
fmt::print(" k: {}\n", keys["BINK"][BINKID]["priv"].get<std::string>());
|
||||||
<< std::endl << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EC_POINT *genPoint, *pubPoint;
|
EC_POINT *genPoint, *pubPoint;
|
||||||
@ -118,7 +76,7 @@ int main(int argc, char *argv[]) {
|
|||||||
nRaw += (oRaw &= 0xF423F); // ensure our serial is less than 999999
|
nRaw += (oRaw &= 0xF423F); // ensure our serial is less than 999999
|
||||||
|
|
||||||
if (options.verbose) {
|
if (options.verbose) {
|
||||||
std::cout << "> PID: " << std::setw(9) << std::setfill('0') << nRaw << std::endl;
|
fmt::print("> PID: {:09d}\n", nRaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate a key
|
// generate a key
|
||||||
@ -129,13 +87,13 @@ int main(int argc, char *argv[]) {
|
|||||||
for (int i = 0; i < total; i++) {
|
for (int i = 0; i < total; i++) {
|
||||||
generateXPKey(eCurve, genPoint, genOrder, privateKey, nRaw, pKey);
|
generateXPKey(eCurve, genPoint, genOrder, privateKey, nRaw, pKey);
|
||||||
print_product_key(pKey);
|
print_product_key(pKey);
|
||||||
std::cout << std::endl << std::endl;
|
fmt::print("\n\n");
|
||||||
|
|
||||||
// verify the key
|
// verify the key
|
||||||
count += verifyXPKey(eCurve, genPoint, pubPoint, pKey);
|
count += verifyXPKey(eCurve, genPoint, pubPoint, pKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Success count: " << std::dec << count << "/" << total << std::endl;
|
fmt::print("Success count: {}/{}\n", count, total);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -219,10 +219,10 @@ void generateXPKey(
|
|||||||
// Pack product key.
|
// Pack product key.
|
||||||
packXP(pRaw, pSerial, pHash, pSignature);
|
packXP(pRaw, pSerial, pHash, pSignature);
|
||||||
|
|
||||||
std::cout << " Serial: 0x" << std::hex << std::setw(8) << std::setfill('0') << pSerial << std::endl
|
fmt::print(" Serial: 0x{:08x}\n", pSerial);
|
||||||
<< " Hash: 0x" << std::hex << std::setw(8) << std::setfill('0') << pHash << std::endl
|
fmt::print(" Hash: 0x{:08x}\n", pHash);
|
||||||
<< " Signature: 0x" << std::hex << std::setw(8) << std::setfill('0') << pSignature << std::endl
|
fmt::print(" Signature: 0x{:08x}\n", pSignature);
|
||||||
<< std::endl;
|
fmt::print("\n");
|
||||||
|
|
||||||
EC_POINT_free(r);
|
EC_POINT_free(r);
|
||||||
} while (pRaw[1] > BITMASK(50));
|
} while (pRaw[1] > BITMASK(50));
|
||||||
|
Loading…
Reference in New Issue
Block a user