testing commit

This commit is contained in:
BuildTools committed 2016-04-06 00:19:14 -07:00
commit a5727b4129
58 files changed
+7221

No files matched your search

+918
View File
@@ -0,0 +1,918 @@
// Includes and Namespaces
#include "Crypto.h"
// AES 128-bit key blob structure
struct AES_128_KEYBLOB
{
BLOBHEADER hdr;
DWORD dwKeySize;
BYTE rgbKeyData[16];
};
// Static AES Session Key
static const AES_128_KEYBLOB keyBlob =
{
// Type, Version, Algorithm
{PLAINTEXTKEYBLOB, CUR_BLOB_VERSION, NULL, CALG_AES_128},
// Blocklength
16,
// Key
{0xCD, 0x7E, 0x79, 0x6F, 0x2A, 0xB2, 0x5D, 0xCB, 0x55, 0xFF, 0xC8, 0xEF, 0x83, 0x64, 0xC4, 0x70}
};
// Default Type
static DWORD Type=AES_TYPE_128;
// Default Mode
static DWORD Mode=AES_MODE_ECB;
// Default Padding
static BYTE Padding=0x00;
// Static Key Pointer
static PBYTE pKey=NULL;
// Static IV Pointer
static PBYTE pIV=NULL;
// Init
static bool IsInit=false;
// Nb: Number of blocks, Nr: Number of rounds, Nk: Number of keys
static DWORD Nb,Nr,Nk;
// Static SubKeys Pointer
static PDWORD pSubKeys=NULL;
// RCon
static BYTE Rcon[11]= {0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36};
#pragma region Tables
// Substitution Table
static BYTE SubTable[256]=
{
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
};
// Inverse Substitution Table
static BYTE InvSubTable[256]=
{
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
};
#pragma endregion
// WinApi: AES-128 CBC PKCS5-Padding Encryption
void AESEncryptMessage(PBYTE const IV, PBYTE const Message, PDWORD const MessageSize, DWORD BufferLen)
{
HCRYPTPROV hProv = NULL;
HCRYPTKEY hKey = NULL;
if(!CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
return;
CryptImportKey(hProv, (PBYTE)&keyBlob, sizeof(keyBlob), NULL, NULL, &hKey);
CryptSetKeyParam(hKey, KP_IV, IV, NULL);
CryptEncrypt(hKey, NULL, true, NULL, Message, MessageSize, BufferLen);
if(hKey)
CryptDestroyKey(hKey);
if(hProv)
CryptReleaseContext(hProv, NULL);
}
// WinApi: AES-128 CBC PKCS5-Padding Decryption
void AESDecryptMessage(PBYTE const IV, PBYTE const Message, PDWORD const MessageSize)
{
HCRYPTPROV hProv = NULL;
HCRYPTKEY hKey = NULL;
if(!CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
return;
CryptImportKey(hProv, (PBYTE)&keyBlob, sizeof(keyBlob), NULL, NULL, &hKey);
CryptSetKeyParam(hKey, KP_IV, IV, NULL);
CryptDecrypt(hKey, NULL, true, NULL, Message, MessageSize);
if(hKey)
CryptDestroyKey(hKey);
if(hProv)
CryptReleaseContext(hProv, NULL);
}
#pragma region Math
// MUL x 2
BYTE MULx2(BYTE bIn)
{
BYTE bOut;
bOut=(bIn<<1);
if ((bIn & 0x80) != 0x00)
bOut^=0x1B;
return bOut;
};
// MUL x 3
BYTE MULx3(BYTE bIn)
{
BYTE bOut;
bOut=MULx2(bIn)^bIn;
return bOut;
};
// MUL x 4
BYTE MULx4(BYTE bIn)
{
BYTE bOut;
bOut=MULx2(bIn);
bOut=MULx2(bOut);
return bOut;
};
// MUL x 8
BYTE MULx8(BYTE bIn)
{
BYTE bOut;
bOut=MULx2(bIn);
bOut=MULx2(bOut);
bOut=MULx2(bOut);
return bOut;
};
// MUL x 9
BYTE MULx9(BYTE bIn)
{
BYTE bOut;
bOut=MULx8(bIn)^bIn;
return bOut;
};
// MUL x B
BYTE MULxB(BYTE bIn)
{
BYTE bOut;
bOut=MULx8(bIn)^MULx2(bIn)^bIn;
return bOut;
};
// MUL x D
BYTE MULxD(BYTE bIn)
{
BYTE bOut;
bOut=MULx8(bIn)^MULx4(bIn)^bIn;
return bOut;
};
// MUL x E
BYTE MULxE(BYTE bIn)
{
BYTE bOut;
bOut=MULx8(bIn)^MULx4(bIn)^MULx2(bIn);
return bOut;
};
// SBOX
BYTE SBox(BYTE bIn)
{
return SubTable[bIn];
};
// Inverse SBOX
BYTE InvSBox(BYTE bIn)
{
return InvSubTable[bIn];
};
// Substitute Word
DWORD SubWord(DWORD dwIn)
{
DWORD dwOut;
(*((PBYTE)(&dwOut)))=SBox(*((PBYTE)(&dwIn)));
(*(((PBYTE)(&dwOut))+1))=SBox(*(((PBYTE)(&dwIn))+1));
(*(((PBYTE)(&dwOut))+2))=SBox(*(((PBYTE)(&dwIn))+2));
(*(((PBYTE)(&dwOut))+3))=SBox(*(((PBYTE)(&dwIn))+3));
return dwOut;
};
// Rotate Word
DWORD RotWord(DWORD dwIn)
{
DWORD dwOut;
(*((PBYTE)(&dwOut)))=(*(((PBYTE)(&dwIn))+1));
(*(((PBYTE)(&dwOut))+1))=(*(((PBYTE)(&dwIn))+2));
(*(((PBYTE)(&dwOut))+2))=(*(((PBYTE)(&dwIn))+3));
(*(((PBYTE)(&dwOut))+3))=(*((PBYTE)(&dwIn)));
return dwOut;
};
// Substitute Bytes
void SubBytes(PBYTE pBytes)
{
DWORD i;
BYTE bIn[16];
for(i=0 ; i<16 ; i++)
bIn[i]=pBytes[i];
for(i=0 ; i<16 ; i++)
pBytes[i]=SBox(bIn[i]);
};
// Shift Rows
void ShiftRows(PBYTE pBytes)
{
DWORD i;
BYTE bIn[16];
for(i=0 ; i<16 ; i++)
bIn[i]=pBytes[i];
pBytes[0]=bIn[0];
pBytes[1]=bIn[5];
pBytes[2]=bIn[10];
pBytes[3]=bIn[15];
pBytes[4]=bIn[4];
pBytes[5]=bIn[9];
pBytes[6]=bIn[14];
pBytes[7]=bIn[3];
pBytes[8]=bIn[8];
pBytes[9]=bIn[13];
pBytes[10]=bIn[2];
pBytes[11]=bIn[7];
pBytes[12]=bIn[12];
pBytes[13]=bIn[1];
pBytes[14]=bIn[6];
pBytes[15]=bIn[11];
};
// Mix Columns
void MixColumns(PBYTE pBytes)
{
DWORD i;
BYTE bIn[16];
for(i=0 ; i<16 ; i++)
bIn[i]=pBytes[i];
pBytes[0] = MULx2(bIn[0]) ^ MULx3(bIn[1]) ^ bIn[2] ^ bIn[3];
pBytes[1] = bIn[0] ^ MULx2(bIn[1]) ^ MULx3(bIn[2]) ^ bIn[3];
pBytes[2] = bIn[0] ^ bIn[1] ^ MULx2(bIn[2]) ^ MULx3(bIn[3]);
pBytes[3] = MULx3(bIn[0]) ^ bIn[1] ^ bIn[2] ^ MULx2(bIn[3]);
pBytes[4] = MULx2(bIn[4]) ^ MULx3(bIn[5]) ^ bIn[6] ^ bIn[7];
pBytes[5] = bIn[4] ^ MULx2(bIn[5]) ^ MULx3(bIn[6]) ^ bIn[7];
pBytes[6] = bIn[4] ^ bIn[5] ^ MULx2(bIn[6]) ^ MULx3(bIn[7]);
pBytes[7] = MULx3(bIn[4]) ^ bIn[5] ^ bIn[6] ^ MULx2(bIn[7]);
pBytes[8] = MULx2(bIn[8]) ^ MULx3(bIn[9]) ^ bIn[10] ^ bIn[11];
pBytes[9] = bIn[8] ^ MULx2(bIn[9]) ^ MULx3(bIn[10]) ^ bIn[11];
pBytes[10] = bIn[8] ^ bIn[9] ^ MULx2(bIn[10]) ^ MULx3(bIn[11]);
pBytes[11] = MULx3(bIn[8]) ^ bIn[9] ^ bIn[10] ^ MULx2(bIn[11]);
pBytes[12] = MULx2(bIn[12]) ^ MULx3(bIn[13]) ^ bIn[14] ^ bIn[15];
pBytes[13] = bIn[12] ^ MULx2(bIn[13]) ^ MULx3(bIn[14]) ^ bIn[15];
pBytes[14] = bIn[12] ^ bIn[13] ^ MULx2(bIn[14]) ^ MULx3(bIn[15]);
pBytes[15] = MULx3(bIn[12]) ^ bIn[13] ^ bIn[14] ^ MULx2(bIn[15]);
};
// Add Round Key
void AddRoundKey(PBYTE pState, DWORD Round)
{
(*((PDWORD)pState)) ^= pSubKeys[4*Round];
(*(((PDWORD)pState)+1)) ^= pSubKeys[4*Round+1];
(*(((PDWORD)pState)+2)) ^= pSubKeys[4*Round+2];
(*(((PDWORD)pState)+3)) ^= pSubKeys[4*Round+3];
};
// Inverse Substitute Bytes
void InvSubBytes(PBYTE pBytes)
{
DWORD i;
BYTE bIn[16];
for(i=0 ; i<16 ; i++)
bIn[i]=pBytes[i];
for(i=0 ; i<16 ; i++)
pBytes[i]=InvSBox(bIn[i]);
};
// Inverse Shift Rows
void InvShiftRows(PBYTE pBytes)
{
DWORD i;
BYTE bIn[16];
for(i=0 ; i<16 ; i++)
bIn[i]=pBytes[i];
pBytes[0]=bIn[0];
pBytes[1]=bIn[13];
pBytes[2]=bIn[10];
pBytes[3]=bIn[7];
pBytes[4]=bIn[4];
pBytes[5]=bIn[1];
pBytes[6]=bIn[14];
pBytes[7]=bIn[11];
pBytes[8]=bIn[8];
pBytes[9]=bIn[5];
pBytes[10]=bIn[2];
pBytes[11]=bIn[15];
pBytes[12]=bIn[12];
pBytes[13]=bIn[9];
pBytes[14]=bIn[6];
pBytes[15]=bIn[3];
};
// Inverse Mix Columns
void InvMixColumns(PBYTE pBytes)
{
DWORD i;
BYTE bIn[16];
for(i=0 ; i<16 ; i++)
bIn[i]=pBytes[i];
pBytes[0] = MULxE(bIn[0]) ^ MULxB(bIn[1]) ^ MULxD(bIn[2]) ^ MULx9(bIn[3]);
pBytes[1] = MULx9(bIn[0]) ^ MULxE(bIn[1]) ^ MULxB(bIn[2]) ^ MULxD(bIn[3]);
pBytes[2] = MULxD(bIn[0]) ^ MULx9(bIn[1]) ^ MULxE(bIn[2]) ^ MULxB(bIn[3]);
pBytes[3] = MULxB(bIn[0]) ^ MULxD(bIn[1]) ^ MULx9(bIn[2]) ^ MULxE(bIn[3]);
pBytes[4] = MULxE(bIn[4]) ^ MULxB(bIn[5]) ^ MULxD(bIn[6]) ^ MULx9(bIn[7]);
pBytes[5] = MULx9(bIn[4]) ^ MULxE(bIn[5]) ^ MULxB(bIn[6]) ^ MULxD(bIn[7]);
pBytes[6] = MULxD(bIn[4]) ^ MULx9(bIn[5]) ^ MULxE(bIn[6]) ^ MULxB(bIn[7]);
pBytes[7] = MULxB(bIn[4]) ^ MULxD(bIn[5]) ^ MULx9(bIn[6]) ^ MULxE(bIn[7]);
pBytes[8] = MULxE(bIn[8]) ^ MULxB(bIn[9]) ^ MULxD(bIn[10]) ^ MULx9(bIn[11]);
pBytes[9] = MULx9(bIn[8]) ^ MULxE(bIn[9]) ^ MULxB(bIn[10]) ^ MULxD(bIn[11]);
pBytes[10] = MULxD(bIn[8]) ^ MULx9(bIn[9]) ^ MULxE(bIn[10]) ^ MULxB(bIn[11]);
pBytes[11] = MULxB(bIn[8]) ^ MULxD(bIn[9]) ^ MULx9(bIn[10]) ^ MULxE(bIn[11]);
pBytes[12] = MULxE(bIn[12]) ^ MULxB(bIn[13]) ^ MULxD(bIn[14]) ^ MULx9(bIn[15]);
pBytes[13] = MULx9(bIn[12]) ^ MULxE(bIn[13]) ^ MULxB(bIn[14]) ^ MULxD(bIn[15]);
pBytes[14] = MULxD(bIn[12]) ^ MULx9(bIn[13]) ^ MULxE(bIn[14]) ^ MULxB(bIn[15]);
pBytes[15] = MULxB(bIn[12]) ^ MULxD(bIn[13]) ^ MULx9(bIn[14]) ^ MULxE(bIn[15]);
};
// Key Expansion
void KeyExpansion(void)
{
DWORD i,Temp;
for(i=0 ; i<Nk ; i++){
(*(((PBYTE)pSubKeys)+4*i))=pKey[4*i];
(*(((PBYTE)pSubKeys)+4*i+1))=pKey[4*i+1];
(*(((PBYTE)pSubKeys)+4*i+2))=pKey[4*i+2];
(*(((PBYTE)pSubKeys)+4*i+3))=pKey[4*i+3];
};
for(i=Nk ; i<(Nb*(Nr+1)) ; i++){
Temp=pSubKeys[i-1];
if (((i/Nk)*Nk) == i){
Temp=((SubWord(RotWord(Temp)))^Rcon[i/Nk]);
}else{
if ((Nk>6)&&((i-Nk*(i/Nk)) == 4))
Temp=SubWord(Temp);
};
pSubKeys[i]=((pSubKeys[i-Nk])^Temp);
};
};
// Do Cipher
void DoCipher(PBYTE pIn, PBYTE pOut)
{
BYTE State[16];
DWORD Round;
DWORD i;
for(i=0 ; i<16 ; i++)
State[i]=pIn[i];
AddRoundKey(State,0);
for(Round=1 ; Round<Nr ; Round++){
SubBytes(State);
ShiftRows(State);
MixColumns(State);
// KMS V6
if(Round == 4){
State[0] ^= 0x73;
}else if(Round == 6){
State[0] ^= 0x09;
}else if(Round == 8){
State[0] ^= 0xE4;
}
AddRoundKey(State,Round);
};
SubBytes(State);
ShiftRows(State);
AddRoundKey(State,Nr);
for(i=0 ; i<16 ; i++)
pOut[i]=State[i];
};
// Do Inverse Cipher
void DoInvCipher(PBYTE pIn, PBYTE pOut)
{
BYTE State[16];
DWORD Round;
DWORD i;
for(i=0 ; i<16 ; i++)
State[i]=pIn[i];
AddRoundKey(State,Nr);
for(Round=(Nr-1) ; Round>0 ; Round--){
InvShiftRows(State);
InvSubBytes(State);
AddRoundKey(State,Round);
// KMS V6
if(Round == 4){
State[0] ^= 0x73;
}else if(Round == 6){
State[0] ^= 0x09;
}else if(Round == 8){
State[0] ^= 0xE4;
}
InvMixColumns(State);
};
InvShiftRows(State);
InvSubBytes(State);
AddRoundKey(State,0);
for(i=0 ; i<16 ; i++)
pOut[i]=State[i];
};
#pragma endregion
#pragma region Initialization and Cleanup
// AES Init
DWORD AesInit(DWORD dwType, DWORD dwMode, BYTE bPadding, PBYTE pbKey, PBYTE pbIV)
{
DWORD i,N;
if ((dwType != AES_TYPE_128) && (dwType != AES_TYPE_192) && (dwType != AES_TYPE_256))
return 1;
if ((dwMode != AES_MODE_ECB) && (dwMode != AES_MODE_CBC) && (dwMode != AES_MODE_CFB) && (dwMode != AES_MODE_OFB) && (dwMode != AES_MODE_CTR))
return 2;
if (pbKey == NULL)
return 3;
if (pbIV == NULL)
return 4;
if (pKey != NULL){
for(i=0 ; i<32 ; i++)
pKey[i]=0x00;
delete(pKey);
};
if (pIV != NULL){
for(i=0 ; i<16 ; i++)
pIV[i]=0x00;
delete(pIV);
};
Type=dwType;
Mode=dwMode;
Padding=bPadding;
pKey = new BYTE[32];
Nb=4;
switch(Type){
case AES_TYPE_128:
N=16;
Nr=10;
Nk=4;
break;
case AES_TYPE_192:
N=24;
Nr=12;
Nk=6;
break;
default:
N=32;
Nr=14;
Nk=8;
};
for(i=0 ; i<N ; i++)
pKey[i]=pbKey[i];
pIV = new BYTE[16];
for(i=0 ; i<16 ; i++)
pIV[i]=pbIV[i];
pSubKeys = new DWORD[Nb*(Nr+1)];
KeyExpansion();
IsInit=true;
return 0;
};
// AES Clear
DWORD AesClear(void)
{
unsigned int i;
if (!IsInit)
return 5;
if (pSubKeys != NULL){
for(i=0 ; i<(Nb*(Nr+1)) ; i++)
pSubKeys[i]=0x00000000;
delete(pSubKeys);
};
pSubKeys=NULL;
if (pKey != NULL){
for(i=0 ; i<32 ; i++)
pKey[i]=0x00;
delete(pKey);
};
pKey=NULL;
if (pIV != NULL){
for(i=0 ; i<16 ; i++)
pIV[i]=0x00;
delete(pIV);
};
pIV=NULL;
Type=AES_TYPE_128;
Mode=AES_MODE_ECB;
Padding=0x00;
IsInit=false;
return 0;
};
#pragma endregion
#pragma region Encryption
// Aes Encrypt Block
DWORD AesEncryptBlock(PBYTE PlainText, DWORD PlainTextSize, PBYTE Cipher)
{
BYTE bIn[16];
DWORD i,j;
if (PlainTextSize > 16)
return 1;
for(i=0 ; i<PlainTextSize ; i++)
bIn[i]=PlainText[i];
for(j=i ; j<16 ; j++)
bIn[j]=Padding;
DoCipher(bIn,Cipher);
return 0;
};
// AES Encrypt
DWORD AesEncrypt(PBYTE PlainText, DWORD PlainTextSize, PBYTE Cipher, PDWORD CipherSize)
{
DWORD N,n;
DWORD i,j;
DWORD Error;
DWORD DataLen;
BYTE Temp[16];
DataLen=0;
N=PlainTextSize/16;
n=PlainTextSize-16*N;
(*CipherSize)=0;
if (PlainTextSize == 0)
return 1;
switch(Mode){
case AES_MODE_ECB:
for(i=0 ; i<N ; i++){
Error=AesEncryptBlock(PlainText+16*i,16,Cipher+16*i);
if (Error != 0)
return Error;
DataLen+=16;
};
if (n != 0){
Error=AesEncryptBlock(PlainText+16*N,n,Cipher+16*N);
if (Error != 0)
return Error;
DataLen+=16;
};
(*CipherSize)=DataLen;
break;
case AES_MODE_CBC:
for(i=0 ; i<N ; i++){
for(j=0 ; j<16 ; j++){
if (i == 0)
Temp[j]=(pIV[j]^PlainText[j]);
else
Temp[j]=(Cipher[16*(i-1)+j]^PlainText[16*i+j]);
};
Error=AesEncryptBlock(Temp,16,Cipher+16*i);
if (Error != 0)
return Error;
DataLen+=16;
};
if (n != 0){
for(j=0 ; j<n ; j++){
if (N == 0)
Temp[j]=(pIV[j]^PlainText[j]);
else
Temp[j]=(Cipher[16*(N-1)+j]^PlainText[16*N+j]);
};
for(j=n ; j<16 ; j++){
if (N == 0)
Temp[j]=(pIV[j]^Padding);
else
Temp[j]=(Cipher[16*(N-1)+j]^Padding);
};
Error=AesEncryptBlock(Temp,16,Cipher+16*N);
if (Error != 0)
return Error;
DataLen+=16;
};
(*CipherSize)=DataLen;
break;
case AES_MODE_CFB:
for(i=0 ; i<N ; i++){
if (i == 0)
Error=AesEncryptBlock(pIV,16,Temp);
else
Error=AesEncryptBlock(Cipher+16*(i-1),16,Temp);
if (Error != 0)
return Error;
for(j=0 ; j<16 ; j++)
Cipher[16*i+j]=Temp[j]^PlainText[16*i+j];
DataLen+=16;
};
if (n != 0){
if (i == 0)
Error=AesEncryptBlock(pIV,16,Temp);
else
Error=AesEncryptBlock(Cipher+16*(i-1),16,Temp);
if (Error != 0)
return Error;
for(j=0 ; j<n ; j++)
Cipher[16*i+j]=Temp[j]^PlainText[16*i+j];
for(j=n ; j<16 ; j++)
Cipher[16*i+j]=Temp[j]^Padding;
DataLen+=16;
};
(*CipherSize)=DataLen;
break;
case AES_MODE_OFB:
for(i=0 ; i<N ; i++){
if (i == 0)
Error=AesEncryptBlock(pIV,16,Temp);
else
Error=AesEncryptBlock(Temp,16,Temp);
if (Error != 0)
return Error;
for(j=0 ; j<16 ; j++)
Cipher[16*i+j]=Temp[j]^PlainText[16*i+j];
DataLen+=16;
};
if (n != 0){
if (i == 0)
Error=AesEncryptBlock(pIV,16,Temp);
else
Error=AesEncryptBlock(Temp,16,Temp);
if (Error != 0)
return Error;
for(j=0 ; j<n ; j++)
Cipher[16*i+j]=Temp[j]^PlainText[16*i+j];
for(j=n ; j<16 ; j++)
Cipher[16*i+j]=Temp[j]^Padding;
DataLen+=16;
};
(*CipherSize)=DataLen;
break;
default:
return 1;
};
return 0;
};
// Encrypt Message
void EncryptMessage(int MessageSize, PBYTE Message)
{
PBYTE p;
DWORD q;
p = new BYTE[MessageSize];
memcpy(p, Message, MessageSize);
AesEncrypt(p, MessageSize, Message, &q);
delete[] p;
};
#pragma endregion
#pragma region Decryption
// Aes Decrypt Block
DWORD AesDecryptBlock(PBYTE Cipher, PBYTE PlainText)
{
DoInvCipher(Cipher,PlainText);
return 0;
};
// AES Decrypt
DWORD AesDecrypt(PBYTE Cipher, DWORD CipherSize, PBYTE PlainText, PDWORD PlainTextSize)
{
DWORD N,n;
DWORD i,j;
DWORD Error;
BYTE Temp[16];
N=CipherSize/16;
n=CipherSize-16*N;
(*PlainTextSize)=0;
if (CipherSize == 0)
return 1;
if (n != 0)
return 1;
switch(Mode){
case AES_MODE_ECB:
for(i=0 ; i<N ; i++){
Error=AesDecryptBlock(Cipher+16*i,PlainText+16*i);
if (Error != 0)
return Error;
};
(*PlainTextSize)=CipherSize;
break;
case AES_MODE_CBC:
for(i=0 ; i<N ; i++){
Error=AesDecryptBlock(Cipher+16*i,Temp);
if (Error != 0)
return Error;
for(j=0 ; j<16 ; j++){
if (i == 0)
PlainText[16*i+j]=(pIV[j]^Temp[j]);
else
PlainText[16*i+j]=(Cipher[16*(i-1)+j]^Temp[j]);
};
};
(*PlainTextSize)=CipherSize;
break;
case AES_MODE_CFB:
for(i=0 ; i<N ; i++){
if (i == 0)
Error=AesEncryptBlock(pIV,16,Temp);
else
Error=AesEncryptBlock(Cipher+16*(i-1),16,Temp);
if (Error != 0)
return Error;
for(j=0 ; j<16 ; j++)
PlainText[16*i+j]=Temp[j]^Cipher[16*i+j];
};
(*PlainTextSize)=CipherSize;
break;
case AES_MODE_OFB:
for(i=0 ; i<N ; i++){
if (i == 0)
Error=AesEncryptBlock(pIV,16,Temp);
else
Error=AesEncryptBlock(Temp,16,Temp);
if (Error != 0) return Error;
for(j=0 ; j<16 ; j++)
PlainText[16*i+j]=Temp[j]^Cipher[16*i+j];
};
(*PlainTextSize)=CipherSize;
break;
default:
return 1;
};
return 0;
};
// Decrypt Message
void DecryptMessage(int MessageSize, PBYTE Message)
{
PBYTE p;
DWORD q;
p = new BYTE[MessageSize];
memcpy(p, Message, MessageSize);
AesDecrypt(p, MessageSize, Message, &q);
delete[] p;
};
#pragma endregion
+220
View File
@@ -0,0 +1,220 @@
// Includes and Namespaces
#include "CoreKMS.h"
#include "Crypto.h"
#include "Hash.h"
#pragma region Tables
// Precomputed Key Schedule
static const BYTE AesKeyV4[] = {
0x05, 0x3D, 0x83, 0x07, 0xF9, 0xE5, 0xF0, 0x88, 0xEB, 0x5E, 0xA6, 0x68, 0x6C, 0xF0, 0x37, 0xC7,
0xE4, 0xEF, 0xD2, 0xD6, 0xDB, 0x88, 0x75, 0x6E, 0x22, 0x6D, 0x85, 0xE6, 0xC9, 0x33, 0x23, 0x8E,
0xA5, 0xC3, 0x14, 0x49, 0x41, 0x2C, 0xC6, 0x9F, 0xA8, 0x3C, 0xAE, 0xED, 0x8A, 0x51, 0x2B, 0x0B,
0x43, 0x62, 0x08, 0x85, 0xE6, 0xA1, 0x1C, 0xCC, 0xA7, 0x8D, 0xDA, 0x53, 0xF1, 0x6B, 0x43, 0xB1,
0x7B, 0x3A, 0x68, 0xBA, 0x38, 0x58, 0x60, 0x3F, 0xDE, 0xF9, 0x7C, 0xF3, 0x79, 0x74, 0xA6, 0xA0,
0x6B, 0x4F, 0xA3, 0x07, 0x10, 0x75, 0xCB, 0xBD, 0x28, 0x2D, 0xAB, 0x82, 0xF6, 0xD4, 0xD7, 0x71,
0x8F, 0xA0, 0x71, 0xD1, 0x9B, 0xEC, 0x9D, 0x74, 0x8B, 0x99, 0x56, 0xC9, 0xA3, 0xB4, 0xFD, 0x4B,
0x55, 0x60, 0x2A, 0x3A, 0xDA, 0xC0, 0x5B, 0xEB, 0x01, 0xD5, 0x74, 0x23, 0x8A, 0x4C, 0x22, 0xEA,
0x29, 0xF8, 0xDF, 0xA1, 0x7C, 0x98, 0xF5, 0x9B, 0xA6, 0x58, 0xAE, 0x70, 0x2B, 0x31, 0x25, 0x07,
0xA1, 0x7D, 0x07, 0xED, 0x88, 0x85, 0xD8, 0x4C, 0xF4, 0x1D, 0x2D, 0xD7, 0x52, 0x45, 0x83, 0xA7,
0xC5, 0xDD, 0x79, 0x07, 0x64, 0xA0, 0x7E, 0xEA, 0xEC, 0x25, 0xA6, 0xA6, 0x18, 0x38, 0x8B, 0x71,
0x4A, 0x7D, 0x08, 0xD6, 0x21, 0xED, 0x8F, 0xD1, 0x45, 0x4D, 0xF1, 0x3B, 0xA9, 0x68, 0x57, 0x9D
};
// Rijndael SBox
static const BYTE SubTable[256] =
{
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
};
#pragma endregion
#pragma region Structs
HMAC_KEYBLOB Hmac_keyblob = {
// Type, Version, Algorithm
{PLAINTEXTKEYBLOB, CUR_BLOB_VERSION, NULL, CALG_RC2},
// Key length
16,
// Key
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
#pragma endregion
#pragma region Helpers
// Rijndael AddRoundKey
void HashAddRoundKey(PBYTE const hash, DWORD round)
{
for (DWORD i = 0; i < 16; i++)
hash[i] ^= AesKeyV4[(round << 4) + i];
}
// Xor Buffer
void HashXorBuffer(PBYTE const source, PBYTE const destination, DWORD size)
{
for (DWORD i = 0; i < size; i++)
destination[i] ^= source[i];
}
// Rijndael SBox
void HashSubBytes(PBYTE const pBytes)
{
for(DWORD i = 0; i < 16; i++)
pBytes[i] = SubTable[pBytes[i]];
}
// Rijndael ShiftRows
void HashShiftRows(PBYTE const pBytes)
{
BYTE bIn[16];
memcpy(bIn, pBytes, 16);
for (DWORD i = 0; i < 16; i++)
pBytes[i] = bIn[(i + ((i & 3) << 2)) & 0xf];
}
// Rijndael MixColumns
void HashMixColumns(PBYTE const pBytes)
{
BYTE column[5];
for (DWORD i = 0; i < 16; i += 4)
{
*(PDWORD) column = *(PDWORD) &pBytes[i];
column[4] = column[0] ^ column[1] ^ column[2] ^ column[3];
pBytes[i] = MULx2(column[0] ^ column[1]) ^ column[4];
pBytes[i | 1] = MULx2(column[1] ^ column[2]) ^ column[4];
pBytes[i | 2] = MULx2(column[2] ^ column[3]) ^ column[4];
pBytes[i | 3] = MULx2(column[3] ^ column[0]) ^ column[4];
*(PDWORD) &pBytes[i] ^= *(PDWORD) column;
}
}
// Rijndael Block
void Hash(PBYTE const hash)
{
HashAddRoundKey(hash, 0);
for (DWORD i = 1; i < 11; i++){
HashSubBytes(hash);
HashShiftRows(hash);
HashMixColumns(hash);
HashAddRoundKey(hash, i);
}
HashSubBytes(hash);
HashShiftRows(hash);
HashAddRoundKey(hash, 11);
}
#pragma endregion
// Get Hash
void GetHash(DWORD MessageSize, PBYTE const Message, PBYTE const hash)
{
DWORD i, j, k;
// MessageSize / Blocksize
j = MessageSize >> 4;
// Remainding Bytes
k = MessageSize & 0xf;
// Hash
for (i = 0; i < j; i++){
HashXorBuffer(&Message[i << 4], hash, 16);
Hash(hash);
}
// Bit Padding
hash[k] ^= 0x80;
HashXorBuffer(&Message[i << 4], hash, k);
Hash(hash);
}
// Generate SHA-256 Hash with Win32 Crypt API Provider
void GetHashSHA256(DWORD dataSize, PBYTE const data, PBYTE const Hash)
{
HCRYPTPROV hProv = NULL;
HCRYPTHASH hHash = NULL;
DWORD HashSize = HASH_SIZE_SHA256;
if(!CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
return;
CryptCreateHash(hProv, CALG_SHA_256, NULL, NULL, &hHash);
CryptHashData(hHash, data, dataSize, NULL);
CryptGetHashParam(hHash, HP_HASHVAL, Hash, &HashSize, NULL);
if(hHash)
CryptDestroyHash(hHash);
if(hProv)
CryptReleaseContext(hProv, NULL);
}
// Generate time based HMAC key
void GetHmacKey(FILETIME* timestamp, PBYTE hmackey)
{
BYTE Sha256Hash[32];
QWORD t, c1, c2, c3, seed;
t = *(PQWORD)timestamp;
c1 = 0x00000022816889BD;
c2 = 0x000000208CBAB5ED;
c3 = 0x3156CD5AC628477A;
seed = ((t / c1) * c2) + c3;
GetHashSHA256(8, (PBYTE)&seed, Sha256Hash);
memcpy(hmackey, Sha256Hash+16, 16);
}
// Generate HMAC-SHA-256
void GetHmacSHA256(DWORD dwDataLen, PBYTE const pbData, PBYTE const pbHash)
{
HCRYPTPROV hProv = NULL;
HCRYPTKEY hKey = NULL;
HCRYPTHASH hHmacHash = NULL;
HMAC_INFO HmacInfo = {0};
DWORD dwHmacSize = 32;
HmacInfo.HashAlgid = CALG_SHA_256;
if(!CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
return;
CryptImportKey(hProv, (PBYTE)&Hmac_keyblob, sizeof(HMAC_KEYBLOB), NULL, NULL, &hKey);
CryptCreateHash(hProv, CALG_HMAC, hKey, NULL, &hHmacHash);
CryptSetHashParam(hHmacHash, HP_HMAC_INFO, (PBYTE)&HmacInfo, NULL);
CryptHashData(hHmacHash, pbData, dwDataLen, NULL);
CryptGetHashParam(hHmacHash, HP_HASHVAL, pbHash, &dwHmacSize, NULL);
if(hKey)
CryptDestroyKey(hKey);
if(hHmacHash)
CryptDestroyHash(hHmacHash);
if(hProv)
CryptReleaseContext(hProv, NULL);
}
+834
View File
@@ -0,0 +1,834 @@
// Includes and Namespaces
#include <regex>
#include <iostream>
#include <stdio.h>
#include <string>
#include "Crypto.h"
#include "Hash.h"
#include "KMSServer.h"
#include "KMSClientLogic.h"
#include "KMSClientSettings.h"
using namespace std;
// Link Libraries
#pragma comment(lib, "rpcrt4.lib")
// Hold KMS Client Settings
KMSClientSettings ClientSettings;
// Windows Service Parameters for Service Application
SERVICE_STATUS ClientServiceStatus;
SERVICE_STATUS_HANDLE ClientServiceHandle;
#pragma region Application Initialization Functions
// Load Application Parameters from Command-Line
void LoadClientParameters(int argc, wchar_t *argv[], bool RunAsService)
{
// Initialize KMS Client Settings Object
ClientSettings.Initialize();
ClientSettings.RunAsService = RunAsService;
#pragma region Command-Line
// Handle Command-Line Arguments (KMS Port or Help)
if (argc >= 2)
{
if (CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, argv[1], -1, L"/?", -1) == CSTR_EQUAL)
{
printf("Usage:\n");
printf("[KMS Port] [KMS Host] [Client Mode]\n\n");
printf("KMS Port:\n");
printf("\tDefaultPort:\t\tUse the built-in KMS Port.\n");
printf("\tInteger:\t\tNumber from 1 to 65535.\n\n");
printf("KMS Host:\n");
printf("\tDefaultHost:\t\tUse the built-in KMS Host Address.\n");
printf("\tString:\t\t\tA DNS Name or IP Address.\n\n");
printf("Client Mode:\n");
printf("\tWindows:\t\tWindows Vista Enterprise KMS (V4) Client.\n");
printf("\tWindowsVista:\t\tWindows Vista Enterprise KMS (V4) Client.\n");
printf("\tWindows7:\t\tWindows 7 Enterprise KMS (V4) Client.\n");
printf("\tWindows8:\t\tWindows 8 Enterprise KMS (V5) Client.\n");
printf("\tWindows81:\t\tWindows 8 Enterprise KMS (V6) Client.\n");
printf("\tOffice2010:\t\tOffice 2010 Pro Plus KMS (V4) Client.\n");
printf("\tOffice2013:\t\tOffice 2013 Pro Plus KMS (V4) Client.\n");
printf("\tOffice2013V4:\t\tOffice 2013 Pro Plus KMS (V4) Client.\n");
printf("\tOffice2013V5:\t\tOffice 2013 Pro Plus KMS (V5) Client.\n\n");
printf("\tOffice2013V6:\t\tOffice 2013 Pro Plus KMS (V6) Client.\n\n");
printf("Example:\n");
printf("\tC:\\>\"KMS Client.exe\" 1688 127.0.0.2 Windows");
ClientWriteLogErrorTerminate(L"\n", -1);
}
else
{
ClientValidateKMSPort(argv[1]);
}
}
// Handle Command-Line Arguments (KMS Host)
if (argc >= 3)
{
ClientValidateKMSHost(argv[2]);
}
// Handle Command-Line Arguments (Client Mode)
if (argc >= 4)
{
ClientValidateKMSClientMode(argv[3]);
}
#pragma endregion
}
// Start RPC Connection and try to contact a KMS Server.
void StartKMSClient()
{
// RPC Parameters
RPC_STATUS status;
RPC_WSTR pszUuid = NULL;
RPC_WSTR pszProtocolSequence = (RPC_WSTR)L"ncacn_ip_tcp";
RPC_WSTR pszNetworkAddress = (RPC_WSTR)ClientSettings.KMSHost;
RPC_WSTR pszEndpoint = (RPC_WSTR)ClientSettings.KMSPort;
RPC_WSTR pszOptions = NULL;
RPC_WSTR pszStringBinding = NULL;
// Create String Binding
status = RpcStringBindingCompose
(
pszUuid,
pszProtocolSequence,
pszNetworkAddress,
pszEndpoint,
pszOptions,
&pszStringBinding
);
if (status)
{
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"RpcStringBindingCompose failed with code %i.\n", status);
ClientWriteLogErrorTerminate(Message, status);
}
// Get RPC Binding Handle from String Binding
status = RpcBindingFromStringBinding(pszStringBinding, &KMSServer_v1_0_c_ifspec);
if (status)
{
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"RpcBindingFromStringBinding failed with code %i.\n", status);
ClientWriteLogErrorTerminate(Message, status);
}
ClientWriteLogInformation(L"\nKMS Client Emulator started successfully.\n");
// Send Requests
int RequestsNeeded = ClientSettings.RequiredClientCount;
for (int requests = 0; requests < RequestsNeeded; requests++)
{
// Define the size of the request
int sizeRequest = 0;
if (ClientSettings.KMSProtocolMajorVersion == 4)
{
sizeRequest = sizeof(REQUEST_V4);
}
else if (ClientSettings.KMSProtocolMajorVersion == 5)
{
sizeRequest = sizeof(REQUEST_V5);
}
else
{
sizeRequest = sizeof(REQUEST_V6);
}
// Create KMS Client Request
PBYTE request = (PBYTE)midl_user_allocate(sizeRequest);
memcpy(request, (PBYTE)CreateRequest(), sizeRequest);
// Send KMS Client Request to KMS Server
status = SendRequest(request, requests, &RequestsNeeded);
if (status)
{
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"Activation request (KMS V%i.%i) %i of %i failed.\n", ClientSettings.KMSProtocolMajorVersion, ClientSettings.KMSProtocolMinorVersion, requests + 1, RequestsNeeded);
ClientWriteLogErrorTerminate(Message, status);
}
else
{
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"Activation request (KMS V%i.%i) %i of %i sent.\n", ClientSettings.KMSProtocolMajorVersion, ClientSettings.KMSProtocolMinorVersion, requests + 1, RequestsNeeded);
ClientWriteLogInformation(Message);
}
}
// Free String Binding
status = RpcStringFree(&pszStringBinding);
if (status)
{
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"RpcStringFree failed with code %i.\n", status);
ClientWriteLogErrorTerminate(Message, status);
}
// Free RPC Binding
status = RpcBindingFree(&KMSServer_v1_0_c_ifspec);
if (status)
{
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"RpcBindingFree failed with code %i.\n", status);
ClientWriteLogErrorTerminate(Message, status);
}
}
#pragma endregion
#pragma region KMS Client Request Generation Functions
// Create KMS Client Request Data Based on KMS Client Protocol Version.
PBYTE CreateRequest()
{
// KMS Protocol Major Version
if (ClientSettings.KMSProtocolMajorVersion == 4)
{
return CreateRequestV4();
}
else if (ClientSettings.KMSProtocolMajorVersion == 5)
{
return CreateRequestV5();
}
else
{
return CreateRequestV6();
}
}
// Create Base KMS Client Request Object.
void CreateRequestBase(REQUEST* const Request)
{
// KMS Protocol Version
Request->MajorVer = ClientSettings.KMSProtocolMajorVersion;
Request->MinorVer = ClientSettings.KMSProtocolMinorVersion;
// KMS Client is NOT a VM
Request->IsClientVM = 0;
// License Status
Request->LicenseStatus = ClientSettings.KMSClientLicenseStatus;
// Grace Time
Request->GraceTime = 43200;
// Application ID
UuidFromStringW((RPC_WSTR)ClientSettings.KMSClientAppID, &Request->ApplicationId);
// SKU ID
UuidFromStringW((RPC_WSTR)ClientSettings.KMSClientSkuID, &Request->SkuId);
// KMS Counted ID
UuidFromStringW((RPC_WSTR)ClientSettings.KMSClientKMSCountedID, &Request->KmsCountedId);
// CMID
CoCreateGuid(&Request->ClientMachineId);
// Minimum Clients
Request->RequiredClientCount = ClientSettings.RequiredClientCount;
// Timestamp
GetSystemTimeAsFileTime(&Request->RequestTime);
// Machine Name
static const char alphanum[] = "0123456789" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz";
// Seed Random Number Generator
srand(GetTickCount());
// Generate Random Machine Name (Up to 63 Characters)
int MachineNameLength = rand() % 63 + 1;
for (int i = 0; i < MachineNameLength; i++)
{
Request->MachineName[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
}
Request->MachineName[MachineNameLength] = 0;
}
// Create Hashed KMS Client Request Data for KMS Protocol Version 4.
PBYTE CreateRequestV4()
{
// Allocate KMS Client Request Buffer
PBYTE request = (PBYTE)midl_user_allocate(sizeof(REQUEST_V4));
// Clean buffer memory
memset(request, 0x00, sizeof(REQUEST_V4));
// Create KMS Client Request Base
CreateRequestBase((REQUEST*)request);
// Create Hash
GetHash(sizeof(REQUEST), request, request + sizeof(REQUEST));
// Return Request
return request;
}
// Create Encrypted KMS Client Request Data for KMS Protocol Version 5.
PBYTE CreateRequestV5()
{
// Allocate KMS Client Request Buffer
PBYTE request = (PBYTE)midl_user_allocate(sizeof(REQUEST_V5));
// Clean buffer memory
memset(request, 0x00, sizeof(REQUEST_V5));
// Temporary Pointer for access to REQUEST_V5 structure
REQUEST_V5 *requestptr = (REQUEST_V5 *)request;
// KMS Protocol Version
requestptr->MajorVer = ClientSettings.KMSProtocolMajorVersion;
requestptr->MinorVer = ClientSettings.KMSProtocolMinorVersion;
// Seed Random Number Generator
srand(GetTickCount());
// Generate a Random Salt Key
for(int i = 0; i < 16; i++)
{
requestptr->Salt[i] = rand() % 256;
}
// Set KMS Client Request Base
CreateRequestBase(&requestptr->RequestBase);
// Encrypted Size
DWORD EncryptedSize = sizeof(requestptr->RequestBase);
// AES-128 Encrypt
AESEncryptMessage(requestptr->Salt, (PBYTE)(&requestptr->RequestBase), &EncryptedSize, sizeof(requestptr->RequestBase) + sizeof(requestptr->Pad));
// Return Request
return request;
}
// Create Encrypted KMS Client Request Data for KMS Protocol Version 6.
PBYTE CreateRequestV6()
{
// V6: AES key
BYTE AES_V6_KEY[16] = {0xA9, 0x4A, 0x41, 0x95, 0xE2, 0x01, 0x43, 0x2D, 0x9B, 0xCB, 0x46, 0x04, 0x05, 0xD8, 0x4A, 0x21};
// Allocate KMS Client Request Buffer
PBYTE request = (PBYTE)midl_user_allocate(sizeof(REQUEST_V6));
// Clean buffer memory
memset(request, 0x00, sizeof(REQUEST_V6));
// Temporary Pointer for access to REQUEST_V6 structure
REQUEST_V6 *requestptr = (REQUEST_V6 *)request;
// KMS Protocol Version
requestptr->MajorVer = ClientSettings.KMSProtocolMajorVersion;
requestptr->MinorVer = ClientSettings.KMSProtocolMinorVersion;
// Seed Random Number Generator
srand(GetTickCount());
// Generate a Random Salt Key
for(int i = 0; i < 16; i++)
{
requestptr->Salt[i] = rand() % 256;
}
// Set KMS Client Request Base
CreateRequestBase(&requestptr->RequestBase);
// Set Padding to 0x04
memset(&requestptr->Pad, 0x04, sizeof(&requestptr->Pad));
// Encrypted Size
DWORD EncryptedSize = sizeof(requestptr->RequestBase) + sizeof(requestptr->Pad);
AesInit(AES_TYPE_128, AES_MODE_CBC, 0x04, AES_V6_KEY, requestptr->Salt);
EncryptMessage(EncryptedSize, (PBYTE)(&requestptr->RequestBase));
AesClear();
// Return Request
return request;
}
// Read KMS Server Response V4 from Byte Array
void ReadResponseV4(RESPONSE_V4& Response_v4, int responseSize, PBYTE response)
{
int copySize =
sizeof(Response_v4.ResponseBase.Version) +
sizeof(Response_v4.ResponseBase.KMSPIDLength) +
(((RESPONSE_V4*)response)->ResponseBase.KMSPIDLength <= PID_BUFFER_SIZE << 1 ?
((RESPONSE_V4*)response)->ResponseBase.KMSPIDLength :
PID_BUFFER_SIZE << 1);
memcpy(&Response_v4, response, copySize);
memcpy(&Response_v4.ResponseBase.ClientMachineId, response + copySize, responseSize - copySize);
// Ensure KMSPID is NULL Terminated
Response_v4.ResponseBase.KMSPID[PID_BUFFER_SIZE - 1] = 0;
}
// Read KMS Server Response V5 from Byte Array
void ReadResponseV5(RESPONSE_V5& Response_v5, int responseSize, PBYTE response)
{
// Get Size of the First Part of the Response
int copySize1 =
sizeof(Response_v5.Version) +
sizeof(Response_v5.RequestSalt);
// Decrypt KMS Server Response (Encrypted part starts after RequestSalt)
responseSize -= copySize1;
AESDecryptMessage(((RESPONSE_V5*)(response))->RequestSalt, response + copySize1, (DWORD*)&responseSize);
// Add Size of KMS Protocol Version, KMS PID Length and KMS PID (Variable Sized)
copySize1 +=
sizeof(Response_v5.ResponseBase.Version) +
sizeof(Response_v5.ResponseBase.KMSPIDLength) +
(((RESPONSE_V5*)response)->ResponseBase.KMSPIDLength <= PID_BUFFER_SIZE << 1 ?
((RESPONSE_V5*)response)->ResponseBase.KMSPIDLength :
PID_BUFFER_SIZE << 1);
// Copy Part 1 of Response up to KMS PID (Variable Sized)
memcpy(&Response_v5, response, copySize1);
// Ensure KMSPID is NULL Terminated
Response_v5.ResponseBase.KMSPID[PID_BUFFER_SIZE - 1] = 0;
// Get Size of the Second Part of the Response
int copySize2 =
sizeof(Response_v5.ResponseBase.ClientMachineId) +
sizeof(Response_v5.ResponseBase.RequestTime) +
sizeof(Response_v5.ResponseBase.KMSCurrentCount) +
sizeof(Response_v5.ResponseBase.VLActivationInterval) +
sizeof(Response_v5.ResponseBase.VLRenewalInterval) +
sizeof(Response_v5.Salt) +
sizeof(Response_v5.Hash);
// Copy Part 2 of Response
memcpy(&Response_v5.ResponseBase.ClientMachineId, response + copySize1, copySize2);
}
// Read KMS Server Response V6 from Byte Array
void ReadResponseV6(RESPONSE_V6& Response_v6, int responseSize, PBYTE response)
{
// V6: AES key
BYTE AES_V6_KEY[16] = {0xA9, 0x4A, 0x41, 0x95, 0xE2, 0x01, 0x43, 0x2D, 0x9B, 0xCB, 0x46, 0x04, 0x05, 0xD8, 0x4A, 0x21};
// Get Size of the First Part of the Response
int copySize =
sizeof(Response_v6.Version) +
sizeof(Response_v6.RequestSalt);
// Read the first part.
memcpy(&Response_v6, response, copySize);
response += copySize;
responseSize -= copySize;
// Decrypt the response.
AesInit(AES_TYPE_128, AES_MODE_CBC, 0x04, AES_V6_KEY, Response_v6.RequestSalt);
DecryptMessage(responseSize, response);
AesClear();
// Read version.
copySize = sizeof(Response_v6.ResponseBase.Version);
memcpy(&Response_v6.ResponseBase.Version, response, copySize);
response += copySize;
responseSize -= copySize;
// Read KMS PID length.
copySize = sizeof(Response_v6.ResponseBase.KMSPIDLength);
memcpy(&Response_v6.ResponseBase.KMSPIDLength, response, copySize);
response += copySize;
responseSize -= copySize;
// Read KMS PID.
copySize = Response_v6.ResponseBase.KMSPIDLength <= PID_BUFFER_SIZE << 1 ? Response_v6.ResponseBase.KMSPIDLength : PID_BUFFER_SIZE << 1;
memcpy(&Response_v6.ResponseBase.KMSPID, response, copySize);
response += copySize;
responseSize -= copySize;
// Ensure KMSPID is NULL Terminated
Response_v6.ResponseBase.KMSPID[PID_BUFFER_SIZE - 1] = 0;
// Read the rest into the structure.
memcpy(&Response_v6.ResponseBase.ClientMachineId, response, responseSize);
}
// Function to Send Request to KMS Server
// Used to allow use of RpcTryExcept
int SendRequest(PBYTE request, const int requestsSent, int* const requestsNeeded)
{
RpcTryExcept
{
// Allocate Memory for Response
int responseSize = MAX_RESPONSE_SIZE;
PBYTE resp = (PBYTE)midl_user_allocate(MAX_RESPONSE_SIZE);
if (ClientSettings.KMSProtocolMajorVersion == 4)
{
// Call KMS Server via RPC for V4
ActivationRequest(KMSServer_v1_0_c_ifspec, sizeof(REQUEST_V4), request, &responseSize, &resp);
}
else if (ClientSettings.KMSProtocolMajorVersion == 5)
{
// Call KMS Server via RPC for V5
ActivationRequest(KMSServer_v1_0_c_ifspec, sizeof(REQUEST_V5), request, &responseSize, &resp);
}
else
{
// Call KMS Server via RPC for V6
ActivationRequest(KMSServer_v1_0_c_ifspec, sizeof(REQUEST_V6), request, &responseSize, &resp);
}
// Verify Response Was Received
if (resp == NULL)
{
ClientWriteLogErrorTerminate(L"Failed to get Activation response.\n", -1);
}
// Determine how many more requests are needed.
if (requestsSent < 1)
{
// Place to Store Base Response Data
RESPONSE response;
// KMSPID from Response
WCHAR* KMSPID = L"";
// KMSHWID from Response
WCHAR KMSHWID[256];
// ActivatedMachines from Response
DWORD ActivatedMachines;
if (ClientSettings.KMSProtocolMajorVersion == 4)
{
// Get KMS Server Response Object
RESPONSE_V4 response_v4;
ReadResponseV4(response_v4, responseSize, resp);
// Get Base KMS Server Response Object
response = response_v4.ResponseBase;
// Read KMSPID from Response
KMSPID = response.KMSPID;
// Read ActivatedMachines from Response
ActivatedMachines = response.KMSCurrentCount;
}
else if (ClientSettings.KMSProtocolMajorVersion == 5)
{
// Get KMS Server Response Object
RESPONSE_V5 response_v5;
ReadResponseV5(response_v5, responseSize, resp);
// Get Base KMS Server Response Object
response = response_v5.ResponseBase;
// Read KMSPID from Response
KMSPID = response.KMSPID;
// Read ActivatedMachines from Response
ActivatedMachines = response.KMSCurrentCount;
}
else
{
// Get KMS Server Response Object
RESPONSE_V6 response_v6;
ReadResponseV6(response_v6, responseSize, resp);
// Get Base KMS Server Response Object
response = response_v6.ResponseBase;
// Read KMSPID from Response
KMSPID = response.KMSPID;
// Read KMSHWID from Response
swprintf_s(KMSHWID, 256, L"%02X%02X%02X%02X%02X%02X%02X%02X", response_v6.MachineHardwareHash[7], response_v6.MachineHardwareHash[6], response_v6.MachineHardwareHash[5], response_v6.MachineHardwareHash[4], response_v6.MachineHardwareHash[3], response_v6.MachineHardwareHash[2], response_v6.MachineHardwareHash[1], response_v6.MachineHardwareHash[0]);
// Read ActivatedMachines from Response
ActivatedMachines = response.KMSCurrentCount;
}
ClientWriteLogInformation(L"Successfully received response from KMS Server.\n");
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"KMS Server PID: %s.\n", KMSPID);
ClientWriteLogInformation(Message);
if (ClientSettings.KMSProtocolMajorVersion > 5)
{
swprintf_s(Message, 256, L"KMS Server HWID: %s.\n", KMSHWID);
ClientWriteLogInformation(Message);
}
// Send no more requests if the client count was sufficient.
if (ActivatedMachines >= ClientSettings.RequiredClientCount)
{
*requestsNeeded = 1;
}
// Send as many requests as needed.
else
{
*requestsNeeded = (ClientSettings.RequiredClientCount - ActivatedMachines) + 1;
}
}
return 0;
}
RpcExcept(1)
{
// Get RPC Exception Code
unsigned long ulCode = RpcExceptionCode();
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"Runtime reported exception 0x%lx = %ld\n", ulCode, ulCode);
ClientWriteLogErrorTerminate(Message, ulCode);
// Return
return false;
}
RpcEndExcept
}
#pragma endregion
#pragma region Parameter Validation Functions
// Validate KMS Port Parameter
void ClientValidateKMSPort(WCHAR* KMSPort)
{
// Check if the KMS Port is not the Default
if (CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, KMSPort, -1, L"DefaultPort", -1) != CSTR_EQUAL)
{
// Check if KMS Port is Valid Number
if (regex_match(KMSPort, wregex(L"^([0-9]+)$")))
{
// Check if KMS Port is Valid Range
if(_wtoi(KMSPort) < 1 || _wtoi(KMSPort) > 65535)
{
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"Invalid KMS Port Range! %s is not a valid argument.\n", KMSPort);
ClientWriteLogErrorTerminate(Message, -1);
}
else
{
// Apply Setting
StringCchCopyW(ClientSettings.KMSPort, PORT_BUFFER_SIZE, KMSPort);
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"KMS Port: %s \n", KMSPort);
ClientWriteLogInformation(Message);
}
}
else
{
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"Invalid KMS Port! %s is not a valid argument.\n", KMSPort);
ClientWriteLogErrorTerminate(Message, -1);
}
}
}
// Validate KMS Host Parameter
void ClientValidateKMSHost(WCHAR* KMSHost)
{
// Check if the KMS PID is not the Default
if (CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, KMSHost, -1, L"DefaultHost", -1) != CSTR_EQUAL)
{
// Apply Setting
StringCchCopyW(ClientSettings.KMSHost, 256, KMSHost);
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"KMS Host: %s \n", KMSHost);
ClientWriteLogInformation(Message);
}
}
// Validate KMS Client Mode
void ClientValidateKMSClientMode(WCHAR* KMSClientMode)
{
// Check if KMS Client Mode is Valid
if (CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, KMSClientMode, -1, L"Windows", -1) == CSTR_EQUAL || CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, KMSClientMode, -1, L"WindowsVista", -1) == CSTR_EQUAL)
{
ClientSettings.RequiredClientCount = 25;
ClientSettings.KMSProtocolMajorVersion = 4;
StringCchCopyW(ClientSettings.KMSClientAppID, GUID_BUFFER_SIZE, L"55c92734-d682-4d71-983e-d6ec3f16059f");
StringCchCopyW(ClientSettings.KMSClientSkuID, GUID_BUFFER_SIZE, L"cfd8ff08-c0d7-452b-9f60-ef5c70c32094");
StringCchCopyW(ClientSettings.KMSClientKMSCountedID, GUID_BUFFER_SIZE, L"212a64dc-43b1-4d3d-a30c-2fc69d2095c6");
}
else if (CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, KMSClientMode, -1, L"Windows7", -1) == CSTR_EQUAL)
{
ClientSettings.RequiredClientCount = 25;
ClientSettings.KMSProtocolMajorVersion = 4;
StringCchCopyW(ClientSettings.KMSClientAppID, GUID_BUFFER_SIZE, L"55c92734-d682-4d71-983e-d6ec3f16059f");
StringCchCopyW(ClientSettings.KMSClientSkuID, GUID_BUFFER_SIZE, L"ae2ee509-1b34-41c0-acb7-6d4650168915");
StringCchCopyW(ClientSettings.KMSClientKMSCountedID, GUID_BUFFER_SIZE, L"7fde5219-fbfa-484a-82c9-34d1ad53e856");
}
else if (CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, KMSClientMode, -1, L"Windows8", -1) == CSTR_EQUAL)
{
ClientSettings.RequiredClientCount = 25;
ClientSettings.KMSProtocolMajorVersion = 5;
StringCchCopyW(ClientSettings.KMSClientAppID, GUID_BUFFER_SIZE, L"55c92734-d682-4d71-983e-d6ec3f16059f");
StringCchCopyW(ClientSettings.KMSClientSkuID, GUID_BUFFER_SIZE, L"458e1bec-837a-45f6-b9d5-925ed5d299de");
StringCchCopyW(ClientSettings.KMSClientKMSCountedID, GUID_BUFFER_SIZE, L"3c40b358-5948-45af-923b-53d21fcc7e79");
}
else if (CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, KMSClientMode, -1, L"Windows81", -1) == CSTR_EQUAL)
{
ClientSettings.RequiredClientCount = 25;
ClientSettings.KMSProtocolMajorVersion = 6;
StringCchCopyW(ClientSettings.KMSClientAppID, GUID_BUFFER_SIZE, L"55c92734-d682-4d71-983e-d6ec3f16059f");
StringCchCopyW(ClientSettings.KMSClientSkuID, GUID_BUFFER_SIZE, L"81671aaf-79d1-4eb1-b004-8cbbe173afea");
StringCchCopyW(ClientSettings.KMSClientKMSCountedID, GUID_BUFFER_SIZE, L"cb8fc780-2c05-495a-9710-85afffc904d7");
}
else if (CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, KMSClientMode, -1, L"Office2010", -1) == CSTR_EQUAL)
{
ClientSettings.RequiredClientCount = 5;
ClientSettings.KMSProtocolMajorVersion = 4;
StringCchCopyW(ClientSettings.KMSClientAppID, GUID_BUFFER_SIZE, L"59a52881-a989-479d-af46-f275c6370663");
StringCchCopyW(ClientSettings.KMSClientSkuID, GUID_BUFFER_SIZE, L"6f327760-8c5c-417c-9b61-836a98287e0c");
StringCchCopyW(ClientSettings.KMSClientKMSCountedID, GUID_BUFFER_SIZE, L"e85af946-2e25-47b7-83e1-bebcebeac611");
}
else if (CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, KMSClientMode, -1, L"Office2013", -1) == CSTR_EQUAL ||
CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, KMSClientMode, -1, L"Office2013V4", -1) == CSTR_EQUAL)
{
ClientSettings.RequiredClientCount = 5;
ClientSettings.KMSProtocolMajorVersion = 4;
StringCchCopyW(ClientSettings.KMSClientAppID, GUID_BUFFER_SIZE, L"0ff1ce15-a989-479d-af46-f275c6370663");
StringCchCopyW(ClientSettings.KMSClientSkuID, GUID_BUFFER_SIZE, L"b322da9c-a2e2-4058-9e4e-f59a6970bd69");
StringCchCopyW(ClientSettings.KMSClientKMSCountedID, GUID_BUFFER_SIZE, L"e6a6f1bf-9d40-40c3-aa9f-c77ba21578c0");
}
else if (CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, KMSClientMode, -1, L"Office2013V5", -1) == CSTR_EQUAL)
{
ClientSettings.RequiredClientCount = 5;
ClientSettings.KMSProtocolMajorVersion = 5;
StringCchCopyW(ClientSettings.KMSClientAppID, GUID_BUFFER_SIZE, L"0ff1ce15-a989-479d-af46-f275c6370663");
StringCchCopyW(ClientSettings.KMSClientSkuID, GUID_BUFFER_SIZE, L"b322da9c-a2e2-4058-9e4e-f59a6970bd69");
StringCchCopyW(ClientSettings.KMSClientKMSCountedID, GUID_BUFFER_SIZE, L"e6a6f1bf-9d40-40c3-aa9f-c77ba21578c0");
}
else if (CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, KMSClientMode, -1, L"Office2013V6", -1) == CSTR_EQUAL)
{
ClientSettings.RequiredClientCount = 5;
ClientSettings.KMSProtocolMajorVersion = 6;
StringCchCopyW(ClientSettings.KMSClientAppID, GUID_BUFFER_SIZE, L"0ff1ce15-a989-479d-af46-f275c6370663");
StringCchCopyW(ClientSettings.KMSClientSkuID, GUID_BUFFER_SIZE, L"b322da9c-a2e2-4058-9e4e-f59a6970bd69");
StringCchCopyW(ClientSettings.KMSClientKMSCountedID, GUID_BUFFER_SIZE, L"e6a6f1bf-9d40-40c3-aa9f-c77ba21578c0");
}
else
{
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"Invalid KMS Client Type! %s is not a valid argument.\n", KMSClientMode);
ClientWriteLogErrorTerminate(Message, -1);
}
// Apply Setting
StringCchCopyW(ClientSettings.KMSClientMode, 256, KMSClientMode);
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"KMS Client Mode: %s \n", KMSClientMode);
ClientWriteLogInformation(Message);
}
#pragma endregion
#pragma region Logging Functions
// Log an informational message to the Console or Windows Application Event Log.
void ClientWriteLogInformation(WCHAR* const Message)
{
// Log Message Buffer
WCHAR logMessage[256];
// Write Log Message to Buffer
StringCbPrintfW(logMessage, 256, Message);
// Choose Log Source
if (ClientSettings.RunAsService)
{
// Output to Windows Event Log: Qualifiers: 16384, EventId: 12290
ClientWriteEventLogEntry(0x40003002, logMessage, EVENTLOG_INFORMATION_TYPE);
}
else
{
// Output to Console
wprintf(L"%s", logMessage);
}
}
// Log an error message to the Console or Windows Application Event Log.
void ClientWriteLogError(WCHAR* const Message)
{
// Log Message Buffer
WCHAR logMessage[256];
// Write Log Message to Buffer
StringCbPrintfW(logMessage, 256, Message);
// Choose Log Source
if (ClientSettings.RunAsService)
{
// Output to Windows Event Log: Qualifiers: 16384, EventId: 902
ClientWriteEventLogEntry(0x40000386, logMessage, EVENTLOG_ERROR_TYPE);
}
else
{
// Output to Console
wprintf(L"%s", logMessage);
}
}
// Log an error message to the Console or Windows Application Event Log and terminate program.
void ClientWriteLogErrorTerminate(WCHAR* const Message, int ExitCode)
{
// Call ClientWriteLogError
ClientWriteLogError(Message);
if (!ClientSettings.RunAsService)
{
// Exit Program
exit(ExitCode);
}
else
{
// Exit Service
ClientServiceStatus.dwCurrentState = SERVICE_STOPPED;
ClientServiceStatus.dwWin32ExitCode = ExitCode;
SetServiceStatus(ClientServiceHandle, &ClientServiceStatus);
}
}
// Log a message to the Windows Application Event Log.
void ClientWriteEventLogEntry(DWORD dwIdentifier, WCHAR* const lpszMessage, WORD wType)
{
HANDLE hEventSource = OpenEventLogW(NULL, L"KmsRequests"); // Provider: KmsRequests or Microsoft-Windows-Security-SPP
if(hEventSource != NULL)
{
ReportEventW(
hEventSource, // Event log handle
wType, // Event type
NULL, // Event category
dwIdentifier, // Event identifier
NULL, // No security identifier
1, // Size of lpszStrings array
NULL, // No binary data
(LPCWSTR*)&lpszMessage, // Array of strings
NULL // No binary data
);
CloseEventLog(hEventSource);
}
}
#pragma endregion
+35
View File
@@ -0,0 +1,35 @@
// Includes and Namespaces
#include "KMSClientSettings.h"
// KMS Client Parameters
WCHAR KMSClientSettings::KMSHost[256];
WCHAR KMSClientSettings::KMSPort[PORT_BUFFER_SIZE];
WCHAR KMSClientSettings::KMSClientMode[256];
// KMS Client Identification Data
DWORD KMSClientSettings::RequiredClientCount;
WORD KMSClientSettings::KMSProtocolMajorVersion;
WORD KMSClientSettings::KMSProtocolMinorVersion;
DWORD KMSClientSettings::KMSClientLicenseStatus;
WCHAR KMSClientSettings::KMSClientAppID[GUID_BUFFER_SIZE];
WCHAR KMSClientSettings::KMSClientSkuID[GUID_BUFFER_SIZE];
WCHAR KMSClientSettings::KMSClientKMSCountedID[GUID_BUFFER_SIZE];
// KMS Client Program Control
bool KMSClientSettings::RunAsService;
// Set Default Settings
void KMSClientSettings::Initialize()
{
StringCchCopyW(KMSHost, 256, L"127.0.0.2");
StringCchCopyW(KMSPort, PORT_BUFFER_SIZE, L"1688");
StringCchCopyW(KMSClientMode, 256, L"Windows");
RequiredClientCount = 25;
KMSProtocolMajorVersion = 4;
KMSProtocolMinorVersion = 0;
KMSClientLicenseStatus = 2;
StringCchCopyW(KMSClientAppID, GUID_BUFFER_SIZE, L"55c92734-d682-4d71-983e-d6ec3f16059f");
StringCchCopyW(KMSClientSkuID, GUID_BUFFER_SIZE, L"cfd8ff08-c0d7-452b-9f60-ef5c70c32094");
StringCchCopyW(KMSClientKMSCountedID, GUID_BUFFER_SIZE, L"212a64dc-43b1-4d3d-a30c-2fc69d2095c6");
RunAsService = false;
};
+40
View File
@@ -0,0 +1,40 @@
// Includes and Namespaces
#include "KMSHWID.h"
using namespace std;
// Get Application Specific KMSHWID from the Registry (KMS Server Service Only)
void GetKMSHWID(PQWORD KMSHWID, REQUEST* const Request)
{
// Open Registry Key
HKEY hKey;
DWORD bufferSize = 256;
WCHAR buffer[256] = {0};
// Get ClientAppID as String
WCHAR ClientAppID[GUID_BUFFER_SIZE];
StringCchPrintfW(ClientAppID, GUID_BUFFER_SIZE, L"%08X-%04hX-%04hX-%02X%02X-%02X%02X%02X%02X%02X%02X", Request->ApplicationId.Data1, Request->ApplicationId.Data2, Request->ApplicationId.Data3, Request->ApplicationId.Data4[0], Request->ApplicationId.Data4[1], Request->ApplicationId.Data4[2], Request->ApplicationId.Data4[3], Request->ApplicationId.Data4[4], Request->ApplicationId.Data4[5], Request->ApplicationId.Data4[6], Request->ApplicationId.Data4[7]);
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\KMSServerService\\Parameters\\KMSHWID"), NULL, KEY_READ, &hKey) == ERROR_SUCCESS)
{
// Get Registry Value
if (RegQueryValueExW(hKey, ClientAppID, NULL, NULL, (LPBYTE)buffer, &bufferSize) == ERROR_SUCCESS)
{
if (regex_match(buffer, wregex(L"^[a-fA-F0-9]{16}$")))
{
// Close Registry Key
RegCloseKey(hKey);
// Apply Setting
*KMSHWID = wcstoull(buffer, NULL, 16);
}
}
// Close Registry Key
RegCloseKey(hKey);
}
else
{
// Return NULL KMSHWID
*KMSHWID = 0x0;
}
}
+176
View File
@@ -0,0 +1,176 @@
// Includes and Namespaces
#include "KMSPID.h"
#pragma region Structs
// HostType and OSBuild
static const struct KMSHostOS { WORD Type; WORD Build; } HostOS[] =
{
{ 55041, 7601 }, // Windows Server 2008 R2 SP1
{ 5426, 9200 }, // Windows Server 2012
{ 6401, 9600 }, // Windows Server 2012 R2
};
// GroupID and PIDRange
static const struct PKEYCONFIG { WORD GroupID; DWORD RangeMin; DWORD RangeMax; } pkeyconfig[] = {
{ 206, 152000000, 152999999 }, // Windows Server 2012 KMS Host pkeyconfig, actual max is 191999999
{ 206, 271000000, 271999999 }, // Windows Server 2012 R2 KMS Host pkeyconfig, actual max is 310999999
{ 96, 199000000, 201999999 }, // Office2010 KMS Host pkeyconfig, actual max is 217999999
{ 206, 234000000, 234999999 }, // Office2013 KMS Host pkeyconfig, actual max is 255999999
};
#pragma endregion
#pragma region Defines
// Defines
static const GUID APP_ID_WINDOWS = {0x55C92734, 0xD682, 0x4D71, {0x98, 0x3E, 0xD6, 0xEC, 0x3F, 0x16, 0x05, 0x9F}};
static const GUID APP_ID_OFFICE14 = {0x59A52881, 0xA989, 0x479D, {0xAF, 0x46, 0xF2, 0x75, 0xC6, 0x37, 0x06, 0x63}};
static const GUID APP_ID_OFFICE15 = {0x0FF1CE15, 0xA989, 0x479D, {0xAF, 0x46, 0xF2, 0x75, 0xC6, 0x37, 0x06, 0x63}};
#define HOST_SERVER2008R2 0
#define HOST_SERVER2012 1
#define HOST_SERVER2012R2 2
#define PKEYCONFIG_SERVER2012_CSVLK 0
#define PKEYCONFIG_SERVER2012R2_CSVLK 1
#define PKEYCONFIG_OFFICE2010_CSVLK 2
#define PKEYCONFIG_OFFICE2013_CSVLK 3
// Minimum possible activation date for each Microsoft products (in UTC seconds)
#define MinDateServer2008R2 ((time_t)1297875600LL) // Available on February 16, 2011 through TechNet or MSDN
#define MinDateServer2012 ((time_t)1346778000LL) // Available on September 4, 2012 through TechNet or MSDN
#define MinDateOffice2013 ((time_t)1351098000LL) // Available on October 24, 2012 through TechNet or MSDN
#define MinDateServer2012R2 ((time_t)1382029200LL) // Available on October 17, 2013 through TechNet or MSDN
// Macros
#define countof( array ) ( sizeof( array )/sizeof( array[0] ) )
#pragma endregion
using namespace std;
// Get GroupID and PIDRange for the specified AppID and KMS Protocol Version
static const PKEYCONFIG *GetKMSHostPkeyConfig(REQUEST* const Request)
{
if (Request->ApplicationId == APP_ID_WINDOWS)
return (Request->MajorVer == 6 ? &pkeyconfig[PKEYCONFIG_SERVER2012R2_CSVLK] : &pkeyconfig[PKEYCONFIG_SERVER2012_CSVLK]);
if (Request->ApplicationId == APP_ID_OFFICE15)
return &pkeyconfig[PKEYCONFIG_OFFICE2013_CSVLK];
if (Request->ApplicationId == APP_ID_OFFICE14)
return &pkeyconfig[PKEYCONFIG_OFFICE2010_CSVLK];
return &pkeyconfig[PKEYCONFIG_SERVER2012_CSVLK];
}
// Calculate Minimum Possible Date of KMS Host
static const time_t GetMinKMSHostBuildDate(int HostIndex, REQUEST* const Request)
{
// Request is KMS V6 or Server 2012 R2 Build # is used
if (Request->MajorVer == 6 || HostIndex == HOST_SERVER2012R2)
return MinDateServer2012R2;
// Request is Office 2013 (Both V4 and V5)
if (Request->ApplicationId == APP_ID_OFFICE15)
return MinDateOffice2013;
// Request is KMS V5 or Server 2012 Build # is used
if (Request->MajorVer == 5 || HostIndex == HOST_SERVER2012)
return MinDateServer2012;
// Otherwise, Request is KMS V4 (Office 2010/Vista/7) and Server 2008 R2 Build # is used
return MinDateServer2008R2;
}
// Random Number Generator
BOOL GetRandomBytes(BYTE *RandomBuffer, DWORD RandomBufferLength)
{
BOOL success = FALSE;
HCRYPTPROV hProv = NULL;
success = CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT) &&
CryptGenRandom(hProv, RandomBufferLength, RandomBuffer);
if (hProv)
CryptReleaseContext(hProv, 0);
return success;
}
void CreateKMSPID(WCHAR* const KMSPID, REQUEST* const Request)
{
// Random Number Buffer
DWORD RandomNumber[4];
GetRandomBytes((BYTE *)RandomNumber, sizeof(RandomNumber));
// Choose KMS HostOS
int HostIndex = RandomNumber[0] % countof(HostOS);
const KMSHostOS *host = &HostOS[HostIndex];
// Set Product Specific Base pkeyconfig (use Windows if unknown product)
const PKEYCONFIG *config = GetKMSHostPkeyConfig(Request);
// Generate Random ID
int RandomID = config->RangeMin + RandomNumber[1] % (config->RangeMax - config->RangeMin);
// Generate Part 5: License Channel (00=Retail, 01=Retail, 02=OEM, 03=Volume(GVLK,MAK)) - always 03
DWORD LicenseChannel = 3;
// Generate Part 6: Language - use system default language
DWORD LanguageCode = GetSystemDefaultLCID();
// Get Product Specific Minimum Activation Date
time_t MinDate = GetMinKMSHostBuildDate(HostIndex, Request);
// Get Maximum Possible Value of Activation Date
time_t MaxDate = time(NULL) - 86400; // limit latest activation date to yesterday
// Generate Random Date between MinDate and MaxDate
time_t RandomDate = ((ULONG64 *)RandomNumber)[1] & 0x7FFFFFFFFFFFFFFFULL;
time_t GeneratedDate = MinDate + RandomDate % (MaxDate - MinDate);
struct tm Date;
localtime_s(&Date, &GeneratedDate);
StringCchPrintfW(KMSPID, PID_BUFFER_SIZE, L"%05u-%05u-%03u-%06u-%02u-%u-%04u.0000-%03d%04d",
host->Type, config->GroupID, RandomID / 1000000, RandomID % 1000000, LicenseChannel,
LanguageCode, host->Build, Date.tm_yday+1, Date.tm_year+1900);
}
// Get Application Specific KMS PID from the Registry (KMS Server Service Only)
void GetKMSPID(WCHAR* const KMSPID, REQUEST* const Request)
{
// Open Registry Key
HKEY hKey;
DWORD bufferSize = 256;
WCHAR buffer[256] = {0};
// Get ClientAppID as String
WCHAR ClientAppID[GUID_BUFFER_SIZE];
StringCchPrintfW(ClientAppID, GUID_BUFFER_SIZE, L"%08X-%04hX-%04hX-%02X%02X-%02X%02X%02X%02X%02X%02X", Request->ApplicationId.Data1, Request->ApplicationId.Data2, Request->ApplicationId.Data3, Request->ApplicationId.Data4[0], Request->ApplicationId.Data4[1], Request->ApplicationId.Data4[2], Request->ApplicationId.Data4[3], Request->ApplicationId.Data4[4], Request->ApplicationId.Data4[5], Request->ApplicationId.Data4[6], Request->ApplicationId.Data4[7]);
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\KMSServerService\\Parameters\\KMSPID"), NULL, KEY_READ, &hKey) == ERROR_SUCCESS)
{
// Get Registry Value
if (RegQueryValueExW(hKey, ClientAppID, NULL, NULL, (LPBYTE)buffer, &bufferSize) == ERROR_SUCCESS)
{
if (regex_match(buffer, wregex(L"^([0-9]{5})-([0-9]{5})-([0-9]{3})-([0-9]{6})-([0-9]{2})-([0-9]{4,5})-([0-9]{4}).([0-9]{4})-([0-9]{7})$")))
{
// Close Registry Key
RegCloseKey(hKey);
// Apply Setting
StringCchCopyW(KMSPID, PID_BUFFER_SIZE, buffer);
}
}
// Close Registry Key
RegCloseKey(hKey);
}
else
{
// Return Empty KMSPID
StringCchCopyW(KMSPID, PID_BUFFER_SIZE, L"");
}
}
+14
View File
@@ -0,0 +1,14 @@
[
uuid(51C82175-844E-4750-B0D8-EC255555BC06),
version(1.0),
]
interface KMSServer
{
int RequestActivation
(
[in] int requestSize,
[in, size_is(requestSize)] unsigned char* request,
[out] int* responseSize,
[out, size_is( , *responseSize)] unsigned char** response
);
}
+949
View File
@@ -0,0 +1,949 @@
// Includes and Namespaces
#include <regex>
#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <string>
#include "Crypto.h"
#include "Hash.h"
#include "KMSPID.h"
#include "KMSHWID.h"
#include "KMSServer.h"
#include "KMSServerLogic.h"
#include "KMSServerSettings.h"
using namespace std;
// Link Libraries
#pragma comment(lib, "rpcrt4.lib")
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")
// Hold KMS Server Settings
KMSServerSettings ServerSettings;
// Windows Service Parameters for Service Application
SERVICE_STATUS ServerServiceStatus;
SERVICE_STATUS_HANDLE ServerServiceHandle;
// Defined in Hash.cpp
extern HMAC_KEYBLOB Hmac_keyblob;
#pragma region Application Initialization Functions
// Load Application Parameters from Command-Line or Registry.
void LoadServerParameters(int argc, wchar_t* argv[], bool RunAsService)
{
// Initialize KMS Server Settings Object
ServerSettings.Initialize();
ServerSettings.RunAsService = RunAsService;
if (!RunAsService)
{
#pragma region Command-Line
// Handle Command-Line Arguments (KMS Port or Help)
if (argc >= 2)
{
if (CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, argv[1], -1, L"/?", -1) == CSTR_EQUAL)
{
printf("Usage:\n");
printf("[KMS Port] [KMS PID] [KMS HWID] [Activation Interval] [Renewal Interval] [Kill Processes]\n\n");
printf("KMS Port:\n");
printf("\tDefaultPort:\t\tUse the built-in KMS Port.\n");
printf("\tInteger:\t\tNumber from 1 to 65535.\n\n");
printf("KMS PID:\n");
printf("\tRandomKMSPID:\t\tGenerate a random KMS PID.\n");
printf("\tString:\t\t\tA Microsoft Extended Product Key ID.\n\n");
printf("KMS HWID:\n");
printf("\tDefaultKMSHWID:\t\tUse the built-in KMS HWID.\n");
printf("\tString:\t\t\t16 Hex character KMS HWID (No 0x).\n\n");
printf("Activation Interval:\n");
printf("\tDefaultAI:\t\tUse the built-in Activation Interval.\n");
printf("\tInteger:\t\tNumber (in minutes) from 15 to 43200.\n\n");
printf("Renewal Interval:\n");
printf("\tDefaultRI:\t\tUse the built-in Renewal Interval.\n");
printf("\tInteger:\t\tNumber (in minutes) from 15 to 43200.\n\n");
printf("Kill Processes:\n");
printf("\tKillProcessOnPort:\tForce open the KMS Port if this is present.\n\n");
printf("Example:\n");
printf("\tC:\\>\"KMS Server.exe\" 1688 RandomKMSPID DefaultKMSHWID 43200 43200 KillProcessOnPort");
ServerWriteLogErrorTerminate(L"\n", -1);
}
else
{
ServerValidateKMSPort(argv[1]);
}
}
// Handle Command-Line Arguments (KMS PID)
if (argc >= 3)
{
ServerValidateKMSPID(argv[2]);
}
// Handle Command-Line Arguments (KMS HWID)
if (argc >= 4)
{
ServerValidateKMSHWID(argv[3]);
}
// Handle Command-Line Arguments (Activation Interval)
if (argc >= 5)
{
if (CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, argv[4], -1, L"DefaultAI", -1) != CSTR_EQUAL)
{
// Check if Activation Interval is Valid Number
if (regex_match(argv[4], wregex(L"^([0-9]+)$")))
{
ServerValidateVLActivationInterval(_wtoi(argv[4]));
}
else
{
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"Invalid KMS Activation Interval! %s is not a valid argument.\n", argv[4]);
ServerWriteLogErrorTerminate(Message, -1);
}
}
}
// Handle Command-Line Arguments (Renewal Interval)
if (argc >= 6)
{
if (CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, argv[5], -1, L"DefaultRI", -1) != CSTR_EQUAL)
{
// Check if Renewal Interval is Valid Number
if (regex_match(argv[5], wregex(L"^([0-9]+)$")))
{
ServerValidateVLRenewalInterval(_wtoi(argv[5]));
}
else
{
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"Invalid KMS Renewal Interval! %s is not a valid argument.\n", argv[5]);
ServerWriteLogErrorTerminate(Message, -1);
}
}
}
// Handle Command-Line Arguments (Free TCP/IP)
if (argc >= 7)
{
if (CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, argv[6], -1, L"KillProcessOnPort", -1) == CSTR_EQUAL)
{
// Apply Setting
ServerSettings.KillProcesses = true;
ServerWriteLogInformation(L"KMS Port Process Termination: Enabled \n");
}
else
{
// Apply Setting
ServerSettings.KillProcesses = false;
ServerWriteLogInformation(L"KMS Port Process Termination: Disabled \n");
}
}
#pragma endregion
}
else
{
#pragma region Registry
// Create Buffers for Values
WCHAR KMSPID[256] = {0};
WCHAR KMSHWID[256] = {0};
WCHAR KMSPort[256] = {0};
DWORD VLActivationInterval = 0;
DWORD VLRenewalInterval = 0;
DWORD KillProcesses = 0;
// Open Registry Key
HKEY hKey;
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\KMSServerService\\Parameters", NULL, KEY_READ, &hKey) == ERROR_SUCCESS)
{
// Buffer Size
DWORD bufferSize = 0;
// Handle Registry Parameters (KMS PID)
bufferSize = 256;
RegQueryValueExW(hKey, L"KMSPID", NULL, NULL, (LPBYTE)KMSPID, &bufferSize);
// Handle Registry Parameters (KMS HWID)
bufferSize = 256;
RegQueryValueExW(hKey, L"KMSHWID", NULL, NULL, (LPBYTE)KMSHWID, &bufferSize);
// Handle Registry Parameters (KMS Port)
bufferSize = 256;
RegQueryValueExW(hKey, L"KMSPort", NULL, NULL, (LPBYTE)KMSPort, &bufferSize);
// Handle Registry Parameters (Activation Interval)
bufferSize = sizeof(DWORD);
RegQueryValueExW(hKey, L"VLActivationInterval", NULL, NULL, (LPBYTE)&VLActivationInterval, &bufferSize);
// Handle Registry Parameters (Renewal Interval)
bufferSize = sizeof(DWORD);
RegQueryValueExW(hKey, L"VLRenewalInterval", NULL, NULL, (LPBYTE)&VLRenewalInterval, &bufferSize);
// Handle Registry Parameters (Free TCP/IP)
bufferSize = sizeof(DWORD);
RegQueryValueExW(hKey, L"KillProcessOnPort", NULL, NULL, (LPBYTE)&KillProcesses, &bufferSize);
// Close Registry Key
RegCloseKey(hKey);
}
// Validate Values
ServerValidateKMSPort(KMSPort);
ServerValidateKMSPID(KMSPID);
ServerValidateKMSHWID(KMSHWID);
ServerValidateVLActivationInterval(VLActivationInterval);
ServerValidateVLRenewalInterval(VLRenewalInterval);
// Handle External Process Termination
if (KillProcesses > 0)
{
// Apply Setting
ServerSettings.KillProcesses = true;
ServerWriteLogInformation(L"KMS Port Process Termination: Enabled \n");
}
else
{
// Apply Setting
ServerSettings.KillProcesses = false;
ServerWriteLogInformation(L"KMS Port Process Termination: Disabled \n");
}
#pragma endregion
}
}
// Start RPC Connection and listen indefinitely for KMS Clients.
void StartKMSServer()
{
// Uses the protocol combined with the endpoint for receiving remote procedure calls.
RPC_STATUS status = RpcServerUseProtseqEp
(
// Use TCP/IP protocol.
(RPC_WSTR)L"ncacn_ip_tcp",
// Backlog queue length for TCP/IP.
RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
// TCP/IP port to use.
(RPC_WSTR)ServerSettings.KMSPort,
// No security.
NULL
);
if (status)
{
// TCP/IP Port in Use
if (status == RPC_S_DUPLICATE_ENDPOINT && ServerSettings.KillProcesses)
{
// TCP Table and TCP Table Size
MIB_TCPTABLE_OWNER_PID *pTCPInfo;
DWORD dwSize = 0;
// Get TCP Table Size
GetExtendedTcpTable(NULL, &dwSize, true, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0);
// Allocate Memory for TCP Table
pTCPInfo = (MIB_TCPTABLE_OWNER_PID*)malloc(dwSize);
// Get TCP Table Data
GetExtendedTcpTable(pTCPInfo, &dwSize, true, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0);
// Read TCP Table Data
for (DWORD i = 0; i < pTCPInfo->dwNumEntries; i++)
{
// Get Process ID, Opened Port of the Process and KMS Port
DWORD processID = pTCPInfo->table[i].dwOwningPid;
DWORD kmsport = _wtoi(ServerSettings.KMSPort);
DWORD port = ntohs((u_short)pTCPInfo->table[i].dwLocalPort);
// Check if this Process has the KMS Port
if (port == kmsport)
{
// Enable Debug Privileges
HANDLE tokenHandle;
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &tokenHandle);
TOKEN_PRIVILEGES privilegeToken;
LookupPrivilegeValue(0, SE_DEBUG_NAME, &privilegeToken.Privileges[0].Luid);
privilegeToken.PrivilegeCount = 1;
privilegeToken.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(tokenHandle, 0, &privilegeToken, sizeof(TOKEN_PRIVILEGES), 0, 0);
CloseHandle(tokenHandle);
// Kill Process using the KMS Port
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, processID);
if (hProcess != NULL)
{
TerminateProcess(hProcess, 0);
CloseHandle(hProcess);
}
else
{
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"Failed to get handle to kill Process ID: %i.\n", processID);
ServerWriteLogErrorTerminate(Message, -1);
}
break;
}
}
// Connect on Port Again
Sleep(5000);
status = RpcServerUseProtseqEp
(
// Use TCP/IP protocol.
(RPC_WSTR)L"ncacn_ip_tcp",
// Backlog queue length for TCP/IP.
RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
// TCP/IP port to use.
(RPC_WSTR)ServerSettings.KMSPort,
// No security.
NULL
);
}
else
{
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"RpcServerUseProtseqEp failed with code %i.\n", status);
ServerWriteLogErrorTerminate(Message, status);
}
}
// Registers the KMSServer interface.
status = RpcServerRegisterIfEx
(
// Interface to register.
KMSServer_v1_0_s_ifspec,
// Use the MIDL generated entry-point vector.
NULL,
// Use the MIDL generated entry-point vector.
NULL,
// Interface Registration Flags
RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH | RPC_IF_AUTOLISTEN,
// Maximum Calls
RPC_C_LISTEN_MAX_CALLS_DEFAULT,
// No Security Callback Function
NULL
);
if (status)
{
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"RpcServerRegisterIfEx failed with code %i.\n", status);
ServerWriteLogErrorTerminate(Message, status);
}
ServerWriteLogInformation(L"\nKMS Server Emulator started successfully.\n");
// Start to listen for remote procedure calls for all registered interfaces.
// This call will not return until RpcMgmtStopServerListening is called or the program is exited.
status = RpcServerListen
(
// Recommended minimum number of threads.
1,
// Recommended maximum number of threads.
RPC_C_LISTEN_MAX_CALLS_DEFAULT,
// Start listening now.
0
);
if (status)
{
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"RpcServerListen failed with code %i.\n", status);
ServerWriteLogErrorTerminate(Message, status);
}
}
// Stop RPC Connection
void StopKMSServer()
{
RpcMgmtStopServerListening(NULL);
RpcServerUnregisterIf(NULL, NULL, FALSE);
}
#pragma endregion
#pragma region RPC Interface Functions
// RPC Function to Build and Send a KMS Server Response.
int ActivationResponse(handle_t IDL_handle, int requestSize, unsigned char *request, int *responseSize, unsigned char **response)
{
// No Unreferenced Parameter Warnings
UNREFERENCED_PARAMETER(IDL_handle);
// Verify Request Size
if (requestSize < 92)
{
return RPC_S_INVALID_ENDPOINT_FORMAT;
}
// KMS Protocol Version
if (request[2] == 4 && request[0] == 0)
{
// Send Response to KMS Client
*response = CreateResponseV4((REQUEST_V4 *)request, responseSize);
// Log Sent Response
ServerWriteLogInformation(L"Activation response (KMS V4.0) sent.\n");
// Return to RPC Interface
return RPC_S_OK;
}
else if (request[2] == 5 && request[0] == 0)
{
// Send Response to KMS Client
*response = CreateResponseV5((REQUEST_V5 *)request, responseSize);
// Log Sent Response
ServerWriteLogInformation(L"Activation response (KMS V5.0) sent.\n");
// Return to RPC Interface
return RPC_S_OK;
}
else if (request[2] == 6 && request[0] == 0)
{
// Send Response to KMS Client
*response = CreateResponseV6((REQUEST_V6 *)request, responseSize);
// Log Sent Response
ServerWriteLogInformation(L"Activation response (KMS V6.0) sent.\n");
// Return to RPC Interface
return RPC_S_OK;
}
else
{
// Unsupported Protocol
return RPC_S_INVALID_VERS_OPTION;
}
}
#pragma endregion
#pragma region KMS Server Response Generation Functions
// Create Base KMS Server Response Object and handle KMS PID and HWID.
DWORD CreateResponseBase(REQUEST* const Request, PBYTE const Response)
{
// Generate KMS PID or use Command Argument
WCHAR kmsPIDInstance[PID_BUFFER_SIZE] = { 0 };
// Try to Get Application Specific KMS PID and HWID if running as KMS Server Service
if (ServerSettings.RunAsService)
{
GetKMSPID(kmsPIDInstance, Request);
}
// No Specific KMS PID or not running as KMS Server Service
if (!regex_match(kmsPIDInstance, wregex(L"^([0-9]{5})-([0-9]{5})-([0-9]{3})-([0-9]{6})-([0-9]{2})-([0-9]{4,5})-([0-9]{4}).([0-9]{4})-([0-9]{7})$")))
{
if (ServerSettings.GenerateRandomKMSPID)
{
// Build Random KMS PID
CreateKMSPID(kmsPIDInstance, Request);
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"\nKMS PID Generated: %s \n", kmsPIDInstance);
ServerWriteLogInformation(Message);
}
else
{
// Use Global KMS PID from Settings
StringCchCopyW(kmsPIDInstance, PID_BUFFER_SIZE, ServerSettings.KMSPID);
}
}
// Get KMS PID Length
DWORD kmsPIDLen = (DWORD)((wcslen(kmsPIDInstance) + 1) * sizeof(WCHAR));
// Current pointer
PBYTE current = Response;
// Set KMS Protocol Minor Version & Major Version
*(PDWORD)current = *(PDWORD)Request;
current += sizeof(DWORD);
// Set KMS PID Length
*(PDWORD)current = kmsPIDLen;
current += sizeof(DWORD);
// Copy KMS PID
memcpy(current, kmsPIDInstance, kmsPIDLen);
current += kmsPIDLen;
// Copy Client Machine ID
memcpy(current, &Request->ClientMachineId, sizeof(GUID));
current += sizeof(GUID);
// Copy KMS Client Request Timestamp
memcpy(current, &Request->RequestTime, sizeof(FILETIME));
current += sizeof(FILETIME);
// Set KMS Client Count Parameter
*(PDWORD)current = ServerSettings.CurrentClientCount;
current += sizeof(DWORD);
// Set KMS Activation Interval Parameter
*(PDWORD)current = ServerSettings.VLActivationInterval;
current += sizeof(DWORD);
// Set KMS Renewal Interval Parameter
*(PDWORD)current = ServerSettings.VLRenewalInterval;
current += sizeof(DWORD);
// Return ResponseBase Size
return (DWORD)(current - Response);
}
// Create Hashed KMS Server Response Data for KMS Protocol Version 4.
PBYTE CreateResponseV4(REQUEST_V4* const Request, int* const responseSize)
{
// Allocate KMS Server Response Buffer
BYTE buffer[MAX_RESPONSE_SIZE] = {0};
// Create KMS Server Response Base
int size = CreateResponseBase(&Request->RequestBase, buffer);
// Create Hash
GetHash(size, buffer, buffer + size);
// Create Proper Response with Hash
*responseSize = size + 16;
PBYTE response = (PBYTE)midl_user_allocate(*responseSize);
memcpy(response, buffer, *responseSize);
// Return Response
return response;
}
// Create Encrypted KMS Server Response Data for KMS Protocol Version 5.
PBYTE CreateResponseV5(REQUEST_V5* const Request, int* const responseSize)
{
// Allocate Response Buffer
BYTE buffer[MAX_RESPONSE_SIZE] = {0};
// Current pointer
PBYTE current = buffer;
// Set KMS Protocol Minor Version & Major Version
*(PDWORD)current = *(PDWORD)Request;
current += sizeof(DWORD);
// Store Response Salt pointer
PBYTE ResponseSalt = current;
// Copy Response Salt
memcpy(current, Request->Salt, 16);
current += 16;
// AES-128 Decrypt
DWORD DecryptSize = sizeof(Request->Salt) + sizeof(Request->RequestBase) + sizeof(Request->Pad);
AESDecryptMessage(Request->Salt, Request->Salt, &DecryptSize);
// Store Encrypt start pointer
PBYTE EncryptStart = current;
// Create Response Base Object
current += CreateResponseBase(&Request->RequestBase, current);
// Random Salt
BYTE RandomSalt[16];
// Seed Random Number Generator
srand(GetTickCount());
// Generate a Random Salt Key
for(int i = 0; i < 16; i++)
{
RandomSalt[i] = rand() % 256;
current[i] = Request->Salt[i] ^ ResponseSalt[i] ^ RandomSalt[i];
}
current += 16;
// Create Hash
GetHashSHA256(16, RandomSalt, current);
current += 32;
// Encrypted and Unencrypted size (KMS Protocol Major Version (2) + KMS Protocol Minor Version (2) + Salt (16))
DWORD UnencryptedSize = 20;
DWORD EncryptedSize = (DWORD)(current - EncryptStart);
// AES-128 Encrypt
AESEncryptMessage(ResponseSalt, EncryptStart, &EncryptedSize, MAX_RESPONSE_SIZE - UnencryptedSize);
// Make proper response with correct size
*responseSize = EncryptedSize + UnencryptedSize;
PBYTE response = (PBYTE)midl_user_allocate(*responseSize);
memcpy(response, buffer, *responseSize);
// Return Response
return response;
}
// Create Encrypted KMS Server Response Data for KMS Protocol Version 6.
PBYTE CreateResponseV6(REQUEST_V6* const Request, int* const responseSize)
{
// V6: AES key
BYTE AES_V6_KEY[16] = {0xA9, 0x4A, 0x41, 0x95, 0xE2, 0x01, 0x43, 0x2D, 0x9B, 0xCB, 0x46, 0x04, 0x05, 0xD8, 0x4A, 0x21};
// Allocate Response Buffer
BYTE buffer[MAX_RESPONSE_SIZE] = {0};
// Current pointer
PBYTE current = buffer;
// Set KMS Protocol Minor Version & Major Version
*(PDWORD)current = *(PDWORD)Request;
current += sizeof(DWORD);
// Store Response Salt pointer
PBYTE ResponseSalt = current;
// Copy Response Salt
memcpy(current, Request->Salt, 16);
current += 16;
// AES-128 Decrypt
DWORD DecryptSize = sizeof(Request->Salt) + sizeof(Request->RequestBase) + sizeof(Request->Pad);
// Modded AES-CBC Decrypt
AesInit(AES_TYPE_128, AES_MODE_CBC, 0x04, AES_V6_KEY, Request->Salt);
DecryptMessage(DecryptSize, Request->Salt);
AesClear();
// Store Encrypt start pointer
PBYTE EncryptStart = current;
// Create Response Base Object
current += CreateResponseBase(&Request->RequestBase, current);
// Random Salt
BYTE RandomSalt[16];
// Seed Random Number Generator
srand(GetTickCount());
// Generate a Random Salt Key
for(int i = 0; i < 16; i++)
{
RandomSalt[i] = rand() % 256;
current[i] = Request->Salt[i] ^ ResponseSalt[i] ^ RandomSalt[i];
}
current += 16;
// Create Hash
GetHashSHA256(16, RandomSalt, current);
current += 32;
#pragma region KMS HWID
// Try to Get Application Specific KMS HWID if running as KMS Server Service
QWORD kmsHWIDInstance = 0x0;
if (ServerSettings.RunAsService)
{
GetKMSHWID(&kmsHWIDInstance, &Request->RequestBase);
}
// No Specific KMS HWID or not running as KMS Server Service
if (kmsHWIDInstance == 0x0)
{
// Use Global KMS PID from Settings
kmsHWIDInstance = ServerSettings.KMSHWID;
}
// Machine Hardware Hash
*(PQWORD) current = kmsHWIDInstance;
current += 8;
#pragma endregion
// HMAC message buffer
BYTE Hmac_msg[256];
// Xor2 and Hmac_msg
for(int i = 0; i < 16; i++)
{
Hmac_msg[i] = current[i] = Request->Salt[i] ^ ResponseSalt[i];
}
current += 16;
// HMAC size
DWORD Hmac_size = current - EncryptStart;
memcpy(Hmac_msg + 16, EncryptStart, Hmac_size);
Hmac_size += 16;
// HMAC-SHA256
BYTE Hmac_hash[32];
GetHmacKey(&Request->RequestBase.RequestTime, Hmac_keyblob.rgbKeyData);
GetHmacSHA256(Hmac_size, Hmac_msg, Hmac_hash);
memcpy(current, Hmac_hash + 16, 16);
current += 16;
// Encrypted and Unencrypted size (KMS Protocol Major Version (2) + KMS Protocol Minor Version (2) + Salt (16))
DWORD EncryptSize = (DWORD)(current - EncryptStart);
// PKCS5 Padding
BYTE bPadding =(~EncryptSize + 1) & 0x0f;
if(bPadding == 0){
bPadding = 16;
}
memset(current, bPadding, bPadding);
EncryptSize += bPadding;
// Modded AES-CBC Encrypt
AesInit(AES_TYPE_128, AES_MODE_CBC, bPadding, AES_V6_KEY, ResponseSalt);
EncryptMessage(EncryptSize, EncryptStart);
AesClear();
// Make proper response with correct size
*responseSize = EncryptSize + 20;
PBYTE response = (PBYTE)midl_user_allocate(*responseSize);
memcpy(response, buffer, *responseSize);
// Return Response
return response;
}
#pragma endregion
#pragma region Parameter Validation Functions
// Validate KMS Port Parameter
void ServerValidateKMSPort(WCHAR* KMSPort)
{
// Check if the KMS Port is not the Default
if (CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, KMSPort, -1, L"DefaultPort", -1) != CSTR_EQUAL)
{
// Check if KMS Port is Valid Number
if (regex_match(KMSPort, wregex(L"^([0-9]+)$")))
{
// Check if KMS Port is Valid Range
if(_wtoi(KMSPort) < 1 || _wtoi(KMSPort) > 65535)
{
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"Invalid KMS Port Range! %s is not a valid argument.\n", KMSPort);
ServerWriteLogErrorTerminate(Message, -1);
}
else
{
// Apply Setting
StringCchCopyW(ServerSettings.KMSPort, PORT_BUFFER_SIZE, KMSPort);
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"KMS Port: %s \n", KMSPort);
ServerWriteLogInformation(Message);
}
}
else
{
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"Invalid KMS Port! %s is not a valid argument.\n", KMSPort);
ServerWriteLogErrorTerminate(Message, -1);
}
}
}
// Validate KMS PID Parameter
void ServerValidateKMSPID(WCHAR* KMSPID)
{
// Check if KMS PID should be Random
if (CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, KMSPID, -1, L"RandomKMSPID", -1) == CSTR_EQUAL)
{
ServerSettings.GenerateRandomKMSPID = true;
}
// Check if KMS PID is Valid
else if (regex_match(KMSPID, wregex(L"^([0-9]{5})-([0-9]{5})-([0-9]{3})-([0-9]{6})-([0-9]{2})-([0-9]{4,5})-([0-9]{4}).([0-9]{4})-([0-9]{7})$")))
{
// Apply Setting
StringCchCopyW(ServerSettings.KMSPID, PID_BUFFER_SIZE, KMSPID);
// Disable Random KMSPID Generation
ServerSettings.GenerateRandomKMSPID = false;
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"KMS PID: %s \n", KMSPID);
ServerWriteLogInformation(Message);
}
else
{
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"Invalid KMS PID! %s is not a valid argument.\n", KMSPID);
ServerWriteLogErrorTerminate(Message, -1);
}
}
// Validate KMS HWID Parameter
void ServerValidateKMSHWID(WCHAR* KMSHWID)
{
// Check if the KMS Port is not the Default
if (CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, KMSHWID, -1, L"DefaultKMSHWID", -1) != CSTR_EQUAL)
{
// Check if KMS HWID is Valid Hex String
if (regex_match(KMSHWID, wregex(L"^[a-fA-F0-9]{16}$")))
{
// Apply Setting
ServerSettings.KMSHWID = wcstoull(KMSHWID, NULL, 16);
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"KMS HWID: %s \n", KMSHWID);
ServerWriteLogInformation(Message);
}
else
{
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"Invalid KMS Hardware ID! %s is not a valid argument.\n", KMSHWID);
ServerWriteLogErrorTerminate(Message, -1);
}
}
}
// Validate KMS Activation Interval Parameter
void ServerValidateVLActivationInterval(int VLActivationInterval)
{
// Check if KMS Activation Interval is Valid Range
if (VLActivationInterval < 15 || VLActivationInterval > 43200)
{
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"Invalid KMS Activation Interval Range! %i is not a valid argument.\n", VLActivationInterval);
ServerWriteLogErrorTerminate(Message, -1);
}
else
{
// Apply Setting
ServerSettings.VLActivationInterval = VLActivationInterval;
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"KMS Activation Interval: %i minutes \n", VLActivationInterval);
ServerWriteLogInformation(Message);
}
}
// Validate KMS Activation Interval Parameter
void ServerValidateVLRenewalInterval(int VLRenewalInterval)
{
// Check if KMS Renewal Interval is Valid Range
if (VLRenewalInterval < 15 || VLRenewalInterval > 43200)
{
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"Invalid KMS Renewal Interval Range! %i is not a valid argument.\n", VLRenewalInterval);
ServerWriteLogErrorTerminate(Message, -1);
}
else
{
// Apply Setting
ServerSettings.VLRenewalInterval = VLRenewalInterval;
// Format Log Message
WCHAR Message[256];
swprintf_s(Message, 256, L"KMS Renewal Interval: %i minutes \n", VLRenewalInterval);
ServerWriteLogInformation(Message);
}
}
#pragma endregion
#pragma region Logging Functions
// Log an informational message to the Console or Windows Application Event Log.
void ServerWriteLogInformation(WCHAR* const Message)
{
// Log Message Buffer
WCHAR logMessage[256];
// Write Log Message to Buffer
StringCbPrintfW(logMessage, 256, Message);
// Choose Log Source
if (ServerSettings.RunAsService)
{
// Output to Windows Event Log: Qualifiers: 16384, EventId: 12290
ServerWriteEventLogEntry(0x40003002, logMessage, EVENTLOG_INFORMATION_TYPE);
}
else
{
// Output to Console
wprintf(L"%s", logMessage);
}
}
// Log an error message to the Console or Windows Application Event Log.
void ServerWriteLogError(WCHAR* const Message)
{
// Log Message Buffer
WCHAR logMessage[256];
// Write Log Message to Buffer
StringCbPrintfW(logMessage, 256, Message);
// Choose Log Source
if (ServerSettings.RunAsService)
{
// Output to Windows Event Log: Qualifiers: 16384, EventId: 902
ServerWriteEventLogEntry(0x40000386, logMessage, EVENTLOG_ERROR_TYPE);
}
else
{
// Output to Console
wprintf(L"%s", logMessage);
}
}
// Log an error message to the Console or Windows Application Event Log and terminate program.
void ServerWriteLogErrorTerminate(WCHAR* const Message, int ExitCode)
{
// Call ServerWriteLogError
ServerWriteLogError(Message);
if (!ServerSettings.RunAsService)
{
// Exit Program
exit(ExitCode);
}
else
{
// Exit Service
ServerServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServerServiceStatus.dwWin32ExitCode = ExitCode;
SetServiceStatus(ServerServiceHandle, &ServerServiceStatus);
}
}
// Log a message to the Windows Application Event Log.
void ServerWriteEventLogEntry(DWORD dwIdentifier, WCHAR* const lpszMessage, WORD wType)
{
HANDLE hEventSource = OpenEventLogW(NULL, L"KmsRequests"); // Provider: KmsRequests or Microsoft-Windows-Security-SPP
if(hEventSource != NULL)
{
ReportEventW(
hEventSource, // Event log handle
wType, // Event type
NULL, // Event category
dwIdentifier, // Event identifier
NULL, // No security identifier
1, // Size of lpszStrings array
NULL, // No binary data
(LPCWSTR*)&lpszMessage, // Array of strings
NULL // No binary data
);
CloseEventLog(hEventSource);
}
}
#pragma endregion
+29
View File
@@ -0,0 +1,29 @@
// Includes and Namespaces
#include "KMSServerSettings.h"
// KMS Server Parameters
WCHAR KMSServerSettings::KMSPID[PID_BUFFER_SIZE];
QWORD KMSServerSettings::KMSHWID;
WCHAR KMSServerSettings::KMSPort[PORT_BUFFER_SIZE];
DWORD KMSServerSettings::CurrentClientCount;
DWORD KMSServerSettings::VLActivationInterval;
DWORD KMSServerSettings::VLRenewalInterval;
// KMS Server Program Control
bool KMSServerSettings::GenerateRandomKMSPID;
bool KMSServerSettings::RunAsService;
// Process Termination Control Variables
bool KMSServerSettings:: KillProcesses;
// Set Default Settings
void KMSServerSettings::Initialize()
{
StringCchCopyW(KMSPID, PID_BUFFER_SIZE, L"55041-00168-305-246209-03-1033-7600.0000-0522010");
KMSHWID = 0x364F463A8863D35F;
StringCchCopyW(KMSPort, PORT_BUFFER_SIZE, L"1688");
CurrentClientCount = 26;
VLActivationInterval = 120;
VLRenewalInterval = 10080;
GenerateRandomKMSPID = true;
};
+498
View File
@@ -0,0 +1,498 @@
// Win32 KMS Client RPC Stubs
#if !defined(_M_IA64) && !defined(_M_AMD64) && !defined(_ARM_)
#pragma warning( disable: 4049 ) /* more than 64k source lines */
#if _MSC_VER >= 1200
#pragma warning(push)
#endif
#pragma warning( disable: 4211 ) /* redefine extern to static */
#pragma warning( disable: 4232 ) /* dllimport identity*/
#pragma warning( disable: 4024 ) /* array to pointer mapping*/
#pragma warning( disable: 4100 ) /* unreferenced arguments in x86 call */
#pragma optimize("", off )
#include <string.h>
#include "KMSServer.h"
#define TYPE_FORMAT_STRING_SIZE 43
#define PROC_FORMAT_STRING_SIZE 59
#define EXPR_FORMAT_STRING_SIZE 1
#define TRANSMIT_AS_TABLE_SIZE 0
#define WIRE_MARSHAL_TABLE_SIZE 0
typedef struct _KMSServer_MIDL_TYPE_FORMAT_STRING
{
short Pad;
unsigned char Format[ TYPE_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_TYPE_FORMAT_STRING;
typedef struct _KMSServer_MIDL_PROC_FORMAT_STRING
{
short Pad;
unsigned char Format[ PROC_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_PROC_FORMAT_STRING;
typedef struct _KMSServer_MIDL_EXPR_FORMAT_STRING
{
long Pad;
unsigned char Format[ EXPR_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_EXPR_FORMAT_STRING;
static const RPC_SYNTAX_IDENTIFIER _RpcTransferSyntax =
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}};
extern const KMSServer_MIDL_TYPE_FORMAT_STRING KMSServer__MIDL_TypeFormatString;
extern const KMSServer_MIDL_PROC_FORMAT_STRING KMSServer__MIDL_ProcFormatString;
extern const KMSServer_MIDL_EXPR_FORMAT_STRING KMSServer__MIDL_ExprFormatString;
#define GENERIC_BINDING_TABLE_SIZE 0
/* Standard interface: KMSServer, ver. 1.0,
GUID={0x51C82175,0x844E,0x4750,{0xB0,0xD8,0xEC,0x25,0x55,0x55,0xBC,0x06}} */
static const RPC_CLIENT_INTERFACE KMSServer___RpcClientInterface =
{
sizeof(RPC_CLIENT_INTERFACE),
{{0x51C82175,0x844E,0x4750,{0xB0,0xD8,0xEC,0x25,0x55,0x55,0xBC,0x06}},{1,0}},
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}},
0,
0,
0,
0,
0,
0x00000000
};
RPC_IF_HANDLE KMSServer_v1_0_c_ifspec = (RPC_IF_HANDLE)& KMSServer___RpcClientInterface;
extern const MIDL_STUB_DESC KMSServer_StubDesc;
static RPC_BINDING_HANDLE KMSServer__MIDL_AutoBindHandle;
int ActivationRequest(
/* [in] */ handle_t IDL_handle,
/* [in] */ int requestSize,
/* [size_is][in] */ unsigned char *request,
/* [out] */ int *responseSize,
/* [size_is][size_is][out] */ unsigned char **response)
{
CLIENT_CALL_RETURN _RetVal;
_RetVal = NdrClientCall2(
( PMIDL_STUB_DESC )&KMSServer_StubDesc,
(PFORMAT_STRING) &KMSServer__MIDL_ProcFormatString.Format[0],
( unsigned char * )&IDL_handle);
return ( int )_RetVal.Simple;
}
#if !defined(__RPC_WIN32__)
#error Invalid build platform for this stub.
#endif
#if !(TARGET_IS_NT50_OR_LATER)
#error You need Windows 2000 or later to run this stub because it uses these features:
#error /robust command line switch.
#error However, your C/C++ compilation flags indicate you intend to run this app on earlier systems.
#error This app will fail with the RPC_X_WRONG_STUB_VERSION error.
#endif
static const KMSServer_MIDL_PROC_FORMAT_STRING KMSServer__MIDL_ProcFormatString =
{
0,
{
/* Procedure ActivationRequest */
0x0, /* 0 */
0x48, /* Old Flags: */
/* 2 */ NdrFcLong( 0x0 ), /* 0 */
/* 6 */ NdrFcShort( 0x0 ), /* 0 */
/* 8 */ NdrFcShort( 0x18 ), /* x86 Stack size/offset = 24 */
/* 10 */ 0x32, /* FC_BIND_PRIMITIVE */
0x0, /* 0 */
/* 12 */ NdrFcShort( 0x0 ), /* x86 Stack size/offset = 0 */
/* 14 */ NdrFcShort( 0x8 ), /* 8 */
/* 16 */ NdrFcShort( 0x24 ), /* 36 */
/* 18 */ 0x47, /* Oi2 Flags: srv must size, clt must size, has return, has ext, */
0x5, /* 5 */
/* 20 */ 0x8, /* 8 */
0x7, /* Ext Flags: new corr desc, clt corr check, srv corr check, */
/* 22 */ NdrFcShort( 0x1 ), /* 1 */
/* 24 */ NdrFcShort( 0x1 ), /* 1 */
/* 26 */ NdrFcShort( 0x0 ), /* 0 */
/* Parameter IDL_handle */
/* 28 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 30 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */
/* 32 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter requestSize */
/* 34 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */
/* 36 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */
/* 38 */ NdrFcShort( 0x6 ), /* Type Offset=6 */
/* Parameter request */
/* 40 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */
/* 42 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */
/* 44 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter responseSize */
/* 46 */ NdrFcShort( 0x2013 ), /* Flags: must size, must free, out, srv alloc size=8 */
/* 48 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */
/* 50 */ NdrFcShort( 0x16 ), /* Type Offset=22 */
/* Parameter response */
/* 52 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 54 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */
/* 56 */ 0x8, /* FC_LONG */
0x0, /* 0 */
0x0
}
};
static const KMSServer_MIDL_TYPE_FORMAT_STRING KMSServer__MIDL_TypeFormatString =
{
0,
{
NdrFcShort( 0x0 ), /* 0 */
/* 2 */
0x11, 0x0, /* FC_RP */
/* 4 */ NdrFcShort( 0x2 ), /* Offset= 2 (6) */
/* 6 */
0x1b, /* FC_CARRAY */
0x0, /* 0 */
/* 8 */ NdrFcShort( 0x1 ), /* 1 */
/* 10 */ 0x28, /* Corr desc: parameter, FC_LONG */
0x0, /* */
/* 12 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */
/* 14 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 16 */ 0x2, /* FC_CHAR */
0x5b, /* FC_END */
/* 18 */
0x11, 0xc, /* FC_RP [alloced_on_stack] [simple_pointer] */
/* 20 */ 0x8, /* FC_LONG */
0x5c, /* FC_PAD */
/* 22 */
0x11, 0x14, /* FC_RP [alloced_on_stack] [pointer_deref] */
/* 24 */ NdrFcShort( 0x2 ), /* Offset= 2 (26) */
/* 26 */
0x12, 0x0, /* FC_UP */
/* 28 */ NdrFcShort( 0x2 ), /* Offset= 2 (30) */
/* 30 */
0x1b, /* FC_CARRAY */
0x0, /* 0 */
/* 32 */ NdrFcShort( 0x1 ), /* 1 */
/* 34 */ 0x28, /* Corr desc: parameter, FC_LONG */
0x54, /* FC_DEREFERENCE */
/* 36 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */
/* 38 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 40 */ 0x2, /* FC_CHAR */
0x5b, /* FC_END */
0x0
}
};
static const unsigned short KMSServer_FormatStringOffsetTable[] =
{
0
};
static const MIDL_STUB_DESC KMSServer_StubDesc =
{
(void *)& KMSServer___RpcClientInterface,
MIDL_user_allocate,
MIDL_user_free,
&KMSServer__MIDL_AutoBindHandle,
0,
0,
0,
0,
KMSServer__MIDL_TypeFormatString.Format,
1, /* -error bounds_check flag */
0x50002, /* Ndr library version */
0,
0x8000253, /* MIDL Version 8.0.595 */
0,
0,
0, /* notify & notify_flag routine table */
0x1, /* MIDL flag */
0, /* cs routines */
0, /* proxy/server info */
0
};
#pragma optimize("", on )
#if _MSC_VER >= 1200
#pragma warning(pop)
#endif
#endif
// x64 KMS Client RPC Stubs
#if defined(_M_AMD64)
#pragma warning( disable: 4049 ) /* more than 64k source lines */
#if _MSC_VER >= 1200
#pragma warning(push)
#endif
#pragma warning( disable: 4211 ) /* redefine extern to static */
#pragma warning( disable: 4232 ) /* dllimport identity*/
#pragma warning( disable: 4024 ) /* array to pointer mapping*/
#include <string.h>
#include "KMSServer.h"
#define TYPE_FORMAT_STRING_SIZE 43
#define PROC_FORMAT_STRING_SIZE 61
#define EXPR_FORMAT_STRING_SIZE 1
#define TRANSMIT_AS_TABLE_SIZE 0
#define WIRE_MARSHAL_TABLE_SIZE 0
typedef struct _KMSServer_MIDL_TYPE_FORMAT_STRING
{
short Pad;
unsigned char Format[ TYPE_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_TYPE_FORMAT_STRING;
typedef struct _KMSServer_MIDL_PROC_FORMAT_STRING
{
short Pad;
unsigned char Format[ PROC_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_PROC_FORMAT_STRING;
typedef struct _KMSServer_MIDL_EXPR_FORMAT_STRING
{
long Pad;
unsigned char Format[ EXPR_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_EXPR_FORMAT_STRING;
static const RPC_SYNTAX_IDENTIFIER _RpcTransferSyntax =
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}};
extern const KMSServer_MIDL_TYPE_FORMAT_STRING KMSServer__MIDL_TypeFormatString;
extern const KMSServer_MIDL_PROC_FORMAT_STRING KMSServer__MIDL_ProcFormatString;
extern const KMSServer_MIDL_EXPR_FORMAT_STRING KMSServer__MIDL_ExprFormatString;
#define GENERIC_BINDING_TABLE_SIZE 0
/* Standard interface: KMSServer, ver. 1.0,
GUID={0x51C82175,0x844E,0x4750,{0xB0,0xD8,0xEC,0x25,0x55,0x55,0xBC,0x06}} */
static const RPC_CLIENT_INTERFACE KMSServer___RpcClientInterface =
{
sizeof(RPC_CLIENT_INTERFACE),
{{0x51C82175,0x844E,0x4750,{0xB0,0xD8,0xEC,0x25,0x55,0x55,0xBC,0x06}},{1,0}},
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}},
0,
0,
0,
0,
0,
0x00000000
};
RPC_IF_HANDLE KMSServer_v1_0_c_ifspec = (RPC_IF_HANDLE)& KMSServer___RpcClientInterface;
extern const MIDL_STUB_DESC KMSServer_StubDesc;
static RPC_BINDING_HANDLE KMSServer__MIDL_AutoBindHandle;
int ActivationRequest(
/* [in] */ handle_t IDL_handle,
/* [in] */ int requestSize,
/* [size_is][in] */ unsigned char *request,
/* [out] */ int *responseSize,
/* [size_is][size_is][out] */ unsigned char **response)
{
CLIENT_CALL_RETURN _RetVal;
_RetVal = NdrClientCall2(
( PMIDL_STUB_DESC )&KMSServer_StubDesc,
(PFORMAT_STRING) &KMSServer__MIDL_ProcFormatString.Format[0],
IDL_handle,
requestSize,
request,
responseSize,
response);
return ( int )_RetVal.Simple;
}
#if !defined(__RPC_WIN64__)
#error Invalid build platform for this stub.
#endif
static const KMSServer_MIDL_PROC_FORMAT_STRING KMSServer__MIDL_ProcFormatString =
{
0,
{
/* Procedure ActivationRequest */
0x0, /* 0 */
0x48, /* Old Flags: */
/* 2 */ NdrFcLong( 0x0 ), /* 0 */
/* 6 */ NdrFcShort( 0x0 ), /* 0 */
/* 8 */ NdrFcShort( 0x30 ), /* X64 Stack size/offset = 48 */
/* 10 */ 0x32, /* FC_BIND_PRIMITIVE */
0x0, /* 0 */
/* 12 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
/* 14 */ NdrFcShort( 0x8 ), /* 8 */
/* 16 */ NdrFcShort( 0x24 ), /* 36 */
/* 18 */ 0x47, /* Oi2 Flags: srv must size, clt must size, has return, has ext, */
0x5, /* 5 */
/* 20 */ 0xa, /* 10 */
0x7, /* Ext Flags: new corr desc, clt corr check, srv corr check, */
/* 22 */ NdrFcShort( 0x1 ), /* 1 */
/* 24 */ NdrFcShort( 0x1 ), /* 1 */
/* 26 */ NdrFcShort( 0x0 ), /* 0 */
/* 28 */ NdrFcShort( 0x0 ), /* 0 */
/* Parameter IDL_handle */
/* 30 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 32 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */
/* 34 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter requestSize */
/* 36 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */
/* 38 */ NdrFcShort( 0x10 ), /* X64 Stack size/offset = 16 */
/* 40 */ NdrFcShort( 0x6 ), /* Type Offset=6 */
/* Parameter request */
/* 42 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */
/* 44 */ NdrFcShort( 0x18 ), /* X64 Stack size/offset = 24 */
/* 46 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter responseSize */
/* 48 */ NdrFcShort( 0x2013 ), /* Flags: must size, must free, out, srv alloc size=8 */
/* 50 */ NdrFcShort( 0x20 ), /* X64 Stack size/offset = 32 */
/* 52 */ NdrFcShort( 0x16 ), /* Type Offset=22 */
/* Parameter response */
/* 54 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 56 */ NdrFcShort( 0x28 ), /* X64 Stack size/offset = 40 */
/* 58 */ 0x8, /* FC_LONG */
0x0, /* 0 */
0x0
}
};
static const KMSServer_MIDL_TYPE_FORMAT_STRING KMSServer__MIDL_TypeFormatString =
{
0,
{
NdrFcShort( 0x0 ), /* 0 */
/* 2 */
0x11, 0x0, /* FC_RP */
/* 4 */ NdrFcShort( 0x2 ), /* Offset= 2 (6) */
/* 6 */
0x1b, /* FC_CARRAY */
0x0, /* 0 */
/* 8 */ NdrFcShort( 0x1 ), /* 1 */
/* 10 */ 0x28, /* Corr desc: parameter, FC_LONG */
0x0, /* */
/* 12 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */
/* 14 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 16 */ 0x2, /* FC_CHAR */
0x5b, /* FC_END */
/* 18 */
0x11, 0xc, /* FC_RP [alloced_on_stack] [simple_pointer] */
/* 20 */ 0x8, /* FC_LONG */
0x5c, /* FC_PAD */
/* 22 */
0x11, 0x14, /* FC_RP [alloced_on_stack] [pointer_deref] */
/* 24 */ NdrFcShort( 0x2 ), /* Offset= 2 (26) */
/* 26 */
0x12, 0x0, /* FC_UP */
/* 28 */ NdrFcShort( 0x2 ), /* Offset= 2 (30) */
/* 30 */
0x1b, /* FC_CARRAY */
0x0, /* 0 */
/* 32 */ NdrFcShort( 0x1 ), /* 1 */
/* 34 */ 0x28, /* Corr desc: parameter, FC_LONG */
0x54, /* FC_DEREFERENCE */
/* 36 */ NdrFcShort( 0x18 ), /* X64 Stack size/offset = 24 */
/* 38 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 40 */ 0x2, /* FC_CHAR */
0x5b, /* FC_END */
0x0
}
};
static const unsigned short KMSServer_FormatStringOffsetTable[] =
{
0
};
static const MIDL_STUB_DESC KMSServer_StubDesc =
{
(void *)& KMSServer___RpcClientInterface,
MIDL_user_allocate,
MIDL_user_free,
&KMSServer__MIDL_AutoBindHandle,
0,
0,
0,
0,
KMSServer__MIDL_TypeFormatString.Format,
1, /* -error bounds_check flag */
0x50002, /* Ndr library version */
0,
0x8000253, /* MIDL Version 8.0.595 */
0,
0,
0, /* notify & notify_flag routine table */
0x1, /* MIDL flag */
0, /* cs routines */
0, /* proxy/server info */
0
};
#if _MSC_VER >= 1200
#pragma warning(pop)
#endif
#endif
+502
View File
@@ -0,0 +1,502 @@
// Win32 KMS Server RPC Stubs
#if !defined(_M_IA64) && !defined(_M_AMD64) && !defined(_ARM_)
#pragma warning( disable: 4049 ) /* more than 64k source lines */
#if _MSC_VER >= 1200
#pragma warning(push)
#endif
#pragma warning( disable: 4211 ) /* redefine extern to static */
#pragma warning( disable: 4232 ) /* dllimport identity*/
#pragma warning( disable: 4024 ) /* array to pointer mapping*/
#pragma warning( disable: 4100 ) /* unreferenced arguments in x86 call */
#pragma optimize("", off )
#include <string.h>
#include "KMSServer.h"
#define TYPE_FORMAT_STRING_SIZE 43
#define PROC_FORMAT_STRING_SIZE 59
#define EXPR_FORMAT_STRING_SIZE 1
#define TRANSMIT_AS_TABLE_SIZE 0
#define WIRE_MARSHAL_TABLE_SIZE 0
typedef struct _KMSServer_MIDL_TYPE_FORMAT_STRING
{
short Pad;
unsigned char Format[ TYPE_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_TYPE_FORMAT_STRING;
typedef struct _KMSServer_MIDL_PROC_FORMAT_STRING
{
short Pad;
unsigned char Format[ PROC_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_PROC_FORMAT_STRING;
typedef struct _KMSServer_MIDL_EXPR_FORMAT_STRING
{
long Pad;
unsigned char Format[ EXPR_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_EXPR_FORMAT_STRING;
static const RPC_SYNTAX_IDENTIFIER _RpcTransferSyntax =
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}};
extern const KMSServer_MIDL_TYPE_FORMAT_STRING KMSServer__MIDL_TypeFormatString;
extern const KMSServer_MIDL_PROC_FORMAT_STRING KMSServer__MIDL_ProcFormatString;
extern const KMSServer_MIDL_EXPR_FORMAT_STRING KMSServer__MIDL_ExprFormatString;
/* Standard interface: KMSServer, ver. 1.0,
GUID={0x51C82175,0x844E,0x4750,{0xB0,0xD8,0xEC,0x25,0x55,0x55,0xBC,0x06}} */
extern const MIDL_SERVER_INFO KMSServer_ServerInfo;
extern const RPC_DISPATCH_TABLE KMSServer_v1_0_DispatchTable;
static const RPC_SERVER_INTERFACE KMSServer___RpcServerInterface =
{
sizeof(RPC_SERVER_INTERFACE),
{{0x51C82175,0x844E,0x4750,{0xB0,0xD8,0xEC,0x25,0x55,0x55,0xBC,0x06}},{1,0}},
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}},
(RPC_DISPATCH_TABLE*)&KMSServer_v1_0_DispatchTable,
0,
0,
0,
&KMSServer_ServerInfo,
0x04000000
};
RPC_IF_HANDLE KMSServer_v1_0_s_ifspec = (RPC_IF_HANDLE)& KMSServer___RpcServerInterface;
extern const MIDL_STUB_DESC KMSServer_StubDesc;
#if !defined(__RPC_WIN32__)
#error Invalid build platform for this stub.
#endif
#if !(TARGET_IS_NT50_OR_LATER)
#error You need Windows 2000 or later to run this stub because it uses these features:
#error /robust command line switch.
#error However, your C/C++ compilation flags indicate you intend to run this app on earlier systems.
#error This app will fail with the RPC_X_WRONG_STUB_VERSION error.
#endif
static const KMSServer_MIDL_PROC_FORMAT_STRING KMSServer__MIDL_ProcFormatString =
{
0,
{
/* Procedure ActivationResponse */
0x0, /* 0 */
0x48, /* Old Flags: */
/* 2 */ NdrFcLong( 0x0 ), /* 0 */
/* 6 */ NdrFcShort( 0x0 ), /* 0 */
/* 8 */ NdrFcShort( 0x18 ), /* x86 Stack size/offset = 24 */
/* 10 */ 0x32, /* FC_BIND_PRIMITIVE */
0x0, /* 0 */
/* 12 */ NdrFcShort( 0x0 ), /* x86 Stack size/offset = 0 */
/* 14 */ NdrFcShort( 0x8 ), /* 8 */
/* 16 */ NdrFcShort( 0x24 ), /* 36 */
/* 18 */ 0x47, /* Oi2 Flags: srv must size, clt must size, has return, has ext, */
0x5, /* 5 */
/* 20 */ 0x8, /* 8 */
0x7, /* Ext Flags: new corr desc, clt corr check, srv corr check, */
/* 22 */ NdrFcShort( 0x1 ), /* 1 */
/* 24 */ NdrFcShort( 0x1 ), /* 1 */
/* 26 */ NdrFcShort( 0x0 ), /* 0 */
/* Parameter IDL_handle */
/* 28 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 30 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */
/* 32 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter requestSize */
/* 34 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */
/* 36 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */
/* 38 */ NdrFcShort( 0x6 ), /* Type Offset=6 */
/* Parameter request */
/* 40 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */
/* 42 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */
/* 44 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter responseSize */
/* 46 */ NdrFcShort( 0x2013 ), /* Flags: must size, must free, out, srv alloc size=8 */
/* 48 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */
/* 50 */ NdrFcShort( 0x16 ), /* Type Offset=22 */
/* Parameter response */
/* 52 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 54 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */
/* 56 */ 0x8, /* FC_LONG */
0x0, /* 0 */
0x0
}
};
static const KMSServer_MIDL_TYPE_FORMAT_STRING KMSServer__MIDL_TypeFormatString =
{
0,
{
NdrFcShort( 0x0 ), /* 0 */
/* 2 */
0x11, 0x0, /* FC_RP */
/* 4 */ NdrFcShort( 0x2 ), /* Offset= 2 (6) */
/* 6 */
0x1b, /* FC_CARRAY */
0x0, /* 0 */
/* 8 */ NdrFcShort( 0x1 ), /* 1 */
/* 10 */ 0x28, /* Corr desc: parameter, FC_LONG */
0x0, /* */
/* 12 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */
/* 14 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 16 */ 0x2, /* FC_CHAR */
0x5b, /* FC_END */
/* 18 */
0x11, 0xc, /* FC_RP [alloced_on_stack] [simple_pointer] */
/* 20 */ 0x8, /* FC_LONG */
0x5c, /* FC_PAD */
/* 22 */
0x11, 0x14, /* FC_RP [alloced_on_stack] [pointer_deref] */
/* 24 */ NdrFcShort( 0x2 ), /* Offset= 2 (26) */
/* 26 */
0x12, 0x0, /* FC_UP */
/* 28 */ NdrFcShort( 0x2 ), /* Offset= 2 (30) */
/* 30 */
0x1b, /* FC_CARRAY */
0x0, /* 0 */
/* 32 */ NdrFcShort( 0x1 ), /* 1 */
/* 34 */ 0x28, /* Corr desc: parameter, FC_LONG */
0x54, /* FC_DEREFERENCE */
/* 36 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */
/* 38 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 40 */ 0x2, /* FC_CHAR */
0x5b, /* FC_END */
0x0
}
};
static const unsigned short KMSServer_FormatStringOffsetTable[] =
{
0
};
static const MIDL_STUB_DESC KMSServer_StubDesc =
{
(void *)& KMSServer___RpcServerInterface,
MIDL_user_allocate,
MIDL_user_free,
0,
0,
0,
0,
0,
KMSServer__MIDL_TypeFormatString.Format,
1, /* -error bounds_check flag */
0x50002, /* Ndr library version */
0,
0x8000253, /* MIDL Version 8.0.595 */
0,
0,
0, /* notify & notify_flag routine table */
0x1, /* MIDL flag */
0, /* cs routines */
0, /* proxy/server info */
0
};
static const RPC_DISPATCH_FUNCTION KMSServer_table[] =
{
NdrServerCall2,
0
};
static const RPC_DISPATCH_TABLE KMSServer_v1_0_DispatchTable =
{
1,
(RPC_DISPATCH_FUNCTION*)KMSServer_table
};
static const SERVER_ROUTINE KMSServer_ServerRoutineTable[] =
{
(SERVER_ROUTINE)ActivationResponse
};
static const MIDL_SERVER_INFO KMSServer_ServerInfo =
{
&KMSServer_StubDesc,
KMSServer_ServerRoutineTable,
KMSServer__MIDL_ProcFormatString.Format,
KMSServer_FormatStringOffsetTable,
0,
0,
0,
0};
#pragma optimize("", on )
#if _MSC_VER >= 1200
#pragma warning(pop)
#endif
#endif
// x64 KMS Server RPC Stubs
#if defined(_M_AMD64)
#pragma warning( disable: 4049 ) /* more than 64k source lines */
#if _MSC_VER >= 1200
#pragma warning(push)
#endif
#pragma warning( disable: 4211 ) /* redefine extern to static */
#pragma warning( disable: 4232 ) /* dllimport identity*/
#pragma warning( disable: 4024 ) /* array to pointer mapping*/
#include <string.h>
#include "KMSServer.h"
#define TYPE_FORMAT_STRING_SIZE 43
#define PROC_FORMAT_STRING_SIZE 61
#define EXPR_FORMAT_STRING_SIZE 1
#define TRANSMIT_AS_TABLE_SIZE 0
#define WIRE_MARSHAL_TABLE_SIZE 0
typedef struct _KMSServer_MIDL_TYPE_FORMAT_STRING
{
short Pad;
unsigned char Format[ TYPE_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_TYPE_FORMAT_STRING;
typedef struct _KMSServer_MIDL_PROC_FORMAT_STRING
{
short Pad;
unsigned char Format[ PROC_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_PROC_FORMAT_STRING;
typedef struct _KMSServer_MIDL_EXPR_FORMAT_STRING
{
long Pad;
unsigned char Format[ EXPR_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_EXPR_FORMAT_STRING;
static const RPC_SYNTAX_IDENTIFIER _RpcTransferSyntax =
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}};
extern const KMSServer_MIDL_TYPE_FORMAT_STRING KMSServer__MIDL_TypeFormatString;
extern const KMSServer_MIDL_PROC_FORMAT_STRING KMSServer__MIDL_ProcFormatString;
extern const KMSServer_MIDL_EXPR_FORMAT_STRING KMSServer__MIDL_ExprFormatString;
/* Standard interface: KMSServer, ver. 1.0,
GUID={0x51C82175,0x844E,0x4750,{0xB0,0xD8,0xEC,0x25,0x55,0x55,0xBC,0x06}} */
extern const MIDL_SERVER_INFO KMSServer_ServerInfo;
extern const RPC_DISPATCH_TABLE KMSServer_v1_0_DispatchTable;
static const RPC_SERVER_INTERFACE KMSServer___RpcServerInterface =
{
sizeof(RPC_SERVER_INTERFACE),
{{0x51C82175,0x844E,0x4750,{0xB0,0xD8,0xEC,0x25,0x55,0x55,0xBC,0x06}},{1,0}},
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}},
(RPC_DISPATCH_TABLE*)&KMSServer_v1_0_DispatchTable,
0,
0,
0,
&KMSServer_ServerInfo,
0x04000000
};
RPC_IF_HANDLE KMSServer_v1_0_s_ifspec = (RPC_IF_HANDLE)& KMSServer___RpcServerInterface;
extern const MIDL_STUB_DESC KMSServer_StubDesc;
#if !defined(__RPC_WIN64__)
#error Invalid build platform for this stub.
#endif
static const KMSServer_MIDL_PROC_FORMAT_STRING KMSServer__MIDL_ProcFormatString =
{
0,
{
/* Procedure ActivationResponse */
0x0, /* 0 */
0x48, /* Old Flags: */
/* 2 */ NdrFcLong( 0x0 ), /* 0 */
/* 6 */ NdrFcShort( 0x0 ), /* 0 */
/* 8 */ NdrFcShort( 0x30 ), /* X64 Stack size/offset = 48 */
/* 10 */ 0x32, /* FC_BIND_PRIMITIVE */
0x0, /* 0 */
/* 12 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
/* 14 */ NdrFcShort( 0x8 ), /* 8 */
/* 16 */ NdrFcShort( 0x24 ), /* 36 */
/* 18 */ 0x47, /* Oi2 Flags: srv must size, clt must size, has return, has ext, */
0x5, /* 5 */
/* 20 */ 0xa, /* 10 */
0x7, /* Ext Flags: new corr desc, clt corr check, srv corr check, */
/* 22 */ NdrFcShort( 0x1 ), /* 1 */
/* 24 */ NdrFcShort( 0x1 ), /* 1 */
/* 26 */ NdrFcShort( 0x0 ), /* 0 */
/* 28 */ NdrFcShort( 0x0 ), /* 0 */
/* Parameter IDL_handle */
/* 30 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 32 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */
/* 34 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter requestSize */
/* 36 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */
/* 38 */ NdrFcShort( 0x10 ), /* X64 Stack size/offset = 16 */
/* 40 */ NdrFcShort( 0x6 ), /* Type Offset=6 */
/* Parameter request */
/* 42 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */
/* 44 */ NdrFcShort( 0x18 ), /* X64 Stack size/offset = 24 */
/* 46 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter responseSize */
/* 48 */ NdrFcShort( 0x2013 ), /* Flags: must size, must free, out, srv alloc size=8 */
/* 50 */ NdrFcShort( 0x20 ), /* X64 Stack size/offset = 32 */
/* 52 */ NdrFcShort( 0x16 ), /* Type Offset=22 */
/* Parameter response */
/* 54 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 56 */ NdrFcShort( 0x28 ), /* X64 Stack size/offset = 40 */
/* 58 */ 0x8, /* FC_LONG */
0x0, /* 0 */
0x0
}
};
static const KMSServer_MIDL_TYPE_FORMAT_STRING KMSServer__MIDL_TypeFormatString =
{
0,
{
NdrFcShort( 0x0 ), /* 0 */
/* 2 */
0x11, 0x0, /* FC_RP */
/* 4 */ NdrFcShort( 0x2 ), /* Offset= 2 (6) */
/* 6 */
0x1b, /* FC_CARRAY */
0x0, /* 0 */
/* 8 */ NdrFcShort( 0x1 ), /* 1 */
/* 10 */ 0x28, /* Corr desc: parameter, FC_LONG */
0x0, /* */
/* 12 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */
/* 14 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 16 */ 0x2, /* FC_CHAR */
0x5b, /* FC_END */
/* 18 */
0x11, 0xc, /* FC_RP [alloced_on_stack] [simple_pointer] */
/* 20 */ 0x8, /* FC_LONG */
0x5c, /* FC_PAD */
/* 22 */
0x11, 0x14, /* FC_RP [alloced_on_stack] [pointer_deref] */
/* 24 */ NdrFcShort( 0x2 ), /* Offset= 2 (26) */
/* 26 */
0x12, 0x0, /* FC_UP */
/* 28 */ NdrFcShort( 0x2 ), /* Offset= 2 (30) */
/* 30 */
0x1b, /* FC_CARRAY */
0x0, /* 0 */
/* 32 */ NdrFcShort( 0x1 ), /* 1 */
/* 34 */ 0x28, /* Corr desc: parameter, FC_LONG */
0x54, /* FC_DEREFERENCE */
/* 36 */ NdrFcShort( 0x18 ), /* X64 Stack size/offset = 24 */
/* 38 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 40 */ 0x2, /* FC_CHAR */
0x5b, /* FC_END */
0x0
}
};
static const unsigned short KMSServer_FormatStringOffsetTable[] =
{
0
};
static const MIDL_STUB_DESC KMSServer_StubDesc =
{
(void *)& KMSServer___RpcServerInterface,
MIDL_user_allocate,
MIDL_user_free,
0,
0,
0,
0,
0,
KMSServer__MIDL_TypeFormatString.Format,
1, /* -error bounds_check flag */
0x50002, /* Ndr library version */
0,
0x8000253, /* MIDL Version 8.0.595 */
0,
0,
0, /* notify & notify_flag routine table */
0x1, /* MIDL flag */
0, /* cs routines */
0, /* proxy/server info */
0
};
static const RPC_DISPATCH_FUNCTION KMSServer_table[] =
{
NdrServerCall2,
0
};
static const RPC_DISPATCH_TABLE KMSServer_v1_0_DispatchTable =
{
1,
(RPC_DISPATCH_FUNCTION*)KMSServer_table
};
static const SERVER_ROUTINE KMSServer_ServerRoutineTable[] =
{
(SERVER_ROUTINE)ActivationResponse
};
static const MIDL_SERVER_INFO KMSServer_ServerInfo =
{
&KMSServer_StubDesc,
KMSServer_ServerRoutineTable,
KMSServer__MIDL_ProcFormatString.Format,
KMSServer_FormatStringOffsetTable,
0,
0,
0,
0};
#if _MSC_VER >= 1200
#pragma warning(pop)
#endif
#endif
+15
View File
@@ -0,0 +1,15 @@
#include "KMSServer.h"
// Memory allocation function for RPC.
// The runtime uses these two functions for allocating/deallocating
// enough memory to pass the string to the server.
void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
{
return malloc(len);
}
// Memory deallocation function for RPC.
void __RPC_USER midl_user_free(void __RPC_FAR *ptr)
{
free(ptr);
}