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>
|
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"
|
||||
|
||||
#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));
|
||||
}
|
||||
|
||||
free(pBytesCopy);
|
||||
}
|
||||
|
||||
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));
|
||||
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;
|
||||
|
||||
void decodeBINKResource(BYTE *pData, ULONG32 nLength, BINKEY *pBINK) {
|
||||
ULONG32 nBlockBytes = 4;
|
||||
nCurveField = FIELD_BYTES;
|
||||
}
|
||||
|
||||
// If BINK is incomplete, return.
|
||||
if (nLength < 0x170) return;
|
||||
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;
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
94
src/header.h
94
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,17 +75,70 @@
|
|||
#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(
|
||||
QWORD(&pRaw)[2],
|
||||
QWORD (&pRaw)[2],
|
||||
BOOL &pUpgrade,
|
||||
DWORD &pChannelID,
|
||||
DWORD &pSequence,
|
||||
|
@ -106,7 +167,8 @@ VOID generateXPKey(
|
|||
);
|
||||
|
||||
BOOL keyXP(
|
||||
CHAR(&pKey)[PK_LENGTH + NULL_TERMINATOR],
|
||||
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)
|
||||
}
|
||||
|
|
|
@ -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_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…
Reference in New Issue