Compare commits
7 Commits
drazisil/p
...
main
Author | SHA1 | Date |
---|---|---|
|
87f567b602 | |
|
4350242e41 | |
|
e82c530910 | |
|
cefd2151d0 | |
|
e92e19757c | |
|
0756a807b8 | |
|
24df6464d1 |
|
@ -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>
|
|
@ -2,7 +2,7 @@
|
||||||
A Windows XP / Windows Server 2003 VLK key generator. This tool allows you to generate _valid Windows XP keys_ based on the _Raw Product Key_, which can be random.
|
A Windows XP / Windows Server 2003 VLK key generator. This tool allows you to generate _valid Windows XP keys_ based on the _Raw Product Key_, which can be random.
|
||||||
The **Raw Product Key (RPK)** is supplied in form of 9 digits `XXX-YYYYYY` and is only necessary to generate a Windows XP Key.
|
The **Raw Product Key (RPK)** is supplied in form of 9 digits `XXX-YYYYYY` and is only necessary to generate a Windows XP Key.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
### Download
|
### Download
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
## 6. Product ID
|
||||||
|
|
||||||
|
Product ID is 5 groups of decimals, e.g.:
|
||||||
|
|
||||||
|
```
|
||||||
|
AAAAA BBB CCCCCCC DD EEE
|
||||||
|
52273 005 6861993 09 146
|
||||||
|
```
|
||||||
|
|
||||||
|
If you search `ProductID` in registry, you will find a product ID associated with your currently installed one.
|
||||||
|
|
||||||
|
The meaning of each group of numbers:
|
||||||
|
|
||||||
|
| Number | Meaning |
|
||||||
|
| --------- | ----------------------------------------------------------------------------------------------- |
|
||||||
|
| `AAAAA` | Product code. e.g.: `55661` for Windows Pro; `55660` for Windows Home. |
|
||||||
|
| `BBB` | First 3 effective number digits of Primary Product Serial. |
|
||||||
|
| `CCCCCCC` | Last 6 effective number digits of Primary Product Serial, and a digit of checksum. |
|
||||||
|
| `DD` | Public key index number for product validation. e.g.: Pro is 22, VLK is 23. |
|
||||||
|
| `EEE` | Nonce (random number), for generating different install ID when doing activation via telephone. |
|
||||||
|
|
||||||
|
For `CCCCCCC` mentioned above, it had two parts including 1 digit and 6 digits. The checksum is calculated as follows: **Add all digits together (including the checksum digit), it is divisible by 7.**
|
||||||
|
For example: the last 6 digits of Primary Product Serial is `728439`, then `7 + 2 + 8 + 4 + 3 + 9 = 33` , then the checksum digit should be `2`, because `7 + 2 + 8 + 4 + 3 + 9 + 2 = 33 + 2 = 35`, and 35 is divisible by 7. So the `CCCCCCC` in Product ID should be `7284392`.
|
||||||
|
|
||||||
|
## 7. OEM related mechanism
|
||||||
|
<!-- Oh boy this section is a total mess... The original content itself is confusing as hell.. -->
|
||||||
|
|
||||||
|
For licensed product to OEMs, starting from Windows XP, Microsoft is using SLP (System-Locked Preinstallation) technology, aka.: before installing the OS, lock in the motherboard with the OS. Windows XP used SLP 1.0, it works by detecting specific string set by OEM in BIOS. This method is easy to be spoofed, but the VLK crack is more easy to use so this method is not wide-spread.
|
||||||
|
From the Windows Vista, SLP upgraded to 2.0 . Primarily the change is using cryptographic key pairs to sign the data to prevent spoofing. This requires a special SLIC (Software Licensing Internal Code) table in BIOS to support this.
|
||||||
|
In Windows 7 series of product, SLP 2.1 is used, but there is no major changes in SLP for this revision, only updated the marker in SLIC to 2.1 .
|
||||||
|
|
||||||
|
SLIC is the important part of SLP, usually directly backed in BIOS ROM, as the most underlying information of OS activation. SLIC contains the digital signature of OEM, when OS is activating, the upper level certificate must can be verified with the OEM information inside SLIC. SLIC usually contained inside SLDT(Software Licensing Description Table), which 374 bytes long, and SLDT itself is contained inside ACPI(Advanced Configuration and Power Management Interface).
|
||||||
|
|
||||||
|
OEM certificate is a certification file provided by Microsoft, including to some mandatory information provided by OEM, the extension for the file is `xrm-ms`. The OEM certificate including the OEM identification information and digitally signed by Microsoft. When OS is activating, the OEM certificate must can be validated against SLIC.
|
||||||
|
|
||||||
|
OEM product key seems no difference with retail product key, but OEM key is only valid for OEM activation, and it identifies the Windows product variation. Windows Vista cancelled the VLK model, only OEM activation is provided, and used SLP 2.0, used public key instead plain text for validation, caused difficulties for cracking.
|
||||||
|
|
||||||
|
### Windows Vista (SLP 2.0)
|
||||||
|
<!-- Following procedure is for SLP 2.0, which is for Windows Vista. -->
|
||||||
|
The procedure for SLP 2.0 verification is as follows:
|
||||||
|
|
||||||
|
1. When installing Windows Vista, retail version user need to input the serial (CD-KEY) presented on the box. For users who got the OEM version of Windows Vista with the computer, they can find a sticker that corresponding the version they got with the computer, as a voucher for purchasing the Windows Vista OEM version. The system identifies different versions of Windows Vista based on their serial numbers, such as Home Basic, Home Advanced, Business, Ultimate, and so on. After installation, the serial number is converted into 4 sets of letters or numbers, which is the "Product ID" shown in the "System Properties". The second group is the "OEM" one, which is the serial number (CD-KEY) of the OEM version. From now on, the product ID replaces the CD-KEY <!-- as user inputted their retail CD-KEY on the box, this OEM product ID became the CD-KEY in this case -->, and the installer generates an OEM certificate for the OEM version of the installation <!-- "product certificate" maybe? And, installed to where? usually the installation is done by OEM. The information is conflicting with the "OEM certificate is a certification file provided by Microsoft" mentioned above. -->.
|
||||||
|
|
||||||
|
2. The information in the BIOS got loaded into RAM every time system boots.
|
||||||
|
|
||||||
|
3. After logging into the Windows Vista, OS calls SLP service to check the licensed rights of running product, especially the activation status. It starts to identify the licensing status of the system based on the product ID. If no product ID is detected or no valid retail version product ID is detected, it is considered as inactivated. If a valid retail version product ID is detected, it is considered successfully activated. If an OEM version of the product ID is detected, continue with the OEM verification.
|
||||||
|
|
||||||
|
4. If the OEM product ID is detected, the OEM verification process starts, and it will check the installed OEM certificate <!-- "product certificate" ? --> is valid. It mainly uses the SLIC public key from BIOS which is loaded into the RAM, to verify the digital signature of product certificate <!-- Yes, this "product certificate" came from nowhere, so I guess this the OEM certificate that installed while installing the Windows Vista by OEM. -->. If validation failed, it is considered as inactivated.
|
||||||
|
|
||||||
|
5. Verify the OEM ID field between SLIC and RSDT (Root System Description Table), and compare the OEM ID field and OEM Table ID fields between SLIC and XSDT (Extended System Description Table). If they didn't match, it is considered as inactivated.
|
||||||
|
|
||||||
|
6. After the above hurdles, the OEM license will be considered as activated. If not then fallback to inactivated and continue with normal procedure, like require user to activate the Windows.
|
||||||
|
|
||||||
|
### Windows 7 (SLP 2.1)
|
||||||
|
<!-- Following procedure is for SLP 2.1, which is for Windows 7. -->
|
||||||
|
Windows 7 still retains the OEM activation policy, but using SLP 2.1 instead.
|
||||||
|
|
||||||
|
Here is more detailed verification process:
|
||||||
|
|
||||||
|
1. After the activation process starts, if the correct SLP Key is detected, the OEM activation process starts, otherwise the WPA activation (online or telephone activation) is performed.
|
||||||
|
|
||||||
|
2. Detect the OEM certificate <!-- "product certificate" ? -->, and use the digital signature inside the OEM certificate to validate the it (Microsoft used their private key to sign the OEM certificate, and verified against the public key), if verified then continue on OEM activation process, otherwise continue on WPA activation process.
|
||||||
|
|
||||||
|
3. Compare the OEM public key, OEM ID and various fields with the information presented in the OEM certificate <!-- "product certificate" ? -->. If they match (this means OEM public key and etc. are correct), then continue on OEM activation process, otherwise continue on WPA activation process.
|
||||||
|
|
||||||
|
4. Use OEM public key verify against the digital signature of the Marker inside SLIC. if verified (this means the Message in the Marker is correct. <!-- There is no where talked about what is that Message and Marker. -->) then continue on OEM activation process, otherwise continue on WPA activation process.
|
||||||
|
|
||||||
|
5. Verify the Windows Logo <!-- I guess? "Windows Logo" part can be directly translate to "Windows Flag Mark", and this "Flag" means that actual waving thing, not a digital bit. I guess this approach is similar as the Nintendo logo bitmap inside Game Boy game cartridge ROM thing. --> inside the Marker. If the Windows Logo is present, then continue on OEM activation process, otherwise continue on WPA activation process.
|
||||||
|
|
||||||
|
6. Verify the version of Marker. If it's at least `0x20001` then continue on OEM activation process, otherwise OEM activation failed, and continue on WPA activation process.
|
||||||
|
|
||||||
|
7. Compare the OEM ID and OEM Table ID against all corresponding ACPI table headers. If they match, then OEM activation completed successfully, otherwise continue on WPA activation process.
|
||||||
|
|
||||||
|
Key points (Not containing all details, this info is only there to emphasize the key points of Microsoft encryption):
|
||||||
|
|
||||||
|
1. OEM certificate <!-- "product certificate" ? --> contains
|
||||||
|
- Data (OEM ID and other information, Microsoft public key, etc.)
|
||||||
|
- Hash (Hash of data)
|
||||||
|
- Signature (Hash were signed with Microsoft private key)
|
||||||
|
|
||||||
|
2. SLIC contains:
|
||||||
|
- Data (OEM ID, Marker version, etc., Microsoft public key, etc.)
|
||||||
|
- Hash (Hash the data)
|
||||||
|
- Signature (Hash were signed with Microsoft private key)
|
||||||
|
|
||||||
|
3. First, use the public key to verify whether the signatures of OEM and SLIC, then, compare the OEM ID, public key and other information in OEM and SLIC to see whether they are the same; verify the Marker version is matching the type of system currently installed.
|
||||||
|
|
||||||
|
* * *
|
||||||
|
Oh boy what a mess...
|
||||||
|
|
||||||
|
This source is from CSDN.net, and this is a known "copy paste and profit" site that infamous in China.
|
||||||
|
|
||||||
|
This article is old enough that the author is actually had integrity and cited all the actual juicy sources. However, all the actual juicy sources were long gone, because the BBS that the author cited is down,only unusable archives were left (reported by discord member @itsmefeng ).
|
||||||
|
|
||||||
|
This article isn't providing enough information on how to crack the Windows Vista/7 activation process. We may need more actual good sources for this.
|
||||||
|
|
||||||
|
For better understanding I provided some comment (as HTML comments for Markdown compatibility). Hopefully it will be useful.
|
||||||
|
|
||||||
|
-- Some Anonymous Person
|
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.
208
src/bink.cpp
208
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
void reverseBytes(CONST BYTE *pBytes, ULONG32 nBytes, BYTE *pReversed) {
|
free(pBytesCopy);
|
||||||
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) {
|
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;
|
||||||
|
|
||||||
|
nCurveField = FIELD_BYTES;
|
||||||
}
|
}
|
||||||
|
|
||||||
void decodeBINKResource(BYTE *pData, ULONG32 nLength, BINKEY *pBINK) {
|
for (nCurveOffset = (pBINK->binKey.header.dwHeaderLength + 1) * sizeof(ULONG32); nStructOffset < sizeof(ULONG32) + sizeof(BINKDATA); nStructOffset += FIELD_LENGTH_MAX, nCurveOffset += nCurveField) {
|
||||||
ULONG32 nBlockBytes = 4;
|
BYTE *pCurveParameter = (BYTE *)pBINK + nStructOffset;
|
||||||
|
|
||||||
// If BINK is incomplete, return.
|
formatBytes(pCurveParameter, pData + nCurveOffset, nCurveField);
|
||||||
if (nLength < 0x170) return;
|
reverseBytes(pCurveParameter);
|
||||||
|
}
|
||||||
|
|
||||||
ulToInteger(pData, TRUE);
|
|
||||||
|
|
||||||
/*/ Read BINK header.
|
|
||||||
for (ULONG32 nOffset = 0; nOffset < sizeof(BINKHDR); nOffset += nBlockBytes) {
|
// Calculate the inverse of the public key.
|
||||||
pBINK[nOffset] =
|
// 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;
|
||||||
}
|
}
|
90
src/header.h
90
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,13 +75,66 @@
|
||||||
#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(
|
||||||
|
@ -107,6 +168,7 @@ VOID generateXPKey(
|
||||||
|
|
||||||
BOOL keyXP(
|
BOOL keyXP(
|
||||||
CHAR (&pKey)[PK_LENGTH + NULL_TERMINATOR],
|
CHAR (&pKey)[PK_LENGTH + NULL_TERMINATOR],
|
||||||
|
BINKEYEX &pBINK,
|
||||||
DWORD nChannelID,
|
DWORD nChannelID,
|
||||||
DWORD nSequence,
|
DWORD nSequence,
|
||||||
BOOL bUpgrade
|
BOOL bUpgrade
|
||||||
|
@ -152,6 +214,7 @@ VOID generateServerKey(
|
||||||
|
|
||||||
BOOL keyServer(
|
BOOL keyServer(
|
||||||
CHAR (&pKey)[PK_LENGTH + NULL_TERMINATOR],
|
CHAR (&pKey)[PK_LENGTH + NULL_TERMINATOR],
|
||||||
|
BINKEYEX &pBINK,
|
||||||
DWORD nChannelID,
|
DWORD nChannelID,
|
||||||
DWORD nAuthInfo,
|
DWORD nAuthInfo,
|
||||||
BOOL bUpgrade
|
BOOL bUpgrade
|
||||||
|
@ -166,15 +229,13 @@ 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,
|
|
||||||
BIGNUM *privateKeySel,
|
|
||||||
EC_POINT **genPoint,
|
EC_POINT **genPoint,
|
||||||
EC_POINT **pubPoint
|
EC_POINT **pubPoint
|
||||||
);
|
);
|
||||||
|
@ -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.
156
src/server.cpp
156
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);
|
||||||
// ↑ ↑ ↑
|
// ↑ ↑ ↑
|
||||||
|
@ -406,6 +391,7 @@ VOID generateServerKey(
|
||||||
|
|
||||||
BOOL keyServer(
|
BOOL keyServer(
|
||||||
CHAR (&pKey)[PK_LENGTH + NULL_TERMINATOR],
|
CHAR (&pKey)[PK_LENGTH + NULL_TERMINATOR],
|
||||||
|
BINKEYEX &pBINK,
|
||||||
DWORD nChannelID,
|
DWORD nChannelID,
|
||||||
DWORD nAuthInfo,
|
DWORD nAuthInfo,
|
||||||
BOOL bUpgrade
|
BOOL bUpgrade
|
||||||
|
@ -414,23 +400,29 @@ BOOL keyServer(
|
||||||
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,
|
|
||||||
BIGNUM *privateKeySel,
|
|
||||||
EC_POINT **genPoint,
|
EC_POINT **genPoint,
|
||||||
EC_POINT **pubPoint
|
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.7",
|
||||||
*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 ◄ 25/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,27 +553,27 @@ 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,
|
||||||
|
|
134
src/xp.cpp
134
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));
|
||||||
// ↑ ↑ ↑
|
// ↑ ↑ ↑
|
||||||
|
@ -296,6 +300,7 @@ VOID generateXPKey(
|
||||||
|
|
||||||
BOOL keyXP(
|
BOOL keyXP(
|
||||||
CHAR (&pKey)[PK_LENGTH + NULL_TERMINATOR],
|
CHAR (&pKey)[PK_LENGTH + NULL_TERMINATOR],
|
||||||
|
BINKEYEX &pBINK,
|
||||||
DWORD nChannelID,
|
DWORD nChannelID,
|
||||||
DWORD nSequence,
|
DWORD nSequence,
|
||||||
BOOL bUpgrade
|
BOOL bUpgrade
|
||||||
|
@ -304,30 +309,49 @@ BOOL keyXP(
|
||||||
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);
|
||||||
}
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
import math
|
||||||
|
|
||||||
|
|
||||||
|
def count_bits(number):
|
||||||
|
return round(math.log2(number)) + 1
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
number = int(input('Input a number: '))
|
||||||
|
print(count_bits(number))
|
||||||
|
|
||||||
|
number *= 2
|
||||||
|
|
||||||
|
number_bytes = int.to_bytes(number, 49, byteorder='big')
|
||||||
|
|
||||||
|
print(f"0x{number_bytes.hex().upper()}")
|
|
@ -0,0 +1,31 @@
|
||||||
|
import math
|
||||||
|
|
||||||
|
|
||||||
|
def count(b):
|
||||||
|
p = 0
|
||||||
|
|
||||||
|
for i in range(25):
|
||||||
|
p += pow(24, 24 - i) * b[i]
|
||||||
|
|
||||||
|
return p
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
charset = "BCDFGHJKMPQRTVWXY2346789"
|
||||||
|
key1 = "JCF8T-2MG8G-Q6BBK-MQKGT-X3GBB"
|
||||||
|
key2 = "FFFFF-GGGGG-HHHHH-JJJJJ-KKKKK"
|
||||||
|
key3 = "99999-99999-99999-99999-99999"
|
||||||
|
|
||||||
|
b = []
|
||||||
|
|
||||||
|
for x in key2:
|
||||||
|
if x != '-':
|
||||||
|
b.append(charset.index(x))
|
||||||
|
|
||||||
|
result = count(b)
|
||||||
|
|
||||||
|
print(f'Byte array: {b}; Length: {len(b)}\n{hex(result).upper()}')
|
||||||
|
data = result.to_bytes(15, byteorder='little')
|
||||||
|
|
||||||
|
hex_string = "".join("%02X " % b for b in data)
|
||||||
|
print(hex_string)
|
Loading…
Reference in New Issue