BINK Preset Upgrade
This commit is contained in:
parent
8272256406
commit
0756a807b8
|
@ -97,7 +97,7 @@
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
|
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
<ExceptionHandling>Sync</ExceptionHandling>
|
<ExceptionHandling>Sync</ExceptionHandling>
|
||||||
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
|
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
|
@ -184,6 +184,7 @@
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<AdditionalManifestDependencies>"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
|
<AdditionalManifestDependencies>"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
|
||||||
<EntryPointSymbol>wWinMainCRTStartup</EntryPointSymbol>
|
<EntryPointSymbol>wWinMainCRTStartup</EntryPointSymbol>
|
||||||
|
<RegisterOutput>true</RegisterOutput>
|
||||||
</Link>
|
</Link>
|
||||||
<ProjectReference>
|
<ProjectReference>
|
||||||
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
||||||
|
@ -274,13 +275,13 @@
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
<AdditionalManifestDependencies>"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
|
<AdditionalManifestDependencies>"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
|
||||||
<EntryPointSymbol>wWinMainCRTStartup</EntryPointSymbol>
|
<EntryPointSymbol>wWinMainCRTStartup</EntryPointSymbol>
|
||||||
|
<RegisterOutput>true</RegisterOutput>
|
||||||
</Link>
|
</Link>
|
||||||
<ProjectReference>
|
<ProjectReference>
|
||||||
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Media Include="resources\neon.wav" />
|
|
||||||
<Media Include="resources\pxiii.wav" />
|
<Media Include="resources\pxiii.wav" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -293,12 +294,14 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="src\header.h" />
|
<ClInclude Include="src\header.h" />
|
||||||
|
<ClInclude Include="src\presets.h" />
|
||||||
<ClInclude Include="src\resource.h" />
|
<ClInclude Include="src\resource.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\bink.cpp" />
|
<ClCompile Include="src\bink.cpp" />
|
||||||
<ClCompile Include="src\key.cpp" />
|
<ClCompile Include="src\key.cpp" />
|
||||||
<ClCompile Include="src\main.cpp" />
|
<ClCompile Include="src\main.cpp" />
|
||||||
|
<ClCompile Include="src\presets.cpp" />
|
||||||
<ClCompile Include="src\server.cpp" />
|
<ClCompile Include="src\server.cpp" />
|
||||||
<ClCompile Include="src\utilities.cpp" />
|
<ClCompile Include="src\utilities.cpp" />
|
||||||
<ClCompile Include="src\windows.cpp" />
|
<ClCompile Include="src\windows.cpp" />
|
||||||
|
@ -307,6 +310,16 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="src\resource.rc" />
|
<ResourceCompile Include="src\resource.rc" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="resources\bink\BINK2003.bin" />
|
||||||
|
<None Include="resources\bink\BINK2003OEM.bin" />
|
||||||
|
<None Include="resources\bink\BINK98SE.bin" />
|
||||||
|
<None Include="resources\bink\BINK98SEOEM.bin" />
|
||||||
|
<None Include="resources\bink\BINKXP.bin" />
|
||||||
|
<None Include="resources\bink\BINKXP64.bin" />
|
||||||
|
<None Include="resources\bink\BINKXP64OEM.bin" />
|
||||||
|
<None Include="resources\bink\BINKXPOEM.bin" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
|
|
@ -10,33 +10,39 @@
|
||||||
<Filter Include="Resources">
|
<Filter Include="Resources">
|
||||||
<UniqueIdentifier>{8c8a7e56-fe48-4168-8eb0-0715690de23e}</UniqueIdentifier>
|
<UniqueIdentifier>{8c8a7e56-fe48-4168-8eb0-0715690de23e}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="Resources\BINK">
|
||||||
|
<UniqueIdentifier>{f5cd78be-da1c-4cfe-a3b9-56a21fefadf4}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resources\Bitmaps">
|
||||||
|
<UniqueIdentifier>{7847a032-b440-4d10-a8a6-ed1b9cb62197}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resources\Wave">
|
||||||
|
<UniqueIdentifier>{198e89a5-06ad-4790-bfaa-1e59588bf2d2}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Media Include="resources\neon.wav">
|
|
||||||
<Filter>Resources</Filter>
|
|
||||||
</Media>
|
|
||||||
<Media Include="resources\pxiii.wav">
|
<Media Include="resources\pxiii.wav">
|
||||||
<Filter>Resources</Filter>
|
<Filter>Resources\Wave</Filter>
|
||||||
</Media>
|
</Media>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Image Include="resources\ender.bmp">
|
|
||||||
<Filter>Resources</Filter>
|
|
||||||
</Image>
|
|
||||||
<Image Include="resources\icon.ico">
|
<Image Include="resources\icon.ico">
|
||||||
<Filter>Resources</Filter>
|
<Filter>Resources</Filter>
|
||||||
</Image>
|
</Image>
|
||||||
<Image Include="resources\logo.bmp">
|
<Image Include="resources\dropdown.bmp">
|
||||||
<Filter>Resources</Filter>
|
<Filter>Resources\Bitmaps</Filter>
|
||||||
|
</Image>
|
||||||
|
<Image Include="resources\ender.bmp">
|
||||||
|
<Filter>Resources\Bitmaps</Filter>
|
||||||
</Image>
|
</Image>
|
||||||
<Image Include="resources\musicoff.bmp">
|
<Image Include="resources\musicoff.bmp">
|
||||||
<Filter>Resources</Filter>
|
<Filter>Resources\Bitmaps</Filter>
|
||||||
</Image>
|
</Image>
|
||||||
<Image Include="resources\musicon.bmp">
|
<Image Include="resources\musicon.bmp">
|
||||||
<Filter>Resources</Filter>
|
<Filter>Resources\Bitmaps</Filter>
|
||||||
</Image>
|
</Image>
|
||||||
<Image Include="resources\dropdown.bmp">
|
<Image Include="resources\logo.bmp">
|
||||||
<Filter>Resources</Filter>
|
<Filter>Resources\Bitmaps</Filter>
|
||||||
</Image>
|
</Image>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -46,6 +52,9 @@
|
||||||
<ClInclude Include="src\resource.h">
|
<ClInclude Include="src\resource.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\presets.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\windows.cpp">
|
<ClCompile Include="src\windows.cpp">
|
||||||
|
@ -69,10 +78,39 @@
|
||||||
<ClCompile Include="src\utilities.cpp">
|
<ClCompile Include="src\utilities.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\presets.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="src\resource.rc">
|
<ResourceCompile Include="src\resource.rc">
|
||||||
<Filter>Resources</Filter>
|
<Filter>Resources</Filter>
|
||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="resources\bink\BINK98SE.bin">
|
||||||
|
<Filter>Resources\BINK</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\bink\BINK98SEOEM.bin">
|
||||||
|
<Filter>Resources\BINK</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\bink\BINK2003.bin">
|
||||||
|
<Filter>Resources\BINK</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\bink\BINK2003OEM.bin">
|
||||||
|
<Filter>Resources\BINK</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\bink\BINKXP.bin">
|
||||||
|
<Filter>Resources\BINK</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\bink\BINKXP64.bin">
|
||||||
|
<Filter>Resources\BINK</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\bink\BINKXP64OEM.bin">
|
||||||
|
<Filter>Resources\BINK</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="resources\bink\BINKXPOEM.bin">
|
||||||
|
<Filter>Resources\BINK</Filter>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
210
src/bink.cpp
210
src/bink.cpp
|
@ -3,63 +3,56 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "header.h"
|
#include "header.h"
|
||||||
|
#include "resource.h"
|
||||||
#define BINK_RETAIL MAKEINTRESOURCEW(1)
|
#include "presets.h"
|
||||||
#define BINK_OEM MAKEINTRESOURCEW(2)
|
|
||||||
|
|
||||||
#define RT_BINK L"BINK"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Bink resource doesn't exist
|
Bink resource doesn't exist
|
||||||
The file you selected isn't a library
|
The file you selected isn't a library
|
||||||
Bink resource is invalid
|
Bink resource is invalid
|
||||||
*/
|
*/
|
||||||
typedef struct _EC_BYTE_POINT {
|
|
||||||
CHAR x[256]; // x-coordinate of the point on the elliptic curve.
|
|
||||||
CHAR y[256]; // y-coordinate of the point on the elliptic curve.
|
|
||||||
} EC_BYTE_POINT;
|
|
||||||
|
|
||||||
typedef struct _BINKHDR {
|
/*BOOL SelectPreset(int nIndex) {
|
||||||
// BINK version - not stored in the resource.
|
if (nIndex >= WCOUNT) return false;
|
||||||
ULONG32 dwVersion;
|
|
||||||
|
|
||||||
// Original BINK header.
|
strcpy(pBINKPreset.p, p[nIndex]);
|
||||||
ULONG32 dwID;
|
strcpy(pBINKPreset.a, a);
|
||||||
ULONG32 dwSize;
|
strcpy(pBINKPreset.b, b);
|
||||||
ULONG32 dwHeaderLength;
|
strcpy(pBINKPreset.G.x, gx[nIndex]);
|
||||||
ULONG32 dwChecksum;
|
strcpy(pBINKPreset.G.y, gy[nIndex]);
|
||||||
ULONG32 dwDate;
|
strcpy(pBINKPreset.K.x, kx[nIndex]);
|
||||||
ULONG32 dwKeySizeInDWORDs;
|
strcpy(pBINKPreset.K.y, ky[nIndex]);
|
||||||
ULONG32 dwHashLength;
|
|
||||||
ULONG32 dwSignatureLength;
|
|
||||||
|
|
||||||
// Extended BINK header. (Windows Server 2003+)
|
pBINKPreset.I.x;
|
||||||
ULONG32 dwAuthCodeLength;
|
pBINKPreset.I.y;
|
||||||
ULONG32 dwProductIDLength;
|
|
||||||
} BINKHDR;
|
|
||||||
|
|
||||||
typedef struct _BINKDATA {
|
pBINKPreset.n = n[nIndex];
|
||||||
CHAR p[256]; // Finite Field order p.
|
pBINKPreset.k = k[nIndex];
|
||||||
CHAR a[256]; // Elliptic Curve parameter a.
|
|
||||||
CHAR b[256]; // Elliptic Curve parameter b.
|
|
||||||
|
|
||||||
EC_BYTE_POINT G; // Base point (Generator) G.
|
return true;
|
||||||
EC_BYTE_POINT K; // Public key K.
|
}*/
|
||||||
EC_BYTE_POINT I; // Inverse of the public key K.
|
|
||||||
} BINKDATA;
|
|
||||||
|
|
||||||
typedef struct _BINKEY {
|
BOOL CALLBACK EnumResourceProc(HMODULE hModule, CONST WCHAR *lpType, WCHAR *lpName, LONG_PTR lParam) {
|
||||||
BINKHDR header;
|
(*(UINT *)lParam)++;
|
||||||
BINKDATA data;
|
|
||||||
} BINKEY;
|
|
||||||
|
|
||||||
DWORD extractBINKResource(HMODULE hLibrary, BYTE **pData) {
|
return TRUE;
|
||||||
HRSRC hRes = FindResourceW(hLibrary, BINK_OEM, RT_BINK);
|
}
|
||||||
|
|
||||||
|
UINT countResources(WCHAR *pName) {
|
||||||
|
UINT nResources = 0;
|
||||||
|
|
||||||
|
EnumResourceNamesW(NULL, pName, EnumResourceProc, (LONG_PTR)&nResources);
|
||||||
|
|
||||||
|
return nResources;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD extractBINKResource(HMODULE hModule, UINT nPreset, BYTE **pMemory) {
|
||||||
|
HRSRC hRes = FindResourceW(hModule, MAKEINTRESOURCEW(nPreset), RT_BINK);
|
||||||
DWORD dwSize = 0;
|
DWORD dwSize = 0;
|
||||||
|
|
||||||
if (hRes != NULL) {
|
if (hRes != NULL) {
|
||||||
dwSize = SizeofResource(hLibrary, hRes);
|
dwSize = SizeofResource(hModule, hRes);
|
||||||
*pData = (BYTE *)LoadResource(hLibrary, hRes);
|
*pMemory = (BYTE *)LoadResource(hModule, hRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
return dwSize;
|
return dwSize;
|
||||||
|
@ -75,64 +68,135 @@ BYTE hexToDecDigit(CHAR nDigit) {
|
||||||
return nDigit - 'A' + 10;
|
return nDigit - 'A' + 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG32 byteToInteger(BYTE *pByte) {
|
void reverseBytes(BYTE *pBytes) {
|
||||||
return hexToDecDigit(pByte[0]) << 4 + hexToDecDigit(pByte[1]);
|
UINT nBytes = strlen((CHAR *)pBytes) / 2;
|
||||||
|
CHAR *pBytesCopy = strdup((CHAR *)pBytes);
|
||||||
|
|
||||||
|
for (int i = 0; i < nBytes; i++) {
|
||||||
|
memcpy(&pBytes[(nBytes - (i + 1)) * 2], &pBytesCopy[i * 2], 2 * sizeof(BYTE));
|
||||||
|
}
|
||||||
|
|
||||||
|
free(pBytesCopy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reverseBytes(CONST BYTE *pBytes, ULONG32 nBytes, BYTE *pReversed) {
|
VOID byteToHex(BYTE *pDestination, BYTE pByte) {
|
||||||
for (int i = nBytes - 1; i >= 0; i--) {
|
BYTE loByte = pByte % 16,
|
||||||
memcpy((BYTE *)&pBytes[i * 2], (BYTE *)&pReversed[(nBytes - i + 1) * 2], 2 * sizeof(BYTE));
|
hiByte = pByte / 16;
|
||||||
|
|
||||||
|
pDestination[0] = hiByte < 10 ? hiByte + '0' : hiByte + 'A' - 10;
|
||||||
|
pDestination[1] = loByte < 10 ? loByte + '0' : loByte + 'A' - 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID formatBytes(BYTE *pDestination, BYTE *pSource, UINT nLength) {
|
||||||
|
for (int i = 0; i < nLength; i++) {
|
||||||
|
byteToHex(pDestination + i * 2, pSource[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG32 ulToInteger(BYTE *pUL, BOOL bLittleEndian) {
|
BOOL decodeBINKResource(BYTE *pData, ULONG32 nLength, BINKEYEX *pBINK) {
|
||||||
BYTE pULCopy[8] = { 0 };
|
ULONG32 nStructOffset,
|
||||||
ULONG32 nUL = 0;
|
nCurveOffset,
|
||||||
|
nCurveField = FIELD_BYTES_2003;
|
||||||
|
|
||||||
if (pUL == NULL)
|
// If BINK is incomplete or the containers are null pointers, return.
|
||||||
return 0;
|
if (pData == nullptr || pBINK == nullptr || nLength < 0x170) return false;
|
||||||
|
|
||||||
if (bLittleEndian)
|
// Reset structure to 0.
|
||||||
reverseBytes(pUL, 4, pULCopy);
|
memset(pBINK, 0, sizeof(BINKEYEX));
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
// Read ID and the BINK header.
|
||||||
nUL += byteToInteger(&pULCopy[i * 2]);
|
for (nStructOffset = 0; nStructOffset < sizeof(ULONG32) + sizeof(BINKHDR); nStructOffset += sizeof(ULONG32)) {
|
||||||
|
*(ULONG32 *)((BYTE *)pBINK + nStructOffset) = BYDWORD(pData + nStructOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nUL;
|
// If it's an older BINK, there are only 7 arguments.
|
||||||
}
|
if (pBINK->binKey.header.dwVersion == 19980206) {
|
||||||
|
pBINK->binKey.header.dwProductIDLength = 0;
|
||||||
|
pBINK->binKey.header.dwAuthCodeLength = 0;
|
||||||
|
|
||||||
void decodeBINKResource(BYTE *pData, ULONG32 nLength, BINKEY *pBINK) {
|
nCurveField = FIELD_BYTES;
|
||||||
ULONG32 nBlockBytes = 4;
|
}
|
||||||
|
|
||||||
// If BINK is incomplete, return.
|
for (nCurveOffset = (pBINK->binKey.header.dwHeaderLength + 1) * sizeof(ULONG32); nStructOffset < sizeof(ULONG32) + sizeof(BINKDATA); nStructOffset += FIELD_LENGTH_MAX, nCurveOffset += nCurveField) {
|
||||||
if (nLength < 0x170) return;
|
BYTE *pCurveParameter = (BYTE *)pBINK + nStructOffset;
|
||||||
|
|
||||||
ulToInteger(pData, TRUE);
|
formatBytes(pCurveParameter, pData + nCurveOffset, nCurveField);
|
||||||
|
reverseBytes(pCurveParameter);
|
||||||
|
}
|
||||||
|
|
||||||
/*/ Read BINK header.
|
|
||||||
for (ULONG32 nOffset = 0; nOffset < sizeof(BINKHDR); nOffset += nBlockBytes) {
|
|
||||||
pBINK[nOffset] =
|
// Calculate the inverse of the public key.
|
||||||
|
// The elliptic curve is symmetric about the x axis, so we only need to calculate the y-coordinate.
|
||||||
|
// I.y = p - K.y
|
||||||
|
BIGNUM *fieldOrder = BN_new(),
|
||||||
|
*publicKeyY = BN_new();
|
||||||
|
|
||||||
|
BN_hex2bn(&fieldOrder, pBINK->binKey.data.p);
|
||||||
|
BN_hex2bn(&publicKeyY, pBINK->binKey.data.K.y);
|
||||||
|
|
||||||
|
BN_sub(publicKeyY, fieldOrder, publicKeyY);
|
||||||
|
|
||||||
|
CHAR *pInverse = BN_bn2hex(publicKeyY);
|
||||||
|
|
||||||
|
strcpy(pBINK->I.x, pBINK->binKey.data.K.x);
|
||||||
|
strcpy(pBINK->I.y, pInverse);
|
||||||
|
|
||||||
|
free(pInverse);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Additional calculations (not implemented yet)
|
||||||
|
BIGNUM *derivative = BN_new();
|
||||||
|
BIGNUM *generatorx = BN_new();
|
||||||
|
BIGNUM *generatory = BN_new();
|
||||||
|
BN_CTX *ctx = BN_CTX_new();
|
||||||
|
|
||||||
|
BN_hex2bn(&generatorx, pBINK->binKey.data.G.x);
|
||||||
|
BN_hex2bn(&generatory, pBINK->binKey.data.G.y);
|
||||||
|
|
||||||
|
/*EC_POINT *genPoint, *pubPoint, *genDerivative;
|
||||||
|
EC_GROUP *eCurve = initializeEllipticCurve(
|
||||||
|
pBINK->data.p,
|
||||||
|
pBINK->data.a,
|
||||||
|
pBINK->data.b,
|
||||||
|
pBINK->data.G.x,
|
||||||
|
pBINK->data.G.y,
|
||||||
|
pBINK->data.K.x,
|
||||||
|
pBINK->data.K.y,
|
||||||
|
&genPoint,
|
||||||
|
&pubPoint
|
||||||
|
);
|
||||||
|
|
||||||
|
genDerivative = EC_POINT_new(eCurve);
|
||||||
|
EC_POINT_copy(genDerivative, genPoint);
|
||||||
|
|
||||||
|
for (ULONG64 iter = 0; iter != 65153636961774397; iter++) {
|
||||||
|
printf("iter: %llu\n", iter);
|
||||||
|
EC_POINT_add(eCurve, genDerivative, genPoint, genDerivative, ctx);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void base(WCHAR *pPath) {
|
VOID InitializePreset(UINT nIndex, BINKEYEX *pBINK) {
|
||||||
HMODULE pIDgen = LoadLibraryExW(pPath, NULL, LOAD_LIBRARY_AS_DATAFILE);
|
/* HMODULE pIDgen = LoadLibraryExW(pPath, NULL, LOAD_LIBRARY_AS_DATAFILE);
|
||||||
|
|
||||||
if (pIDgen == NULL)
|
if (pIDgen == NULL)
|
||||||
return;
|
return;*/
|
||||||
|
|
||||||
BYTE *pBuffer = NULL;
|
BYTE *pMemory = NULL;
|
||||||
ULONG32 nLength = extractBINKResource(pIDgen, &pBuffer);
|
ULONG32 nLength = extractBINKResource(NULL, IDR_BINK1 + nIndex, &pMemory);
|
||||||
|
|
||||||
if (nLength == 0) {
|
if (nLength == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BINKEY pBINK = { 0 };
|
decodeBINKResource(pMemory, nLength, pBINK);
|
||||||
|
|
||||||
decodeBINKResource(pBuffer, nLength, &pBINK);
|
pBINK->n = generatorOrderArr[nIndex];
|
||||||
|
pBINK->k = privateKeyArr[nIndex];
|
||||||
|
|
||||||
FreeLibrary(pIDgen);
|
// FreeLibrary(pIDgen);
|
||||||
|
return;
|
||||||
}
|
}
|
114
src/header.h
114
src/header.h
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#pragma warning(disable: 6387)
|
#pragma warning(disable: 6387)
|
||||||
|
|
||||||
|
// Arithmetic macros
|
||||||
#define PK_LENGTH 25
|
#define PK_LENGTH 25
|
||||||
#define NULL_TERMINATOR 1
|
#define NULL_TERMINATOR 1
|
||||||
|
|
||||||
|
@ -27,9 +28,14 @@
|
||||||
#define FIELD_BITS_2003 512
|
#define FIELD_BITS_2003 512
|
||||||
#define FIELD_BYTES_2003 (FIELD_BITS_2003 / 8)
|
#define FIELD_BYTES_2003 (FIELD_BITS_2003 / 8)
|
||||||
|
|
||||||
|
#define FIELD_BITS_MAX FIELD_BITS_2003
|
||||||
|
#define FIELD_BYTES_MAX FIELD_BYTES_2003
|
||||||
|
|
||||||
#define SHA_MSG_LENGTH_XP (4 + 2 * FIELD_BYTES)
|
#define SHA_MSG_LENGTH_XP (4 + 2 * FIELD_BYTES)
|
||||||
#define SHA_MSG_LENGTH_2003 (3 + 2 * FIELD_BYTES_2003)
|
#define SHA_MSG_LENGTH_2003 (3 + 2 * FIELD_BYTES_2003)
|
||||||
|
|
||||||
|
#define FIELD_LENGTH_MAX (FIELD_BYTES_MAX * 2 + NULL_TERMINATOR)
|
||||||
|
|
||||||
#define NEXTSNBITS(field, n, offset) (((QWORD)(field) >> (offset)) & ((1ULL << (n)) - 1))
|
#define NEXTSNBITS(field, n, offset) (((QWORD)(field) >> (offset)) & ((1ULL << (n)) - 1))
|
||||||
#define FIRSTNBITS(field, n) NEXTSNBITS((field), (n), 0)
|
#define FIRSTNBITS(field, n) NEXTSNBITS((field), (n), 0)
|
||||||
|
|
||||||
|
@ -37,8 +43,10 @@
|
||||||
#define LOBYTES(field, bytes) FIRSTNBITS((QWORD)(field), ((bytes) * 8))
|
#define LOBYTES(field, bytes) FIRSTNBITS((QWORD)(field), ((bytes) * 8))
|
||||||
|
|
||||||
#define BYDWORD(n) (DWORD)(*((n) + 0) | *((n) + 1) << 8 | *((n) + 2) << 16 | *((n) + 3) << 24)
|
#define BYDWORD(n) (DWORD)(*((n) + 0) | *((n) + 1) << 8 | *((n) + 2) << 16 | *((n) + 3) << 24)
|
||||||
|
#define BYDWORDBE(n) (DWORD)(*((n) + 3) | *((n) + 2) << 8 | *((n) + 1) << 16 | *((n) + 0) << 24)
|
||||||
#define BITMASK(n) ((1ULL << (n)) - 1)
|
#define BITMASK(n) ((1ULL << (n)) - 1)
|
||||||
|
|
||||||
|
// Control macros
|
||||||
#define IDC_BUTTON1 1000
|
#define IDC_BUTTON1 1000
|
||||||
#define IDC_BUTTON2 1001
|
#define IDC_BUTTON2 1001
|
||||||
#define IDC_BUTTON3 1002
|
#define IDC_BUTTON3 1002
|
||||||
|
@ -67,18 +75,71 @@
|
||||||
#define IDC_LABEL5 1109
|
#define IDC_LABEL5 1109
|
||||||
#define IDC_LABEL6 1110
|
#define IDC_LABEL6 1110
|
||||||
|
|
||||||
|
// Resource macros
|
||||||
|
#define BINK_RETAIL MAKEINTRESOURCEW(1)
|
||||||
|
#define BINK_OEM MAKEINTRESOURCEW(2)
|
||||||
|
|
||||||
|
#define RT_BINK TEXT("BINK")
|
||||||
|
|
||||||
|
// Type definitions
|
||||||
typedef uint64_t QWORD;
|
typedef uint64_t QWORD;
|
||||||
|
|
||||||
extern char pCharset[];
|
// Structures
|
||||||
|
typedef struct _EC_BYTE_POINT {
|
||||||
|
CHAR x[FIELD_LENGTH_MAX]; // x-coordinate of the point on the elliptic curve.
|
||||||
|
CHAR y[FIELD_LENGTH_MAX]; // y-coordinate of the point on the elliptic curve.
|
||||||
|
} EC_BYTE_POINT;
|
||||||
|
|
||||||
|
typedef struct _BINKHDR {
|
||||||
|
// Original BINK header.
|
||||||
|
ULONG32 dwSize;
|
||||||
|
ULONG32 dwHeaderLength;
|
||||||
|
ULONG32 dwChecksum;
|
||||||
|
ULONG32 dwVersion;
|
||||||
|
ULONG32 dwKeySizeInDWORDs;
|
||||||
|
ULONG32 dwHashLength;
|
||||||
|
ULONG32 dwSignatureLength;
|
||||||
|
|
||||||
|
// Extended BINK header. (Windows Server 2003+)
|
||||||
|
ULONG32 dwAuthCodeLength;
|
||||||
|
ULONG32 dwProductIDLength;
|
||||||
|
} BINKHDR, *PBINKHDR;
|
||||||
|
|
||||||
|
typedef struct _BINKDATA {
|
||||||
|
CHAR p[FIELD_LENGTH_MAX]; // Finite Field order p.
|
||||||
|
CHAR a[FIELD_LENGTH_MAX]; // Elliptic Curve parameter a.
|
||||||
|
CHAR b[FIELD_LENGTH_MAX]; // Elliptic Curve parameter b.
|
||||||
|
|
||||||
|
EC_BYTE_POINT G; // Base point (Generator) G.
|
||||||
|
EC_BYTE_POINT K; // Public key K.
|
||||||
|
} BINKDATA, *PBINKDATA;
|
||||||
|
|
||||||
|
typedef struct _BINKEY {
|
||||||
|
BINKHDR header;
|
||||||
|
BINKDATA data;
|
||||||
|
} BINKEY, *PBINKEY;
|
||||||
|
|
||||||
|
typedef struct _BINKEYEX {
|
||||||
|
// ID of the BINK. (Separate from the BINKEY structure per spec)
|
||||||
|
ULONG32 dwID;
|
||||||
|
|
||||||
|
// BINKEY structure.
|
||||||
|
BINKEY binKey;
|
||||||
|
|
||||||
|
// Calculated values.
|
||||||
|
EC_BYTE_POINT I; // Inverse of the public key K.
|
||||||
|
QWORD n; // Order of the generator G.
|
||||||
|
QWORD k; // Private Key k.
|
||||||
|
} BINKEYEX, *PBINKEYEX;
|
||||||
|
|
||||||
|
extern BINKEYEX pBINKPreset;
|
||||||
|
extern CHAR pCharset[];
|
||||||
|
|
||||||
extern const char pXP[];
|
|
||||||
extern const long aXP;
|
|
||||||
extern const long bXP;
|
|
||||||
|
|
||||||
// xp.cpp
|
// xp.cpp
|
||||||
VOID unpackXP(
|
VOID unpackXP(
|
||||||
QWORD(&pRaw)[2],
|
QWORD (&pRaw)[2],
|
||||||
BOOL &pUpgrade,
|
BOOL &pUpgrade,
|
||||||
DWORD &pChannelID,
|
DWORD &pChannelID,
|
||||||
DWORD &pSequence,
|
DWORD &pSequence,
|
||||||
DWORD &pHash,
|
DWORD &pHash,
|
||||||
|
@ -106,10 +167,11 @@ VOID generateXPKey(
|
||||||
);
|
);
|
||||||
|
|
||||||
BOOL keyXP(
|
BOOL keyXP(
|
||||||
CHAR(&pKey)[PK_LENGTH + NULL_TERMINATOR],
|
CHAR (&pKey)[PK_LENGTH + NULL_TERMINATOR],
|
||||||
DWORD nChannelID,
|
BINKEYEX &pBINK,
|
||||||
DWORD nSequence,
|
DWORD nChannelID,
|
||||||
BOOL bUpgrade
|
DWORD nSequence,
|
||||||
|
BOOL bUpgrade
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -151,10 +213,11 @@ VOID generateServerKey(
|
||||||
);
|
);
|
||||||
|
|
||||||
BOOL keyServer(
|
BOOL keyServer(
|
||||||
CHAR (&pKey)[PK_LENGTH + NULL_TERMINATOR],
|
CHAR (&pKey)[PK_LENGTH + NULL_TERMINATOR],
|
||||||
DWORD nChannelID,
|
BINKEYEX &pBINK,
|
||||||
DWORD nAuthInfo,
|
DWORD nChannelID,
|
||||||
BOOL bUpgrade
|
DWORD nAuthInfo,
|
||||||
|
BOOL bUpgrade
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -166,17 +229,15 @@ void stopAudio();
|
||||||
bool playAudio(HINSTANCE hInstance, WCHAR *lpName, UINT bFlags);
|
bool playAudio(HINSTANCE hInstance, WCHAR *lpName, UINT bFlags);
|
||||||
|
|
||||||
EC_GROUP *initializeEllipticCurve(
|
EC_GROUP *initializeEllipticCurve(
|
||||||
const char *pSel,
|
CONST CHAR *pSel,
|
||||||
long aSel,
|
CONST CHAR *aSel,
|
||||||
long bSel,
|
CONST CHAR *bSel,
|
||||||
const char *generatorXSel,
|
CONST CHAR *generatorXSel,
|
||||||
const char *generatorYSel,
|
CONST CHAR *generatorYSel,
|
||||||
const char *publicKeyXSel,
|
CONST CHAR *publicKeyXSel,
|
||||||
const char *publicKeyYSel,
|
CONST CHAR *publicKeyYSel,
|
||||||
BIGNUM *genOrderSel,
|
EC_POINT **genPoint,
|
||||||
BIGNUM *privateKeySel,
|
EC_POINT **pubPoint
|
||||||
EC_POINT **genPoint,
|
|
||||||
EC_POINT **pubPoint
|
|
||||||
);
|
);
|
||||||
|
|
||||||
int BN_bn2lebin(const BIGNUM *a, unsigned char *to, int tolen);
|
int BN_bn2lebin(const BIGNUM *a, unsigned char *to, int tolen);
|
||||||
|
@ -195,6 +256,7 @@ bool InitializeWindow(HINSTANCE hInstance);
|
||||||
|
|
||||||
|
|
||||||
// bink.cpp
|
// bink.cpp
|
||||||
void base(WCHAR *pPath);
|
VOID InitializePreset(UINT nIndex, BINKEYEX *pBINK);
|
||||||
|
UINT countResources(WCHAR *pName);
|
||||||
|
|
||||||
#endif //KEYGEN_HEADER_H
|
#endif //KEYGEN_HEADER_H
|
||||||
|
|
|
@ -87,7 +87,7 @@ void formatXP(BOOL bUpgrade, WCHAR *pBSection, WCHAR *pCSection, WCHAR *pText) {
|
||||||
DWORD nChannelID = wcstoul(pBSection, nullptr, 10),
|
DWORD nChannelID = wcstoul(pBSection, nullptr, 10),
|
||||||
nSequence = wcstoul(pCSection, nullptr, 10);
|
nSequence = wcstoul(pCSection, nullptr, 10);
|
||||||
|
|
||||||
BOOL bValid = keyXP(pKey, nChannelID, nSequence, bUpgrade);
|
BOOL bValid = keyXP(pKey, pBINKPreset, nChannelID, nSequence, bUpgrade);
|
||||||
|
|
||||||
QWORD pRaw[2]{},
|
QWORD pRaw[2]{},
|
||||||
pSignature;
|
pSignature;
|
||||||
|
@ -131,7 +131,7 @@ void formatServer(BOOL bUpgrade, WCHAR *pBSection, WCHAR *pAuthSection, WCHAR *p
|
||||||
DWORD nChannelID = wcstoul(pBSection, nullptr, 10);
|
DWORD nChannelID = wcstoul(pBSection, nullptr, 10);
|
||||||
DWORD nAuthInfo = wcstoul(pAuthSection, nullptr, 0) % 0x400;
|
DWORD nAuthInfo = wcstoul(pAuthSection, nullptr, 0) % 0x400;
|
||||||
|
|
||||||
BOOL bValid = keyServer(pKey, nChannelID, nAuthInfo, bUpgrade);
|
BOOL bValid = keyServer(pKey, pBINKPreset, nChannelID, nAuthInfo, bUpgrade);
|
||||||
|
|
||||||
QWORD pRaw[2]{},
|
QWORD pRaw[2]{},
|
||||||
pSignature;
|
pSignature;
|
||||||
|
|
|
@ -61,12 +61,15 @@
|
||||||
|
|
||||||
#include "header.h"
|
#include "header.h"
|
||||||
|
|
||||||
char pCharset[] = "BCDFGHJKMPQRTVWXY2346789";
|
BINKEYEX pBINKPreset;
|
||||||
|
CHAR pCharset[] = "BCDFGHJKMPQRTVWXY2346789";
|
||||||
|
|
||||||
INT wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ WCHAR *pCmdLine, _In_ INT nCmdShow) {
|
INT wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ WCHAR *pCmdLine, _In_ INT nCmdShow) {
|
||||||
srand(GetTickCount64());
|
srand(GetTickCount64());
|
||||||
|
|
||||||
//base(L"D:\\Desktop\\ECC Research\\pIDgen\\pidgenxp.dll");
|
InitializePreset(2, &pBINKPreset);
|
||||||
|
|
||||||
return InitializeWindow(hInstance);
|
return InitializeWindow(hInstance);
|
||||||
|
|
||||||
|
// don't forget to free bink presets (I Forgor)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
#include "presets.h"
|
||||||
|
|
||||||
|
const unsigned long long generatorOrderArr[] = {
|
||||||
|
71314261946000873,
|
||||||
|
65153636961774397,
|
||||||
|
61760995553426173,
|
||||||
|
62443961168019161,
|
||||||
|
5532044755580494717,
|
||||||
|
4755964586330124773,
|
||||||
|
4710798293276956193,
|
||||||
|
5152953887135671777,
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned long long privateKeyArr[] = {
|
||||||
|
42187888123314505,
|
||||||
|
52329725233299758,
|
||||||
|
24306963676698312,
|
||||||
|
32781177223842894,
|
||||||
|
2739897280441110808,
|
||||||
|
174180799641457829,
|
||||||
|
11731326262766101,
|
||||||
|
1583498175279647618,
|
||||||
|
};
|
|
@ -0,0 +1,27 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
enum VERSIONS {
|
||||||
|
W98SE,
|
||||||
|
W98SEOEM,
|
||||||
|
WXP,
|
||||||
|
WXPOEM,
|
||||||
|
WSERVER2003,
|
||||||
|
WXP64,
|
||||||
|
WXP64OEM,
|
||||||
|
WCOUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const wchar_t *pPresets[256];
|
||||||
|
extern const char *p[256];
|
||||||
|
extern const char *a;
|
||||||
|
extern const char *b;
|
||||||
|
extern const char *gx[256];
|
||||||
|
extern const char *gy[256];
|
||||||
|
|
||||||
|
extern const char *kx[256];
|
||||||
|
|
||||||
|
extern const char *ky[256];
|
||||||
|
|
||||||
|
extern const unsigned long long generatorOrderArr[];
|
||||||
|
|
||||||
|
extern const unsigned long long privateKeyArr[];
|
|
@ -10,6 +10,15 @@
|
||||||
#define IDB_BITMAP4 106
|
#define IDB_BITMAP4 106
|
||||||
#define IDB_BITMAP5 107
|
#define IDB_BITMAP5 107
|
||||||
|
|
||||||
|
#define IDR_BINK1 1001
|
||||||
|
#define IDR_BINK2 1002
|
||||||
|
#define IDR_BINK3 1003
|
||||||
|
#define IDR_BINK4 1004
|
||||||
|
#define IDR_BINK5 1005
|
||||||
|
#define IDR_BINK6 1006
|
||||||
|
#define IDR_BINK7 1007
|
||||||
|
#define IDR_BINK8 1008
|
||||||
|
|
||||||
// Next default values for new objects
|
// Next default values for new objects
|
||||||
//
|
//
|
||||||
#ifdef APSTUDIO_INVOKED
|
#ifdef APSTUDIO_INVOKED
|
||||||
|
|
BIN
src/resource.rc
BIN
src/resource.rc
Binary file not shown.
164
src/server.cpp
164
src/server.cpp
|
@ -4,66 +4,6 @@
|
||||||
|
|
||||||
#include "header.h"
|
#include "header.h"
|
||||||
|
|
||||||
/* Windows Server 2003 */
|
|
||||||
const char pSv[] = "C9AE7AED19F6A7E100AADE98134111AD8118E59B8264734327940064BC675A0C682E19C89695FBFA3A4653E47D47FD7592258C7E3C3C61BBEA07FE5A7E842379";
|
|
||||||
const long aSv = 1;
|
|
||||||
const long bSv = 0;
|
|
||||||
|
|
||||||
// Base point G (Generator)
|
|
||||||
const char genXSv[] = "85ACEC9F9F9B456A78E43C3637DC88D21F977A9EC15E5225BD5060CE5B892F24FEDEE574BF5801F06BC232EEF2161074496613698D88FAC4B397CE3B475406A7";
|
|
||||||
const char genYSv[] = "66B7D1983F5D4FE43E8B4F1E28685DE0E22BBE6576A1A6B86C67533BF72FD3D082DBA281A556A16E593DB522942C8DD7120BA50C9413DF944E7258BDDF30B3C4";
|
|
||||||
|
|
||||||
// Inverse of the public key
|
|
||||||
const char pubXSv[] = "90BF6BD980C536A8DB93B52AA9AEBA640BABF1D31BEC7AA345BB7510194A9B07379F552DA7B4A3EF81A9B87E0B85B5118E1E20A098641EE4CCF2045558C98C0E";
|
|
||||||
const char pubYSv[] = "6B87D1E658D03868362945CDD582E2CF33EE4BA06369E0EFE9E4851F6DCBEC7F15081E250D171EA0CC4CB06435BCFCFEA8F438C9766743A06CBD06E7EFB4C3AE";
|
|
||||||
|
|
||||||
// Order of G <- from MSKey 4-in-1
|
|
||||||
const char genOrderSv[] = "4CC5C56529F0237D";
|
|
||||||
|
|
||||||
// Computed private key
|
|
||||||
const char privateKeySv[] = "2606120F59C05118";
|
|
||||||
|
|
||||||
/* Windows XP x64
|
|
||||||
Public key (-K) = (1989960177638374390878377737764297057685259206834686428253479199374616869742150776410973898745805799780071536831208959469038333664656928533078897351495263; 2680493145252003995204016438404731303203625133293449171132691660710342616258476835192643732221910418645447349019141673820306444587247165566828458285756618)
|
|
||||||
Order of base point G (n) = 4710798293276956193
|
|
||||||
Private key (k) = 4699066967014190092 for INVERSE. 11731326262766101
|
|
||||||
|
|
||||||
|
|
||||||
const char pSv[] = "D4B49D04A01EF209121C370DCF0D6292569EC65B8F147A8C62319B6B90DEA2D1CD45199B93582732BFEE27F40BF62D7EB2559BCD08041E301E0D14037A25D989";
|
|
||||||
const long aSv = 1;
|
|
||||||
const long bSv = 0;
|
|
||||||
|
|
||||||
const char genXSv[] = "828A23E65A03F2CE12342DC2B3AA4089C1447DD5C4DC36C0470885A4662F10187037F72B2216C3F671B434267A329BD3363BB27055F0EBBA8A0ABEF451D3F6A3";
|
|
||||||
const char genYSv[] = "23B0823295C9CB669E1643B298624083F68C58F14FEEC55D0B247EF37B353A1066F502D7BC71050056C7D006156A26CC9222F5135FB8B255D7773AE0CDCA31E2";
|
|
||||||
|
|
||||||
const char pubXSv[] = "25FEB90513F63C0833F1096369149E65C9359F4BCC8DE9A8F647030F96485BC71929594FF369DB967910B8F0A59BC7C30CF0D38311486293BA0B2952EE648E5F";
|
|
||||||
const char pubYSv[] = "A186A2C2913E5584F05E97D3CD49E354E6C41BE329877D7FCC7B2BF877A0B00C9298901D305D7FF012FF7902B4202D4ED64D6A90C6AD05960253BAB8F69D68BF";
|
|
||||||
|
|
||||||
// Order of G <- CALCULATED ON MY i7-12700K in 20 seconds
|
|
||||||
const char genOrderSv[] = "41601E16BF4A1621";
|
|
||||||
|
|
||||||
// Computed private key <- CALCULATED ON MY i7-12700K in 5 minutes 40 seconds
|
|
||||||
const char privateKeySv[] = "29AD943EA2EA15"; */
|
|
||||||
|
|
||||||
|
|
||||||
/* Windows XP x64 OEM
|
|
||||||
const char pSv[] = "A6FEDE9568C7863685F783F864A5943D34DED45EC460EEB2EC0455B01BC3C4D21FE081E479F2338BAAF7B10903AC89D23774938F41FDBFB6F16A615ECE5A04A1";
|
|
||||||
const long aSv = 1;
|
|
||||||
const long bSv = 0;
|
|
||||||
|
|
||||||
const char genXSv[] = "3CCFE20244697894A5CF8F8A57F335462C8C7C4935E171A373C2C1BA85C304D121A48931A99E4DD911945B410E10DEF21C00B2ED33FEF4E8F6FCBE16014E0AA8";
|
|
||||||
const char genYSv[] = "7D3F4583D6A45EF6547532B2AE6AC83281317A212223A47ADA92FB48DF055A225DD3E8DF17850EBFAD744780C8166B14F0A39C96B3D216E2247A89518985F6F8";
|
|
||||||
|
|
||||||
const char pubXSv[] = "19D3C8A75DACEAB3CE42970BCF3097F712FD3F6D3B171BE55D7AEF6210C48194480E998AFAC181935DCB9E66BD23769AF5E7ABB8ED2A7E5FAABD4FD1F8D24F7C";
|
|
||||||
const char pubYSv[] = "47A138CDB3C51BEB5443A00FD24734C6DE5DCE6DBA3B2EC337984C09B1CB108E45E8B50F78AEE5FBCA068C0B285576AC26099BD4D52AE2AF9F32A30A340705AF";
|
|
||||||
|
|
||||||
// Order of G <- CALCULATED ON MY i7-12700K in 2 hours (single threaded).
|
|
||||||
const char genOrderSv[] = "4782F84242B0A5E1";
|
|
||||||
|
|
||||||
// Computed private key <- CALCULATED ON MY i7-12700K in 5 minutes 40 seconds
|
|
||||||
const char privateKeySv[] = "15F9B7336005CB82";// or "3189410EE2AADA5F";
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Unpacks the Windows Server 2003-like Product Key. */
|
/* Unpacks the Windows Server 2003-like Product Key. */
|
||||||
VOID unpackServer(
|
VOID unpackServer(
|
||||||
QWORD (&pRaw)[2],
|
QWORD (&pRaw)[2],
|
||||||
|
@ -219,6 +159,30 @@ BOOL verifyServerKey(
|
||||||
// Truncate the hash to 31 bits.
|
// Truncate the hash to 31 bits.
|
||||||
DWORD compHash = BYDWORD(msgDigest) & BITMASK(31);
|
DWORD compHash = BYDWORD(msgDigest) & BITMASK(31);
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
printf(
|
||||||
|
"Validating an XP-like key using following values:\n\n Upgrade: %s\n Channel ID: %d\n AuthInfo: 0x%03lX\n\n Hash: 0x%08lX\n Computed Hash: 0x%08lX\n Signature: 0x%s\n\n",
|
||||||
|
pUpgrade ? "True" : "False",
|
||||||
|
pChannelID,
|
||||||
|
pAuthInfo,
|
||||||
|
pHash,
|
||||||
|
compHash,
|
||||||
|
BN_bn2hex(s)
|
||||||
|
);
|
||||||
|
|
||||||
|
printf(
|
||||||
|
" K(x; y) = {\n 0x%s,\n 0x%s\n }\n\n",
|
||||||
|
BN_bn2hex(x),
|
||||||
|
BN_bn2hex(y)
|
||||||
|
);
|
||||||
|
|
||||||
|
printf(
|
||||||
|
" compHash %s pHash (%s)\n\n\n",
|
||||||
|
compHash == pHash ? "==" : "!=",
|
||||||
|
compHash == pHash ? "VALID" : "INVALID"
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
BN_free(s);
|
BN_free(s);
|
||||||
BN_free(e);
|
BN_free(e);
|
||||||
BN_free(x);
|
BN_free(x);
|
||||||
|
@ -386,6 +350,27 @@ VOID generateServerKey(
|
||||||
// Pack product key.
|
// Pack product key.
|
||||||
packServer(pRaw, pUpgrade, pChannelID, pHash, pSignature, pAuthInfo);
|
packServer(pRaw, pUpgrade, pChannelID, pHash, pSignature, pAuthInfo);
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
printf(
|
||||||
|
"Generating a Server 2003-like key using following values:\n\n Upgrade: %s\n Channel ID: %d\n AuthInfo: 0x%03lX\n\n Generator Order: 0x%s\n Private Key: 0x%s\n Seed: 0x%s\n\n",
|
||||||
|
pUpgrade ? "True" : "False",
|
||||||
|
pChannelID,
|
||||||
|
pAuthInfo,
|
||||||
|
BN_bn2hex(genOrder),
|
||||||
|
BN_bn2hex(privateKey),
|
||||||
|
BN_bn2hex(c)
|
||||||
|
);
|
||||||
|
|
||||||
|
printf(
|
||||||
|
" R(x; y) = {\n 0x%s,\n 0x%s\n }\n\n Signature bits: %02d (%s)\n BN_mod_sqrt(Intermediate): %s\n\n\n",
|
||||||
|
BN_bn2hex(x),
|
||||||
|
BN_bn2hex(y),
|
||||||
|
BN_num_bits(s),
|
||||||
|
BN_num_bits(s) <= 62 ? "GOOD" : "BAD",
|
||||||
|
noSquare ? "False" : "True"
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
EC_POINT_free(r);
|
EC_POINT_free(r);
|
||||||
} while (pSignature > BITMASK(62) || noSquare);
|
} while (pSignature > BITMASK(62) || noSquare);
|
||||||
// ↑ ↑ ↑
|
// ↑ ↑ ↑
|
||||||
|
@ -405,32 +390,39 @@ VOID generateServerKey(
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL keyServer(
|
BOOL keyServer(
|
||||||
CHAR (&pKey)[PK_LENGTH + NULL_TERMINATOR],
|
CHAR (&pKey)[PK_LENGTH + NULL_TERMINATOR],
|
||||||
DWORD nChannelID,
|
BINKEYEX &pBINK,
|
||||||
DWORD nAuthInfo,
|
DWORD nChannelID,
|
||||||
BOOL bUpgrade
|
DWORD nAuthInfo,
|
||||||
|
BOOL bUpgrade
|
||||||
) {
|
) {
|
||||||
// If the Channel ID isn't valid, quit.
|
// If the Channel ID isn't valid, quit.
|
||||||
if (nChannelID >= 1'000)
|
if (nChannelID >= 1'000)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (pBINK.n == 0 ||
|
||||||
|
pBINK.k == 0) {
|
||||||
|
#ifdef _DEBUG
|
||||||
|
printf("!! NOT IMPLEMENTED !!\n\n");
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
BIGNUM *privateKey = BN_new();
|
BIGNUM *privateKey = BN_new();
|
||||||
BIGNUM *genOrder = BN_new();
|
BIGNUM *genOrder = BN_new();
|
||||||
|
|
||||||
BN_hex2bn(&privateKey, privateKeySv);
|
BN_set_word(privateKey, pBINK.k);
|
||||||
BN_hex2bn(&genOrder, genOrderSv);
|
BN_set_word(genOrder, pBINK.n);
|
||||||
|
|
||||||
EC_POINT *genPoint, *pubPoint;
|
EC_POINT *genPoint, *pubPoint;
|
||||||
EC_GROUP *eCurve = initializeEllipticCurve(
|
EC_GROUP *eCurve = initializeEllipticCurve(
|
||||||
pSv,
|
pBINK.binKey.data.p,
|
||||||
aSv,
|
pBINK.binKey.data.a,
|
||||||
bSv,
|
pBINK.binKey.data.b,
|
||||||
genXSv,
|
pBINK.binKey.data.G.x,
|
||||||
genYSv,
|
pBINK.binKey.data.G.y,
|
||||||
pubXSv,
|
pBINK.binKey.data.K.x,
|
||||||
pubYSv,
|
pBINK.binKey.data.K.y,
|
||||||
genOrder,
|
|
||||||
privateKey,
|
|
||||||
&genPoint,
|
&genPoint,
|
||||||
&pubPoint
|
&pubPoint
|
||||||
);
|
);
|
||||||
|
@ -441,9 +433,23 @@ BOOL keyServer(
|
||||||
nAuthInfo &= 0x3FF;
|
nAuthInfo &= 0x3FF;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
#ifdef _DEBUG
|
||||||
generateServerKey(eCurve, genPoint, genOrder, privateKey, nChannelID, nAuthInfo, bUpgrade, pKey);
|
printf(
|
||||||
} while (!verifyServerKey(eCurve, genPoint, pubPoint, pKey));
|
"Created elliptic curve:\n\n E = EllipticCurve(\n GF(0x%s),\n [0, 0, 0, %d, %d]\n ) => y^2 = x^3 + %dx + %d;\n\n G(x; y) = {\n 0x%s,\n 0x%s\n }\n\n K(x; y) = {\n 0x%s,\n 0x%s\n }\n\n AuthInfo: 0x%03lX\n\n\n",
|
||||||
|
pBINK.binKey.data.p,
|
||||||
|
atoi(pBINK.binKey.data.a),
|
||||||
|
atoi(pBINK.binKey.data.b),
|
||||||
|
atoi(pBINK.binKey.data.a),
|
||||||
|
atoi(pBINK.binKey.data.b),
|
||||||
|
pBINK.binKey.data.G.x,
|
||||||
|
pBINK.binKey.data.G.y,
|
||||||
|
pBINK.binKey.data.K.x,
|
||||||
|
pBINK.binKey.data.K.y,
|
||||||
|
nAuthInfo
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
generateServerKey(eCurve, genPoint, genOrder, privateKey, nChannelID, nAuthInfo, bUpgrade, pKey);
|
||||||
|
|
||||||
|
return verifyServerKey(eCurve, genPoint, pubPoint, pKey);
|
||||||
}
|
}
|
|
@ -43,57 +43,54 @@ bool playAudio(HINSTANCE hInstance, WCHAR *lpName, UINT bFlags) {
|
||||||
|
|
||||||
/* Initializes the elliptic curve. */
|
/* Initializes the elliptic curve. */
|
||||||
EC_GROUP *initializeEllipticCurve(
|
EC_GROUP *initializeEllipticCurve(
|
||||||
const char *pSel,
|
CONST CHAR *pSel,
|
||||||
long aSel,
|
CONST CHAR *aSel,
|
||||||
long bSel,
|
CONST CHAR *bSel,
|
||||||
const char *generatorXSel,
|
CONST CHAR *generatorXSel,
|
||||||
const char *generatorYSel,
|
CONST CHAR *generatorYSel,
|
||||||
const char *publicKeyXSel,
|
CONST CHAR *publicKeyXSel,
|
||||||
const char *publicKeyYSel,
|
CONST CHAR *publicKeyYSel,
|
||||||
BIGNUM *genOrderSel,
|
EC_POINT **genPoint,
|
||||||
BIGNUM *privateKeySel,
|
EC_POINT **pubPoint
|
||||||
EC_POINT **genPoint,
|
|
||||||
EC_POINT **pubPoint
|
|
||||||
) {
|
) {
|
||||||
// Initialize BIGNUM and BIGNUMCTX structures.
|
// Initialize BIGNUM and BIGNUMCTX structures.
|
||||||
// BIGNUM - Large numbers
|
// BIGNUM - Large numbers
|
||||||
// BIGNUMCTX - Context large numbers (temporary)
|
// BN_CTX - Context variables (allow concurrency)
|
||||||
BIGNUM *a, *b, *p, *generatorX, *generatorY, *publicKeyX, *publicKeyY;
|
BIGNUM *a, *b, *p, *generatorX, *generatorY, *publicKeyX, *publicKeyY;
|
||||||
BN_CTX *context;
|
BN_CTX *context;
|
||||||
|
|
||||||
// Microsoft Product Key identification program uses a public key stored in pidgen.dll's BINK resource,
|
// Microsoft Product Key identification program uses a public key stored in pidgen.dll's BINK resource,
|
||||||
// which is an Elliptic Curve Cryptography (ECC) public key. It can be decomposed into a following mathematical task:
|
// which is an Elliptic Curve Cryptography (ECC) public key. It can be decomposed into a following mathematical task:
|
||||||
|
|
||||||
// We're presented with an elliptic curve, a multivariable function y(x; p; a; b), where
|
// We're presented with an elliptic curve, a multivariable function F(y; x; p; a; b), where
|
||||||
// y^2 % p = x^3 + ax + b % p.
|
// y^2 = x^3 + ax + b (mod p).
|
||||||
a = BN_new();
|
a = BN_new();
|
||||||
b = BN_new();
|
b = BN_new();
|
||||||
p = BN_new();
|
p = BN_new();
|
||||||
|
|
||||||
// Public key will consist of the resulting (x; y) values.
|
// K(x; y) is the resulting point.
|
||||||
publicKeyX = BN_new();
|
publicKeyX = BN_new();
|
||||||
publicKeyY = BN_new();
|
publicKeyY = BN_new();
|
||||||
|
|
||||||
// G(x; y) is a generator function, its return value represents a point on the elliptic curve.
|
// G(x; y) is the base point.
|
||||||
generatorX = BN_new();
|
generatorX = BN_new();
|
||||||
generatorY = BN_new();
|
generatorY = BN_new();
|
||||||
|
|
||||||
// Context variable
|
// Context variable.
|
||||||
context = BN_CTX_new();
|
context = BN_CTX_new();
|
||||||
|
|
||||||
/* Public data */
|
// Initialize public data from the BINK resource.
|
||||||
BN_hex2bn(&p, pSel);
|
BN_hex2bn(&p, pSel);
|
||||||
BN_set_word(a, aSel);
|
BN_hex2bn(&a, aSel);
|
||||||
BN_set_word(b, bSel);
|
BN_hex2bn(&b, bSel);
|
||||||
BN_hex2bn(&generatorX, generatorXSel);
|
BN_hex2bn(&generatorX, generatorXSel);
|
||||||
BN_hex2bn(&generatorY, generatorYSel);
|
BN_hex2bn(&generatorY, generatorYSel);
|
||||||
|
|
||||||
BN_hex2bn(&publicKeyX, publicKeyXSel);
|
BN_hex2bn(&publicKeyX, publicKeyXSel);
|
||||||
BN_hex2bn(&publicKeyY, publicKeyYSel);
|
BN_hex2bn(&publicKeyY, publicKeyYSel);
|
||||||
|
|
||||||
/* Elliptical Curve calculations. */
|
// Elliptic Curve calculations.
|
||||||
// The group is defined via Fp = all integers [0; p - 1], where p is prime.
|
// The abelian group is defined via Galois field Fp - all integers [0; p - 1], where p is prime.
|
||||||
// The function EC_POINT_set_affine_coordinates() sets the x and y coordinates for the point p defined over the curve given in group.
|
|
||||||
EC_GROUP *eCurve = EC_GROUP_new_curve_GFp(p, a, b, context);
|
EC_GROUP *eCurve = EC_GROUP_new_curve_GFp(p, a, b, context);
|
||||||
|
|
||||||
// Create new point for the generator on the elliptic curve and set its coordinates to (genX; genY).
|
// Create new point for the generator on the elliptic curve and set its coordinates to (genX; genY).
|
||||||
|
@ -108,7 +105,7 @@ EC_GROUP *initializeEllipticCurve(
|
||||||
assert(EC_POINT_is_on_curve(eCurve, *genPoint, context) == 1);
|
assert(EC_POINT_is_on_curve(eCurve, *genPoint, context) == 1);
|
||||||
assert(EC_POINT_is_on_curve(eCurve, *pubPoint, context) == 1);
|
assert(EC_POINT_is_on_curve(eCurve, *pubPoint, context) == 1);
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup.
|
||||||
BN_CTX_free(context);
|
BN_CTX_free(context);
|
||||||
|
|
||||||
return eCurve;
|
return eCurve;
|
||||||
|
|
|
@ -13,18 +13,28 @@
|
||||||
|
|
||||||
HWND hMainWindow;
|
HWND hMainWindow;
|
||||||
|
|
||||||
const WCHAR *pAboutLink = L"https://github.com/Endermanch/XPKeygen",
|
CONST WCHAR *pAboutLink = L"https://github.com/Endermanch/XPKeygen",
|
||||||
*pWebsite = L"https://malwarewatch.org",
|
*pWebsite = L"https://malwarewatch.org",
|
||||||
*pVersion = L"2.5",
|
*pVersion = L"2.5",
|
||||||
*pTitle = L"Windows XP Pro SP3 // Server 2003 SP0 x86 VLK - Enderman[ch]",
|
*pTitle = L"Windows 98 - Windows Server 2003 / SP2 x64 VLK - Enderman[ch]",
|
||||||
*pGroupTitle = L"Windows XP Pro SP3 // Server 2003 SP0 x86 VLK",
|
*pGroupTitle = L"Windows 98 - Windows Server 2003 / SP2 x64 VLK",
|
||||||
*pRBText = L"z22 / MSKey / Endermanch ◄ 14/06/2023";
|
*pRBText = L"z22 / MSKey / Endermanch ◄ 14/06/2023",
|
||||||
|
*pPresets[256] = {
|
||||||
|
L"Windows 98",
|
||||||
|
L"Windows 98 (OEM)",
|
||||||
|
L"Windows XP VLK",
|
||||||
|
L"Windows XP VLK (OEM)",
|
||||||
|
L"Windows Server 2003 VLK",
|
||||||
|
L"Windows Server 2003 VLK (OEM)",
|
||||||
|
L"Windows XP x64 Edition VLK",
|
||||||
|
L"Windows XP x64 Edition VLK (OEM)",
|
||||||
|
};
|
||||||
|
|
||||||
bool bServer = false,
|
BOOL bServer = false,
|
||||||
bUpgrade = false,
|
bUpgrade = false,
|
||||||
bMusic = true;
|
bMusic = true;
|
||||||
|
|
||||||
const int w = 615,
|
CONST INT w = 615,
|
||||||
h = 545,
|
h = 545,
|
||||||
x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2,
|
x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2,
|
||||||
y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2;
|
y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2;
|
||||||
|
@ -543,26 +553,26 @@ LRESULT CALLBACK WNDProc(HWND hWindow, UINT uMessage, WPARAM wParam, LPARAM lPar
|
||||||
|
|
||||||
case IDC_COMBO1:
|
case IDC_COMBO1:
|
||||||
switch (HIWORD(wParam)) {
|
switch (HIWORD(wParam)) {
|
||||||
case CBN_SELCHANGE:
|
case CBN_SELCHANGE: {
|
||||||
int nSelect = SendMessageW((HWND)lParam, CB_GETCURSEL, 0, 0);
|
UINT nPresetSelect = SendMessageW((HWND)lParam, CB_GETCURSEL, 0, 0);
|
||||||
|
|
||||||
switch (nSelect) {
|
InitializePreset(nPresetSelect, &pBINKPreset);
|
||||||
case 0:
|
|
||||||
|
if (pBINKPreset.binKey.header.dwVersion == 19980206) {
|
||||||
EnableWindow(GetDlgItem(hMainWindow, IDC_INPUT2), true);
|
EnableWindow(GetDlgItem(hMainWindow, IDC_INPUT2), true);
|
||||||
EnableWindow(GetDlgItem(hMainWindow, IDC_INPUT3), false);
|
EnableWindow(GetDlgItem(hMainWindow, IDC_INPUT3), false);
|
||||||
|
|
||||||
bServer = false;
|
bServer = false;
|
||||||
break;
|
}
|
||||||
|
else {
|
||||||
case 1:
|
|
||||||
EnableWindow(GetDlgItem(hMainWindow, IDC_INPUT2), false);
|
EnableWindow(GetDlgItem(hMainWindow, IDC_INPUT2), false);
|
||||||
EnableWindow(GetDlgItem(hMainWindow, IDC_INPUT3), true);
|
EnableWindow(GetDlgItem(hMainWindow, IDC_INPUT3), true);
|
||||||
|
|
||||||
bServer = true;
|
bServer = true;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -867,10 +877,11 @@ bool InitializeWindow(HINSTANCE hInstance) {
|
||||||
|
|
||||||
SendMessageW(hComboBox, WM_SETFONT, (WPARAM)hLabelFont, 0);
|
SendMessageW(hComboBox, WM_SETFONT, (WPARAM)hLabelFont, 0);
|
||||||
|
|
||||||
SendMessageW(hComboBox, CB_ADDSTRING, 0, (LPARAM)L"Windows XP (SP0 - SP3)");
|
for (int i = 0; i < countResources(RT_BINK); i++) {
|
||||||
SendMessageW(hComboBox, CB_ADDSTRING, 0, (LPARAM)L"Windows Server 2003 (SP0)");
|
SendMessageW(hComboBox, CB_ADDSTRING, 0, (LPARAM)pPresets[i]);
|
||||||
|
}
|
||||||
|
|
||||||
SendMessageW(hComboBox, CB_SETCURSEL, 0, 0);
|
SendMessageW(hComboBox, CB_SETCURSEL, 2, 0);
|
||||||
|
|
||||||
HWND hUpgrade = CreateWindowExW(
|
HWND hUpgrade = CreateWindowExW(
|
||||||
WS_EX_WINDOWEDGE,
|
WS_EX_WINDOWEDGE,
|
||||||
|
@ -1040,7 +1051,8 @@ bool InitializeWindow(HINSTANCE hInstance) {
|
||||||
|
|
||||||
HWND hAuthInfoLabel = CreateWindowExW(
|
HWND hAuthInfoLabel = CreateWindowExW(
|
||||||
0,
|
0,
|
||||||
L"Static", L"AuthInfo:",
|
L"Static",
|
||||||
|
L"AuthInfo:",
|
||||||
WS_CHILD | WS_VISIBLE,
|
WS_CHILD | WS_VISIBLE,
|
||||||
290, 220 + 1,
|
290, 220 + 1,
|
||||||
70, 16,
|
70, 16,
|
||||||
|
@ -1176,6 +1188,8 @@ bool InitializeWindow(HINSTANCE hInstance) {
|
||||||
ShowWindow(hMainWindow, SW_SHOW);
|
ShowWindow(hMainWindow, SW_SHOW);
|
||||||
UpdateWindow(hMainWindow);
|
UpdateWindow(hMainWindow);
|
||||||
|
|
||||||
|
stopAudio();
|
||||||
|
|
||||||
MSG uMessage;
|
MSG uMessage;
|
||||||
|
|
||||||
while(GetMessageW(&uMessage, nullptr, 0, 0)) {
|
while(GetMessageW(&uMessage, nullptr, 0, 0)) {
|
||||||
|
|
142
src/xp.cpp
142
src/xp.cpp
|
@ -4,46 +4,6 @@
|
||||||
|
|
||||||
#include "header.h"
|
#include "header.h"
|
||||||
|
|
||||||
/* Windows XP */
|
|
||||||
const char pXP[] = "92ddcf14cb9e71f4489a2e9ba350ae29454d98cb93bdbcc07d62b502ea12238ee904a8b20d017197aae0c103b32713a9";
|
|
||||||
const long aXP = 1;
|
|
||||||
const long bXP = 0;
|
|
||||||
|
|
||||||
// Base point G (Generator)
|
|
||||||
const char genXXP[] = "46E3775ECE21B0898D39BEA57050D422A0AF989E497962BAEE2CB17E0A28D5360D5476B8DC966443E37A14F1AEF37742";
|
|
||||||
const char genYXP[] = "7C8E741D2C34F4478E325469CD491603D807222C9C4AC09DDB2B31B3CE3F7CC191B3580079932BC6BEF70BE27604F65E";
|
|
||||||
|
|
||||||
// The public key
|
|
||||||
const char pubXXP[] = "5D8DBE75198015EC41C45AAB6143542EB098F6A5CC9CE4178A1B8A1E7ABBB5BC64DF64FAF6177DC1B0988AB00BA94BF8";
|
|
||||||
const char pubYXP[] = "23A2909A0B4803C89F910C7191758B48746CEA4D5FF07667444ACDB9512080DBCA55E6EBF30433672B894F44ACE92BFA";
|
|
||||||
|
|
||||||
// The order of G was computed in 18 hours using a Pentium III 450
|
|
||||||
const char genOrderXP[] = "DB6B4C58EFBAFD";
|
|
||||||
|
|
||||||
// The private key was computed in 10 hours using a Pentium III 450
|
|
||||||
const char privateKeyXP[] = "565B0DFF8496C8";
|
|
||||||
|
|
||||||
|
|
||||||
/* Windows 98
|
|
||||||
const char pXP[] = "ec224ff2613a9fe1411b51e89634643f79a272402ee146b012a3f71098c7e75df4bf8b3713c4f0ce56691ce56b9b5029";
|
|
||||||
const long aXP = 1;
|
|
||||||
const long bXP = 0;
|
|
||||||
|
|
||||||
// Base point G (Generator)
|
|
||||||
const char genXXP[] = "b5e1957b19951b5523204a62fd83ab22056f59a13bf8aaaf16ac10b7540f8ea92ba28dbfa68996fa12510c024f912340";
|
|
||||||
const char genYXP[] = "a84fbc02f311b1fd4521773e01821bd047f067c496ad54ce1504315cb88667d69130caa25efb2cb1e479ed50efb40d6b";
|
|
||||||
|
|
||||||
// The public key
|
|
||||||
const char pubXXP[] = "26ea9efe57ab6da485225a13ed66533c143f81b7b9528e38c8568bb726a8f0f5607da0e8d85aebf2e1425758b409e811";
|
|
||||||
const char pubYXP[] = "1a7c4cebe5f3919e96876a447a813efcd920979e9610d2b2146a04fab1041b31ae65e24efa3e0b0d61622483655716c2";
|
|
||||||
|
|
||||||
// The order of G was computed in 18 hours using a Pentium III 450
|
|
||||||
const char genOrderXP[] = "E778E33AEE6B3D";
|
|
||||||
|
|
||||||
// The private key was computed in 10 hours using a Pentium III 450
|
|
||||||
const char privateKeyXP[] = "B9E99B9BB9812E"; // "677A485D4BE4A0";*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Unpacks a Windows XP-like Product Key. */
|
/* Unpacks a Windows XP-like Product Key. */
|
||||||
VOID unpackXP(
|
VOID unpackXP(
|
||||||
QWORD (&pRaw)[2],
|
QWORD (&pRaw)[2],
|
||||||
|
@ -172,6 +132,30 @@ BOOL verifyXPKey(
|
||||||
// Truncate the hash to 28 bits.
|
// Truncate the hash to 28 bits.
|
||||||
DWORD compHash = BYDWORD(msgDigest) >> 4 & BITMASK(28);
|
DWORD compHash = BYDWORD(msgDigest) >> 4 & BITMASK(28);
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
printf(
|
||||||
|
"Validating an XP-like key using following values:\n\n Upgrade: %s\n Channel ID: %d\n Sequence: %d\n\n Hash: 0x%08lX\n Computed Hash: 0x%08lX\n Signature: 0x%s\n\n",
|
||||||
|
pUpgrade ? "True" : "False",
|
||||||
|
pChannelID,
|
||||||
|
pSequence,
|
||||||
|
pHash,
|
||||||
|
compHash,
|
||||||
|
BN_bn2hex(s)
|
||||||
|
);
|
||||||
|
|
||||||
|
printf(
|
||||||
|
" K(x; y) = {\n 0x%s,\n 0x%s\n }\n\n",
|
||||||
|
BN_bn2hex(x),
|
||||||
|
BN_bn2hex(y)
|
||||||
|
);
|
||||||
|
|
||||||
|
printf(
|
||||||
|
" compHash %s pHash (%s)\n\n\n",
|
||||||
|
compHash == pHash ? "==" : "!=",
|
||||||
|
compHash == pHash ? "VALID" : "INVALID"
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
BN_free(e);
|
BN_free(e);
|
||||||
BN_free(s);
|
BN_free(s);
|
||||||
BN_free(x);
|
BN_free(x);
|
||||||
|
@ -277,6 +261,26 @@ VOID generateXPKey(
|
||||||
// Pack product key.
|
// Pack product key.
|
||||||
packXP(pRaw, pUpgrade, pChannelID, pSequence, pHash, pSignature);
|
packXP(pRaw, pUpgrade, pChannelID, pSequence, pHash, pSignature);
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
printf(
|
||||||
|
"Generating an XP-like key using following values:\n\n Upgrade: %s\n Channel ID: %d\n Sequence: %d\n\n Generator Order: 0x%s\n Private Key: 0x%s\n Seed: 0x%s\n\n",
|
||||||
|
pUpgrade ? "True" : "False",
|
||||||
|
pChannelID,
|
||||||
|
pSequence,
|
||||||
|
BN_bn2hex(genOrder),
|
||||||
|
BN_bn2hex(privateKey),
|
||||||
|
BN_bn2hex(c)
|
||||||
|
);
|
||||||
|
|
||||||
|
printf(
|
||||||
|
" R(x; y) = {\n 0x%s,\n 0x%s\n }\n\nSignature bits: %02d (%s)\n\n\n",
|
||||||
|
BN_bn2hex(x),
|
||||||
|
BN_bn2hex(y),
|
||||||
|
BN_num_bits(s),
|
||||||
|
BN_num_bits(s) <= 55 ? "GOOD" : "BAD"
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
EC_POINT_free(r);
|
EC_POINT_free(r);
|
||||||
} while (pSignature > BITMASK(55));
|
} while (pSignature > BITMASK(55));
|
||||||
// ↑ ↑ ↑
|
// ↑ ↑ ↑
|
||||||
|
@ -295,39 +299,59 @@ VOID generateXPKey(
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL keyXP(
|
BOOL keyXP(
|
||||||
CHAR (&pKey)[PK_LENGTH + NULL_TERMINATOR],
|
CHAR (&pKey)[PK_LENGTH + NULL_TERMINATOR],
|
||||||
DWORD nChannelID,
|
BINKEYEX &pBINK,
|
||||||
DWORD nSequence,
|
DWORD nChannelID,
|
||||||
BOOL bUpgrade
|
DWORD nSequence,
|
||||||
|
BOOL bUpgrade
|
||||||
) {
|
) {
|
||||||
// If the Channel ID or the random sequence aren't valid, quit.
|
// If the Channel ID or the random sequence aren't valid, quit.
|
||||||
if (nChannelID >= 1'000 || nSequence >= 1'000'000)
|
if (nChannelID >= 1'000 || nSequence >= 1'000'000)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (pBINK.n == 0 ||
|
||||||
|
pBINK.k == 0) {
|
||||||
|
#ifdef _DEBUG
|
||||||
|
printf("!! NOT IMPLEMENTED !!\n\n");
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
BIGNUM *privateKey = BN_new();
|
BIGNUM *privateKey = BN_new();
|
||||||
BIGNUM *genOrder = BN_new();
|
BIGNUM *genOrder = BN_new();
|
||||||
|
|
||||||
BN_hex2bn(&privateKey, privateKeyXP);
|
BN_set_word(privateKey, pBINK.k);
|
||||||
BN_hex2bn(&genOrder, genOrderXP);
|
BN_set_word(genOrder, pBINK.n);
|
||||||
|
|
||||||
EC_POINT *genPoint, *pubPoint;
|
EC_POINT *genPoint, *pubPoint;
|
||||||
EC_GROUP *eCurve = initializeEllipticCurve(
|
EC_GROUP *eCurve = initializeEllipticCurve(
|
||||||
pXP,
|
pBINK.binKey.data.p,
|
||||||
aXP,
|
pBINK.binKey.data.a,
|
||||||
bXP,
|
pBINK.binKey.data.b,
|
||||||
genXXP,
|
pBINK.binKey.data.G.x,
|
||||||
genYXP,
|
pBINK.binKey.data.G.y,
|
||||||
pubXXP,
|
pBINK.binKey.data.K.x,
|
||||||
pubYXP,
|
pBINK.binKey.data.K.y,
|
||||||
genOrder,
|
|
||||||
privateKey,
|
|
||||||
&genPoint,
|
&genPoint,
|
||||||
&pubPoint
|
&pubPoint
|
||||||
);
|
);
|
||||||
|
|
||||||
do {
|
#ifdef _DEBUG
|
||||||
generateXPKey(eCurve, genPoint, genOrder, privateKey, nChannelID, nSequence, bUpgrade, pKey);
|
printf(
|
||||||
} while (!verifyXPKey(eCurve, genPoint, pubPoint, pKey));
|
"Created elliptic curve:\n\n E = EllipticCurve(\n GF(0x%s),\n [0, 0, 0, %d, %d]\n ) => y^2 = x^3 + %dx + %d;\n\n G(x; y) = {\n 0x%s,\n 0x%s\n }\n\n K(x; y) = {\n 0x%s,\n 0x%s\n }\n\n\n",
|
||||||
|
pBINK.binKey.data.p,
|
||||||
|
atoi(pBINK.binKey.data.a),
|
||||||
|
atoi(pBINK.binKey.data.b),
|
||||||
|
atoi(pBINK.binKey.data.a),
|
||||||
|
atoi(pBINK.binKey.data.b),
|
||||||
|
pBINK.binKey.data.G.x,
|
||||||
|
pBINK.binKey.data.G.y,
|
||||||
|
pBINK.binKey.data.K.x,
|
||||||
|
pBINK.binKey.data.K.y
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
generateXPKey(eCurve, genPoint, genOrder, privateKey, nChannelID, nSequence, bUpgrade, pKey);
|
||||||
|
|
||||||
|
return verifyXPKey(eCurve, genPoint, pubPoint, pKey);
|
||||||
}
|
}
|
Loading…
Reference in New Issue