Add Office Accounting 2006-2009 Confirmation ID support

This commit is contained in:
WitherOrNot
2026-06-04 00:35:54 -04:00
parent 58dffe7bc4
commit c2239ce7b8
5 changed files with 35 additions and 10 deletions
+1 -1
View File
@@ -97,7 +97,7 @@ In light of the recent exponential interest in this project I've decided to put
* Select the **telephone activation** method, then, run `umskt -i <Installation ID>` using the `Installation ID` the activation Wizard provides for you
* If you're activating a non-Windows product, use `umskt -i <Installation ID> -m <Product>`, where `<Product>` is one of `OFFICEXP`, `OFFICE2K3`, `OFFICE2K7`, or `PLUSDME`
* If you're activating a non-Windows product, use `umskt -i <Installation ID> -m <Product>`, where `<Product>` is one of `OFFICEXP`, `OFFICE2K3`, `OFFICE2K7`, `PLUSDME`, or `OFFICEACC`
* If activating Office 2003/2007, use `umskt -i <Installation ID> -m <Product> -p <Product ID>`
#### 4. Profit!
+4 -1
View File
@@ -94,7 +94,10 @@
"BINK": ["52", "53"]
},
"Plus! Digital Media Edition for Windows XP": {
"BINK": ["52", "53"]
"BINK": [ "52", "53" ]
},
"Office Accounting 2006 / 2007 / 2008 / 2009": {
"BINK": [ "52", "53" ]
},
"Windows Longhorn (6.0.4033.0)": {
"BINK": ["54", "55"]
+6 -4
View File
@@ -62,12 +62,12 @@ void CLI::showHelp(char *argv[]) {
fmt::print("\t-n --number\tnumber of keys to generate (defaults to 1)\n");
fmt::print("\t-f --file\tspecify which keys file to load\n");
fmt::print("\t-i --instid\tinstallation ID used to generate confirmation ID (reads from stdin if no argument provided)\n");
fmt::print("\t-m --mode\tproduct family to activate.\n\t\t\tvalid options are \"WINDOWS\", \"OFFICEXP\", \"OFFICE2K3\", \"OFFICE2K7\" or \"PLUSDME\"\n\t\t\t(defaults to \"WINDOWS\")\n");
fmt::print("\t-m --mode\tproduct family to activate.\n\t\t\tvalid options are \"WINDOWS\", \"OFFICEXP\", \"OFFICE2K3\", \"OFFICE2K7\", \"PLUSDME\", or \"OFFICEACC\"\n\t\t\t(defaults to \"WINDOWS\")\n");
fmt::print("\t-p --productid\tthe product ID of the Program to activate. only required for Office 2K3 and Office 2K7 programs\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("\t-s --serial\tspecifies a serial (eg. 123456) or comma-separated serial range (recommended for BINK2002, eg. 1234,5678) to use in the product ID (defaults to 0,999999)\n");
fmt::print("\t-s --serial\tspecifies a serial (eg. 123456) or comma-separated serial range\n\t\t\t(recommended for BINK2002, eg. 1234,5678) to use in the product ID (defaults to 0,999999)\n");
fmt::print("\t-u --upgrade\tspecifies the Product Key will be an \"Upgrade\" version\n");
fmt::print("\t-V --validate\tproduct key to validate signature\n");
fmt::print("\t-N --nonewlines\tdisables newlines (for easier embedding in other apps)\n");
@@ -198,11 +198,13 @@ int CLI::parseCommandLine(int argc, char* argv[], Options* options) {
options->activationMode = OFFICE_XP;
} else if (strcmp(p, "OFFICE2K3") == 0) {
options->activationMode = OFFICE_2K3;
} else if (strcmp(p, "OFFICE2K7") == 0) {
} else if (strcmp(p, "OFFICE2K7") == 0) {
options->activationMode = OFFICE_2K7;
} else if (strcmp(p, "PLUSDME") == 0) {
options->activationMode = PLUS_DME;
}
} else if (strcmp(p, "OFFICEACC") == 0) {
options->activationMode = OFFICE_ACC;
}
i++;
} else if (arg == "-p" || arg == "--productid") {
if (i == argc -1) {
+1
View File
@@ -42,6 +42,7 @@ enum ACTIVATION_ALGORITHM {
OFFICE_2K3 = 2,
OFFICE_2K7 = 3,
PLUS_DME = 4,
OFFICE_ACC = 5,
};
enum MODE {
+23 -4
View File
@@ -128,6 +128,7 @@ QWORD ConfirmationID::ui128_quotient_mod(QWORD lo, QWORD hi)
__umul128(lo, 0x4FA8E4A40CDAE44A, &prod1);
break;
case 4:
case 5:
__umul128(lo, 0x2C5C4D3654A594F0, &prod1);
}
QWORD part1hi;
@@ -142,6 +143,7 @@ QWORD ConfirmationID::ui128_quotient_mod(QWORD lo, QWORD hi)
part1lo = __umul128(lo, 0x2CBAF12A59BBE, &part1hi);
break;
case 4:
case 5:
part1lo = __umul128(lo, 0x2D36C691A4EA5, &part1hi);
}
QWORD part2hi;
@@ -156,6 +158,7 @@ QWORD ConfirmationID::ui128_quotient_mod(QWORD lo, QWORD hi)
part2lo = __umul128(hi, 0x4FA8E4A40CDAE44A, &part2hi);
break;
case 4:
case 5:
part2lo = __umul128(hi, 0x2C5C4D3654A594F0, &part2hi);
}
QWORD sum1 = part1lo + part2lo;
@@ -175,6 +178,7 @@ QWORD ConfirmationID::ui128_quotient_mod(QWORD lo, QWORD hi)
prod3lo = __umul128(hi, 0x2CBAF12A59BBE, &prod3hi);
break;
case 4:
case 5:
prod3lo = __umul128(hi, 0x2D36C691A4EA5, &prod3hi);
}
prod3lo += prod2;
@@ -724,6 +728,7 @@ void ConfirmationID::Mix(unsigned char* buffer, size_t bufSize, const unsigned c
break;
case 2:
case 3:
case 5:
sha1_input[0] = 0x79;
memcpy(sha1_input + 1, buffer + half, half);
memcpy(sha1_input + 1 + half, key, keySize);
@@ -764,6 +769,7 @@ void ConfirmationID::Unmix(unsigned char* buffer, size_t bufSize, const unsigned
break;
case 2:
case 3:
case 5:
sha1_input[0] = 0x79;
memcpy(sha1_input + 1, buffer, half);
memcpy(sha1_input + 1 + half, key, keySize);
@@ -812,6 +818,7 @@ int ConfirmationID::Generate(const char* installation_id_str, char confirmation_
f[5] = 0x1;
break;
case 4:
case 5:
MOD = 0x16A5DABA0605983;
NON_RESIDUE = 2;
f[0] = 0x334F24F75CAA0E;
@@ -821,7 +828,7 @@ int ConfirmationID::Generate(const char* installation_id_str, char confirmation_
f[4] = 0x163694F26056DB;
f[5] = 0x1;
}
unsigned char installation_id[19]; // 10**45 < 256**19
unsigned char installation_id[20]; // 10**45 < 256**19
size_t installation_id_len = 0;
const char* p = installation_id_str;
size_t count = 0, totalCount = 0;
@@ -845,7 +852,7 @@ int ConfirmationID::Generate(const char* installation_id_str, char confirmation_
check += (count % 2 ? d * 2 : d);
count++;
totalCount++;
if (totalCount > 45)
if (totalCount > 50)
return ERR_TOO_LARGE;
unsigned char carry = d;
for (i = 0; i < installation_id_len; i++) {
@@ -866,6 +873,7 @@ int ConfirmationID::Generate(const char* installation_id_str, char confirmation_
switch (activationMode) {
case 0:
case 4:
case 5:
iid_key[0] = 0x6A;
iid_key[1] = 0xC8;
iid_key[2] = 0x5E;
@@ -880,7 +888,9 @@ int ConfirmationID::Generate(const char* installation_id_str, char confirmation_
iid_key[3] = 0xF3;
}
Unmix(installation_id, totalCount == 41 ? 17 : 19, iid_key, 4);
if (installation_id[18] >= 0x10 && overrideVersion == false)
if (activationMode != 5 && installation_id[18] >= 0x10 && overrideVersion == false)
return ERR_UNKNOWN_VERSION;
if (activationMode == 5 && installation_id[19] != 0xB)
return ERR_UNKNOWN_VERSION;
#pragma pack(push, 1)
@@ -917,6 +927,13 @@ int ConfirmationID::Generate(const char* installation_id_str, char confirmation_
}
}
break;
case 5:
memcpy(&parsed, installation_id, sizeof(parsed));
productID[0] = parsed.ProductIDLow & ((1 << 17) - 1);
productID[1] = (parsed.ProductIDLow >> 17) & ((1 << 10) - 1);
productID[2] = (parsed.KeySHA1 << 8) | parsed.ProductIDHigh;
productID[3] = (parsed.ProductIDLow >> 27) & ((1 << 17) - 1);
break;
case 2:
case 3:
@@ -950,8 +967,8 @@ int ConfirmationID::Generate(const char* installation_id_str, char confirmation_
productID[2] = stoi(productid.substr(10,7));
productID[3] = stoi(productid.substr(18,5));
}
//fmt::print("ProductID: {}-{}-{}-{} \n", productID[0], productID[1], productID[2], productID[3]);
}
// fmt::print("ProductID: {}-{}-{}-{} \n", productID[0], productID[1], productID[2], productID[3]);
unsigned char keybuf[16];
memcpy(keybuf, &parsed.HardwareID, 8);
@@ -974,6 +991,7 @@ int ConfirmationID::Generate(const char* installation_id_str, char confirmation_
case 0:
case 1:
case 4:
case 5:
u.buffer[7] = attempt;
break;
case 2:
@@ -1001,6 +1019,7 @@ int ConfirmationID::Generate(const char* installation_id_str, char confirmation_
divisor_mul128(&d, 0xEFE0302A1F7A5341, 0x01FB8CF48A70DF, &d);
break;
case 4:
case 5:
divisor_mul128(&d, 0x7C4254C43A5D1181, 0x01C61212ECE610, &d);
}
union {