BINK Preset Upgrade
This commit is contained in:
parent
8272256406
commit
0756a807b8
@ -97,7 +97,7 @@
|
||||
<ClCompile>
|
||||
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
|
||||
<Optimization>Disabled</Optimization>
|
||||
@ -184,6 +184,7 @@
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalManifestDependencies>"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
|
||||
<EntryPointSymbol>wWinMainCRTStartup</EntryPointSymbol>
|
||||
<RegisterOutput>true</RegisterOutput>
|
||||
</Link>
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
||||
@ -274,13 +275,13 @@
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<AdditionalManifestDependencies>"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
|
||||
<EntryPointSymbol>wWinMainCRTStartup</EntryPointSymbol>
|
||||
<RegisterOutput>true</RegisterOutput>
|
||||
</Link>
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<Media Include="resources\neon.wav" />
|
||||
<Media Include="resources\pxiii.wav" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@ -293,12 +294,14 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\header.h" />
|
||||
<ClInclude Include="src\presets.h" />
|
||||
<ClInclude Include="src\resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\bink.cpp" />
|
||||
<ClCompile Include="src\key.cpp" />
|
||||
<ClCompile Include="src\main.cpp" />
|
||||
<ClCompile Include="src\presets.cpp" />
|
||||
<ClCompile Include="src\server.cpp" />
|
||||
<ClCompile Include="src\utilities.cpp" />
|
||||
<ClCompile Include="src\windows.cpp" />
|
||||
@ -307,6 +310,16 @@
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="src\resource.rc" />
|
||||
</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" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
@ -10,33 +10,39 @@
|
||||
<Filter Include="Resources">
|
||||
<UniqueIdentifier>{8c8a7e56-fe48-4168-8eb0-0715690de23e}</UniqueIdentifier>
|
||||
</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>
|
||||
<Media Include="resources\neon.wav">
|
||||
<Filter>Resources</Filter>
|
||||
</Media>
|
||||
<Media Include="resources\pxiii.wav">
|
||||
<Filter>Resources</Filter>
|
||||
<Filter>Resources\Wave</Filter>
|
||||
</Media>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="resources\ender.bmp">
|
||||
<Filter>Resources</Filter>
|
||||
</Image>
|
||||
<Image Include="resources\icon.ico">
|
||||
<Filter>Resources</Filter>
|
||||
</Image>
|
||||
<Image Include="resources\logo.bmp">
|
||||
<Filter>Resources</Filter>
|
||||
<Image Include="resources\dropdown.bmp">
|
||||
<Filter>Resources\Bitmaps</Filter>
|
||||
</Image>
|
||||
<Image Include="resources\ender.bmp">
|
||||
<Filter>Resources\Bitmaps</Filter>
|
||||
</Image>
|
||||
<Image Include="resources\musicoff.bmp">
|
||||
<Filter>Resources</Filter>
|
||||
<Filter>Resources\Bitmaps</Filter>
|
||||
</Image>
|
||||
<Image Include="resources\musicon.bmp">
|
||||
<Filter>Resources</Filter>
|
||||
<Filter>Resources\Bitmaps</Filter>
|
||||
</Image>
|
||||
<Image Include="resources\dropdown.bmp">
|
||||
<Filter>Resources</Filter>
|
||||
<Image Include="resources\logo.bmp">
|
||||
<Filter>Resources\Bitmaps</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@ -46,6 +52,9 @@
|
||||
<ClInclude Include="src\resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\presets.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\windows.cpp">
|
||||
@ -69,10 +78,39 @@
|
||||
<ClCompile Include="src\utilities.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\presets.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="src\resource.rc">
|
||||
<Filter>Resources</Filter>
|
||||
</ResourceCompile>
|
||||
</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>
|
BIN
resources/bink/BINK2003.bin
Normal file
BIN
resources/bink/BINK2003.bin
Normal file
Binary file not shown.
BIN
resources/bink/BINK2003OEM.bin
Normal file
BIN
resources/bink/BINK2003OEM.bin
Normal file
Binary file not shown.
BIN
resources/bink/BINK98SE.bin
Normal file
BIN
resources/bink/BINK98SE.bin
Normal file
Binary file not shown.
BIN
resources/bink/BINK98SEOEM.bin
Normal file
BIN
resources/bink/BINK98SEOEM.bin
Normal file
Binary file not shown.
BIN
resources/bink/BINKXP.bin
Normal file
BIN
resources/bink/BINKXP.bin
Normal file
Binary file not shown.
BIN
resources/bink/BINKXP64.bin
Normal file
BIN
resources/bink/BINKXP64.bin
Normal file
Binary file not shown.
BIN
resources/bink/BINKXP64OEM.bin
Normal file
BIN
resources/bink/BINKXP64OEM.bin
Normal file
Binary file not shown.
BIN
resources/bink/BINKXPOEM.bin
Normal file
BIN
resources/bink/BINKXPOEM.bin
Normal file
Binary file not shown.
208
src/bink.cpp
208
src/bink.cpp
@ -3,63 +3,56 @@
|
||||
//
|
||||
|
||||
#include "header.h"
|
||||
|
||||
#define BINK_RETAIL MAKEINTRESOURCEW(1)
|
||||
#define BINK_OEM MAKEINTRESOURCEW(2)
|
||||
|
||||
#define RT_BINK L"BINK"
|
||||
#include "resource.h"
|
||||
#include "presets.h"
|
||||
|
||||
/*
|
||||
Bink resource doesn't exist
|
||||
The file you selected isn't a library
|
||||
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 {
|
||||
// BINK version - not stored in the resource.
|
||||
ULONG32 dwVersion;
|
||||
/*BOOL SelectPreset(int nIndex) {
|
||||
if (nIndex >= WCOUNT) return false;
|
||||
|
||||
// Original BINK header.
|
||||
ULONG32 dwID;
|
||||
ULONG32 dwSize;
|
||||
ULONG32 dwHeaderLength;
|
||||
ULONG32 dwChecksum;
|
||||
ULONG32 dwDate;
|
||||
ULONG32 dwKeySizeInDWORDs;
|
||||
ULONG32 dwHashLength;
|
||||
ULONG32 dwSignatureLength;
|
||||
strcpy(pBINKPreset.p, p[nIndex]);
|
||||
strcpy(pBINKPreset.a, a);
|
||||
strcpy(pBINKPreset.b, b);
|
||||
strcpy(pBINKPreset.G.x, gx[nIndex]);
|
||||
strcpy(pBINKPreset.G.y, gy[nIndex]);
|
||||
strcpy(pBINKPreset.K.x, kx[nIndex]);
|
||||
strcpy(pBINKPreset.K.y, ky[nIndex]);
|
||||
|
||||
// Extended BINK header. (Windows Server 2003+)
|
||||
ULONG32 dwAuthCodeLength;
|
||||
ULONG32 dwProductIDLength;
|
||||
} BINKHDR;
|
||||
pBINKPreset.I.x;
|
||||
pBINKPreset.I.y;
|
||||
|
||||
typedef struct _BINKDATA {
|
||||
CHAR p[256]; // Finite Field order p.
|
||||
CHAR a[256]; // Elliptic Curve parameter a.
|
||||
CHAR b[256]; // Elliptic Curve parameter b.
|
||||
pBINKPreset.n = n[nIndex];
|
||||
pBINKPreset.k = k[nIndex];
|
||||
|
||||
EC_BYTE_POINT G; // Base point (Generator) G.
|
||||
EC_BYTE_POINT K; // Public key K.
|
||||
EC_BYTE_POINT I; // Inverse of the public key K.
|
||||
} BINKDATA;
|
||||
return true;
|
||||
}*/
|
||||
|
||||
typedef struct _BINKEY {
|
||||
BINKHDR header;
|
||||
BINKDATA data;
|
||||
} BINKEY;
|
||||
BOOL CALLBACK EnumResourceProc(HMODULE hModule, CONST WCHAR *lpType, WCHAR *lpName, LONG_PTR lParam) {
|
||||
(*(UINT *)lParam)++;
|
||||
|
||||
DWORD extractBINKResource(HMODULE hLibrary, BYTE **pData) {
|
||||
HRSRC hRes = FindResourceW(hLibrary, BINK_OEM, RT_BINK);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (hRes != NULL) {
|
||||
dwSize = SizeofResource(hLibrary, hRes);
|
||||
*pData = (BYTE *)LoadResource(hLibrary, hRes);
|
||||
dwSize = SizeofResource(hModule, hRes);
|
||||
*pMemory = (BYTE *)LoadResource(hModule, hRes);
|
||||
}
|
||||
|
||||
return dwSize;
|
||||
@ -75,64 +68,135 @@ BYTE hexToDecDigit(CHAR nDigit) {
|
||||
return nDigit - 'A' + 10;
|
||||
}
|
||||
|
||||
ULONG32 byteToInteger(BYTE *pByte) {
|
||||
return hexToDecDigit(pByte[0]) << 4 + hexToDecDigit(pByte[1]);
|
||||
void reverseBytes(BYTE *pBytes) {
|
||||
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));
|
||||
}
|
||||
|
||||
void reverseBytes(CONST BYTE *pBytes, ULONG32 nBytes, BYTE *pReversed) {
|
||||
for (int i = nBytes - 1; i >= 0; i--) {
|
||||
memcpy((BYTE *)&pBytes[i * 2], (BYTE *)&pReversed[(nBytes - i + 1) * 2], 2 * sizeof(BYTE));
|
||||
free(pBytesCopy);
|
||||
}
|
||||
|
||||
VOID byteToHex(BYTE *pDestination, BYTE pByte) {
|
||||
BYTE loByte = pByte % 16,
|
||||
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) {
|
||||
BYTE pULCopy[8] = { 0 };
|
||||
ULONG32 nUL = 0;
|
||||
BOOL decodeBINKResource(BYTE *pData, ULONG32 nLength, BINKEYEX *pBINK) {
|
||||
ULONG32 nStructOffset,
|
||||
nCurveOffset,
|
||||
nCurveField = FIELD_BYTES_2003;
|
||||
|
||||
if (pUL == NULL)
|
||||
return 0;
|
||||
// If BINK is incomplete or the containers are null pointers, return.
|
||||
if (pData == nullptr || pBINK == nullptr || nLength < 0x170) return false;
|
||||
|
||||
if (bLittleEndian)
|
||||
reverseBytes(pUL, 4, pULCopy);
|
||||
// Reset structure to 0.
|
||||
memset(pBINK, 0, sizeof(BINKEYEX));
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
nUL += byteToInteger(&pULCopy[i * 2]);
|
||||
// Read ID and the BINK header.
|
||||
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;
|
||||
|
||||
nCurveField = FIELD_BYTES;
|
||||
}
|
||||
|
||||
void decodeBINKResource(BYTE *pData, ULONG32 nLength, BINKEY *pBINK) {
|
||||
ULONG32 nBlockBytes = 4;
|
||||
for (nCurveOffset = (pBINK->binKey.header.dwHeaderLength + 1) * sizeof(ULONG32); nStructOffset < sizeof(ULONG32) + sizeof(BINKDATA); nStructOffset += FIELD_LENGTH_MAX, nCurveOffset += nCurveField) {
|
||||
BYTE *pCurveParameter = (BYTE *)pBINK + nStructOffset;
|
||||
|
||||
// If BINK is incomplete, return.
|
||||
if (nLength < 0x170) return;
|
||||
formatBytes(pCurveParameter, pData + nCurveOffset, nCurveField);
|
||||
reverseBytes(pCurveParameter);
|
||||
}
|
||||
|
||||
ulToInteger(pData, TRUE);
|
||||
|
||||
/*/ 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) {
|
||||
HMODULE pIDgen = LoadLibraryExW(pPath, NULL, LOAD_LIBRARY_AS_DATAFILE);
|
||||
VOID InitializePreset(UINT nIndex, BINKEYEX *pBINK) {
|
||||
/* HMODULE pIDgen = LoadLibraryExW(pPath, NULL, LOAD_LIBRARY_AS_DATAFILE);
|
||||
|
||||
if (pIDgen == NULL)
|
||||
return;
|
||||
return;*/
|
||||
|
||||
BYTE *pBuffer = NULL;
|
||||
ULONG32 nLength = extractBINKResource(pIDgen, &pBuffer);
|
||||
BYTE *pMemory = NULL;
|
||||
ULONG32 nLength = extractBINKResource(NULL, IDR_BINK1 + nIndex, &pMemory);
|
||||
|
||||
if (nLength == 0) {
|
||||
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;
|
||||
}
|
90
src/header.h
90
src/header.h
@ -18,6 +18,7 @@
|
||||
|
||||
#pragma warning(disable: 6387)
|
||||
|
||||
// Arithmetic macros
|
||||
#define PK_LENGTH 25
|
||||
#define NULL_TERMINATOR 1
|
||||
|
||||
@ -27,9 +28,14 @@
|
||||
#define FIELD_BITS_2003 512
|
||||
#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_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 FIRSTNBITS(field, n) NEXTSNBITS((field), (n), 0)
|
||||
|
||||
@ -37,8 +43,10 @@
|
||||
#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 BYDWORDBE(n) (DWORD)(*((n) + 3) | *((n) + 2) << 8 | *((n) + 1) << 16 | *((n) + 0) << 24)
|
||||
#define BITMASK(n) ((1ULL << (n)) - 1)
|
||||
|
||||
// Control macros
|
||||
#define IDC_BUTTON1 1000
|
||||
#define IDC_BUTTON2 1001
|
||||
#define IDC_BUTTON3 1002
|
||||
@ -67,13 +75,66 @@
|
||||
#define IDC_LABEL5 1109
|
||||
#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;
|
||||
|
||||
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
|
||||
VOID unpackXP(
|
||||
@ -107,6 +168,7 @@ VOID generateXPKey(
|
||||
|
||||
BOOL keyXP(
|
||||
CHAR (&pKey)[PK_LENGTH + NULL_TERMINATOR],
|
||||
BINKEYEX &pBINK,
|
||||
DWORD nChannelID,
|
||||
DWORD nSequence,
|
||||
BOOL bUpgrade
|
||||
@ -152,6 +214,7 @@ VOID generateServerKey(
|
||||
|
||||
BOOL keyServer(
|
||||
CHAR (&pKey)[PK_LENGTH + NULL_TERMINATOR],
|
||||
BINKEYEX &pBINK,
|
||||
DWORD nChannelID,
|
||||
DWORD nAuthInfo,
|
||||
BOOL bUpgrade
|
||||
@ -166,15 +229,13 @@ void stopAudio();
|
||||
bool playAudio(HINSTANCE hInstance, WCHAR *lpName, UINT bFlags);
|
||||
|
||||
EC_GROUP *initializeEllipticCurve(
|
||||
const char *pSel,
|
||||
long aSel,
|
||||
long bSel,
|
||||
const char *generatorXSel,
|
||||
const char *generatorYSel,
|
||||
const char *publicKeyXSel,
|
||||
const char *publicKeyYSel,
|
||||
BIGNUM *genOrderSel,
|
||||
BIGNUM *privateKeySel,
|
||||
CONST CHAR *pSel,
|
||||
CONST CHAR *aSel,
|
||||
CONST CHAR *bSel,
|
||||
CONST CHAR *generatorXSel,
|
||||
CONST CHAR *generatorYSel,
|
||||
CONST CHAR *publicKeyXSel,
|
||||
CONST CHAR *publicKeyYSel,
|
||||
EC_POINT **genPoint,
|
||||
EC_POINT **pubPoint
|
||||
);
|
||||
@ -195,6 +256,7 @@ bool InitializeWindow(HINSTANCE hInstance);
|
||||
|
||||
|
||||
// bink.cpp
|
||||
void base(WCHAR *pPath);
|
||||
VOID InitializePreset(UINT nIndex, BINKEYEX *pBINK);
|
||||
UINT countResources(WCHAR *pName);
|
||||
|
||||
#endif //KEYGEN_HEADER_H
|
||||
|
@ -87,7 +87,7 @@ void formatXP(BOOL bUpgrade, WCHAR *pBSection, WCHAR *pCSection, WCHAR *pText) {
|
||||
DWORD nChannelID = wcstoul(pBSection, 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]{},
|
||||
pSignature;
|
||||
@ -131,7 +131,7 @@ void formatServer(BOOL bUpgrade, WCHAR *pBSection, WCHAR *pAuthSection, WCHAR *p
|
||||
DWORD nChannelID = wcstoul(pBSection, nullptr, 10);
|
||||
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]{},
|
||||
pSignature;
|
||||
|
@ -61,12 +61,15 @@
|
||||
|
||||
#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) {
|
||||
srand(GetTickCount64());
|
||||
|
||||
//base(L"D:\\Desktop\\ECC Research\\pIDgen\\pidgenxp.dll");
|
||||
InitializePreset(2, &pBINKPreset);
|
||||
|
||||
return InitializeWindow(hInstance);
|
||||
|
||||
// don't forget to free bink presets (I Forgor)
|
||||
}
|
||||
|
23
src/presets.cpp
Normal file
23
src/presets.cpp
Normal file
@ -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,
|
||||
};
|
27
src/presets.h
Normal file
27
src/presets.h
Normal file
@ -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_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
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
|
BIN
src/resource.rc
BIN
src/resource.rc
Binary file not shown.
156
src/server.cpp
156
src/server.cpp
@ -4,66 +4,6 @@
|
||||
|
||||
#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. */
|
||||
VOID unpackServer(
|
||||
QWORD (&pRaw)[2],
|
||||
@ -219,6 +159,30 @@ BOOL verifyServerKey(
|
||||
// Truncate the hash to 31 bits.
|
||||
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(e);
|
||||
BN_free(x);
|
||||
@ -386,6 +350,27 @@ VOID generateServerKey(
|
||||
// Pack product key.
|
||||
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);
|
||||
} while (pSignature > BITMASK(62) || noSquare);
|
||||
// ↑ ↑ ↑
|
||||
@ -406,6 +391,7 @@ VOID generateServerKey(
|
||||
|
||||
BOOL keyServer(
|
||||
CHAR (&pKey)[PK_LENGTH + NULL_TERMINATOR],
|
||||
BINKEYEX &pBINK,
|
||||
DWORD nChannelID,
|
||||
DWORD nAuthInfo,
|
||||
BOOL bUpgrade
|
||||
@ -414,23 +400,29 @@ BOOL keyServer(
|
||||
if (nChannelID >= 1'000)
|
||||
return false;
|
||||
|
||||
if (pBINK.n == 0 ||
|
||||
pBINK.k == 0) {
|
||||
#ifdef _DEBUG
|
||||
printf("!! NOT IMPLEMENTED !!\n\n");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
BIGNUM *privateKey = BN_new();
|
||||
BIGNUM *genOrder = BN_new();
|
||||
|
||||
BN_hex2bn(&privateKey, privateKeySv);
|
||||
BN_hex2bn(&genOrder, genOrderSv);
|
||||
BN_set_word(privateKey, pBINK.k);
|
||||
BN_set_word(genOrder, pBINK.n);
|
||||
|
||||
EC_POINT *genPoint, *pubPoint;
|
||||
EC_GROUP *eCurve = initializeEllipticCurve(
|
||||
pSv,
|
||||
aSv,
|
||||
bSv,
|
||||
genXSv,
|
||||
genYSv,
|
||||
pubXSv,
|
||||
pubYSv,
|
||||
genOrder,
|
||||
privateKey,
|
||||
pBINK.binKey.data.p,
|
||||
pBINK.binKey.data.a,
|
||||
pBINK.binKey.data.b,
|
||||
pBINK.binKey.data.G.x,
|
||||
pBINK.binKey.data.G.y,
|
||||
pBINK.binKey.data.K.x,
|
||||
pBINK.binKey.data.K.y,
|
||||
&genPoint,
|
||||
&pubPoint
|
||||
);
|
||||
@ -441,9 +433,23 @@ BOOL keyServer(
|
||||
nAuthInfo &= 0x3FF;
|
||||
}
|
||||
|
||||
do {
|
||||
generateServerKey(eCurve, genPoint, genOrder, privateKey, nChannelID, nAuthInfo, bUpgrade, pKey);
|
||||
} while (!verifyServerKey(eCurve, genPoint, pubPoint, pKey));
|
||||
#ifdef _DEBUG
|
||||
printf(
|
||||
"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. */
|
||||
EC_GROUP *initializeEllipticCurve(
|
||||
const char *pSel,
|
||||
long aSel,
|
||||
long bSel,
|
||||
const char *generatorXSel,
|
||||
const char *generatorYSel,
|
||||
const char *publicKeyXSel,
|
||||
const char *publicKeyYSel,
|
||||
BIGNUM *genOrderSel,
|
||||
BIGNUM *privateKeySel,
|
||||
CONST CHAR *pSel,
|
||||
CONST CHAR *aSel,
|
||||
CONST CHAR *bSel,
|
||||
CONST CHAR *generatorXSel,
|
||||
CONST CHAR *generatorYSel,
|
||||
CONST CHAR *publicKeyXSel,
|
||||
CONST CHAR *publicKeyYSel,
|
||||
EC_POINT **genPoint,
|
||||
EC_POINT **pubPoint
|
||||
) {
|
||||
// Initialize BIGNUM and BIGNUMCTX structures.
|
||||
// BIGNUM - Large numbers
|
||||
// BIGNUMCTX - Context large numbers (temporary)
|
||||
// BN_CTX - Context variables (allow concurrency)
|
||||
BIGNUM *a, *b, *p, *generatorX, *generatorY, *publicKeyX, *publicKeyY;
|
||||
BN_CTX *context;
|
||||
|
||||
// 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:
|
||||
|
||||
// We're presented with an elliptic curve, a multivariable function y(x; p; a; b), where
|
||||
// y^2 % p = x^3 + ax + b % p.
|
||||
// We're presented with an elliptic curve, a multivariable function F(y; x; p; a; b), where
|
||||
// y^2 = x^3 + ax + b (mod p).
|
||||
a = BN_new();
|
||||
b = 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();
|
||||
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();
|
||||
generatorY = BN_new();
|
||||
|
||||
// Context variable
|
||||
// Context variable.
|
||||
context = BN_CTX_new();
|
||||
|
||||
/* Public data */
|
||||
// Initialize public data from the BINK resource.
|
||||
BN_hex2bn(&p, pSel);
|
||||
BN_set_word(a, aSel);
|
||||
BN_set_word(b, bSel);
|
||||
BN_hex2bn(&a, aSel);
|
||||
BN_hex2bn(&b, bSel);
|
||||
BN_hex2bn(&generatorX, generatorXSel);
|
||||
BN_hex2bn(&generatorY, generatorYSel);
|
||||
|
||||
BN_hex2bn(&publicKeyX, publicKeyXSel);
|
||||
BN_hex2bn(&publicKeyY, publicKeyYSel);
|
||||
|
||||
/* Elliptical Curve calculations. */
|
||||
// The group is defined via 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.
|
||||
// Elliptic Curve calculations.
|
||||
// The abelian group is defined via Galois field Fp - all integers [0; p - 1], where p is prime.
|
||||
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).
|
||||
@ -108,7 +105,7 @@ EC_GROUP *initializeEllipticCurve(
|
||||
assert(EC_POINT_is_on_curve(eCurve, *genPoint, context) == 1);
|
||||
assert(EC_POINT_is_on_curve(eCurve, *pubPoint, context) == 1);
|
||||
|
||||
// Cleanup
|
||||
// Cleanup.
|
||||
BN_CTX_free(context);
|
||||
|
||||
return eCurve;
|
||||
|
@ -13,18 +13,28 @@
|
||||
|
||||
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",
|
||||
*pVersion = L"2.5",
|
||||
*pTitle = L"Windows XP Pro SP3 // Server 2003 SP0 x86 VLK - Enderman[ch]",
|
||||
*pGroupTitle = L"Windows XP Pro SP3 // Server 2003 SP0 x86 VLK",
|
||||
*pRBText = L"z22 / MSKey / Endermanch ◄ 14/06/2023";
|
||||
*pTitle = L"Windows 98 - Windows Server 2003 / SP2 x64 VLK - Enderman[ch]",
|
||||
*pGroupTitle = L"Windows 98 - Windows Server 2003 / SP2 x64 VLK",
|
||||
*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,
|
||||
bMusic = true;
|
||||
|
||||
const int w = 615,
|
||||
CONST INT w = 615,
|
||||
h = 545,
|
||||
x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2,
|
||||
y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2;
|
||||
@ -543,27 +553,27 @@ LRESULT CALLBACK WNDProc(HWND hWindow, UINT uMessage, WPARAM wParam, LPARAM lPar
|
||||
|
||||
case IDC_COMBO1:
|
||||
switch (HIWORD(wParam)) {
|
||||
case CBN_SELCHANGE:
|
||||
int nSelect = SendMessageW((HWND)lParam, CB_GETCURSEL, 0, 0);
|
||||
case CBN_SELCHANGE: {
|
||||
UINT nPresetSelect = SendMessageW((HWND)lParam, CB_GETCURSEL, 0, 0);
|
||||
|
||||
switch (nSelect) {
|
||||
case 0:
|
||||
InitializePreset(nPresetSelect, &pBINKPreset);
|
||||
|
||||
if (pBINKPreset.binKey.header.dwVersion == 19980206) {
|
||||
EnableWindow(GetDlgItem(hMainWindow, IDC_INPUT2), true);
|
||||
EnableWindow(GetDlgItem(hMainWindow, IDC_INPUT3), false);
|
||||
|
||||
bServer = false;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
}
|
||||
else {
|
||||
EnableWindow(GetDlgItem(hMainWindow, IDC_INPUT2), false);
|
||||
EnableWindow(GetDlgItem(hMainWindow, IDC_INPUT3), true);
|
||||
|
||||
bServer = true;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@ -867,10 +877,11 @@ bool InitializeWindow(HINSTANCE hInstance) {
|
||||
|
||||
SendMessageW(hComboBox, WM_SETFONT, (WPARAM)hLabelFont, 0);
|
||||
|
||||
SendMessageW(hComboBox, CB_ADDSTRING, 0, (LPARAM)L"Windows XP (SP0 - SP3)");
|
||||
SendMessageW(hComboBox, CB_ADDSTRING, 0, (LPARAM)L"Windows Server 2003 (SP0)");
|
||||
for (int i = 0; i < countResources(RT_BINK); i++) {
|
||||
SendMessageW(hComboBox, CB_ADDSTRING, 0, (LPARAM)pPresets[i]);
|
||||
}
|
||||
|
||||
SendMessageW(hComboBox, CB_SETCURSEL, 0, 0);
|
||||
SendMessageW(hComboBox, CB_SETCURSEL, 2, 0);
|
||||
|
||||
HWND hUpgrade = CreateWindowExW(
|
||||
WS_EX_WINDOWEDGE,
|
||||
@ -1040,7 +1051,8 @@ bool InitializeWindow(HINSTANCE hInstance) {
|
||||
|
||||
HWND hAuthInfoLabel = CreateWindowExW(
|
||||
0,
|
||||
L"Static", L"AuthInfo:",
|
||||
L"Static",
|
||||
L"AuthInfo:",
|
||||
WS_CHILD | WS_VISIBLE,
|
||||
290, 220 + 1,
|
||||
70, 16,
|
||||
@ -1176,6 +1188,8 @@ bool InitializeWindow(HINSTANCE hInstance) {
|
||||
ShowWindow(hMainWindow, SW_SHOW);
|
||||
UpdateWindow(hMainWindow);
|
||||
|
||||
stopAudio();
|
||||
|
||||
MSG uMessage;
|
||||
|
||||
while(GetMessageW(&uMessage, nullptr, 0, 0)) {
|
||||
|
134
src/xp.cpp
134
src/xp.cpp
@ -4,46 +4,6 @@
|
||||
|
||||
#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. */
|
||||
VOID unpackXP(
|
||||
QWORD (&pRaw)[2],
|
||||
@ -172,6 +132,30 @@ BOOL verifyXPKey(
|
||||
// Truncate the hash to 28 bits.
|
||||
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(s);
|
||||
BN_free(x);
|
||||
@ -277,6 +261,26 @@ VOID generateXPKey(
|
||||
// Pack product key.
|
||||
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);
|
||||
} while (pSignature > BITMASK(55));
|
||||
// ↑ ↑ ↑
|
||||
@ -296,6 +300,7 @@ VOID generateXPKey(
|
||||
|
||||
BOOL keyXP(
|
||||
CHAR (&pKey)[PK_LENGTH + NULL_TERMINATOR],
|
||||
BINKEYEX &pBINK,
|
||||
DWORD nChannelID,
|
||||
DWORD nSequence,
|
||||
BOOL bUpgrade
|
||||
@ -304,30 +309,49 @@ BOOL keyXP(
|
||||
if (nChannelID >= 1'000 || nSequence >= 1'000'000)
|
||||
return false;
|
||||
|
||||
if (pBINK.n == 0 ||
|
||||
pBINK.k == 0) {
|
||||
#ifdef _DEBUG
|
||||
printf("!! NOT IMPLEMENTED !!\n\n");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
BIGNUM *privateKey = BN_new();
|
||||
BIGNUM *genOrder = BN_new();
|
||||
|
||||
BN_hex2bn(&privateKey, privateKeyXP);
|
||||
BN_hex2bn(&genOrder, genOrderXP);
|
||||
BN_set_word(privateKey, pBINK.k);
|
||||
BN_set_word(genOrder, pBINK.n);
|
||||
|
||||
EC_POINT *genPoint, *pubPoint;
|
||||
EC_GROUP *eCurve = initializeEllipticCurve(
|
||||
pXP,
|
||||
aXP,
|
||||
bXP,
|
||||
genXXP,
|
||||
genYXP,
|
||||
pubXXP,
|
||||
pubYXP,
|
||||
genOrder,
|
||||
privateKey,
|
||||
pBINK.binKey.data.p,
|
||||
pBINK.binKey.data.a,
|
||||
pBINK.binKey.data.b,
|
||||
pBINK.binKey.data.G.x,
|
||||
pBINK.binKey.data.G.y,
|
||||
pBINK.binKey.data.K.x,
|
||||
pBINK.binKey.data.K.y,
|
||||
&genPoint,
|
||||
&pubPoint
|
||||
);
|
||||
|
||||
do {
|
||||
generateXPKey(eCurve, genPoint, genOrder, privateKey, nChannelID, nSequence, bUpgrade, pKey);
|
||||
} while (!verifyXPKey(eCurve, genPoint, pubPoint, pKey));
|
||||
#ifdef _DEBUG
|
||||
printf(
|
||||
"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…
x
Reference in New Issue
Block a user