?? main.c
字號:
/*
* XPDec I - Decrypt the XP RC1 Installation ID
*
* Copyright (C) 2001 Fully Licensed GmbH (www.licenturion.com)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. This software may not be used in applications that aim at subverting
* the XP license enforcement mechanism.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This product includes software written by the OpenSSL project for use in
* the OpenSSL toolkit. (http://www.OpenSSL.org/)
*
* Copyright (C) 1999 the OpenSSL project.
* All rights reserved.
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com).
*
* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*/
#include <stdio.h>
#include <string.h>
#include "openssl/md5.h"
#include "openssl/sha.h"
unsigned int CheckDigit(unsigned int Val)
{
unsigned int Sum, Copy;
Sum = 0;
Copy = Val;
while (Copy != 0)
{
Sum += Copy % 10;
Copy /= 10;
}
return Val * 10 + 7 - (Sum % 7);
}
void ShowProdKey(unsigned char *ProdKey)
{
unsigned int Val1, Val2;
Val1 = *(unsigned int *)ProdKey;
Val1 &= 0x7fffffff;
Val1 >>= 1;
Val2 = CheckDigit(Val1 % 1000000);
Val1 /= 1000000;
printf("Your product ID should be XXXXX-%.3u-%.7u-XXXXX.\n", Val1, Val2);
}
int ValidateProdKey(unsigned char *BinProdKey, int Len)
{
fprintf(stderr, "Note: Product key validation is not implemented.\n");
return 0;
}
int DecodeProdKey(char *ProdKey, unsigned char *Result, int ResLen)
{
static char *ValidDigits = "BCDFGHJKMPQRTVWXY2346789";
int i, k, m, Groups;
int Aux, NumDigits;
if (strlen(ProdKey) != 29)
fprintf(stderr, "Warning: Product key has non-standard length.\n");
if (strlen(ProdKey) % 6 < 1)
{
fprintf(stderr, "Product key has invalid length.\n");
return -1;
}
memset(Result, 0, ResLen);
NumDigits = strlen(ValidDigits);
Groups = (strlen(ProdKey) + 5) / 6;
for (i = 0; i < Groups * 6; i += 6)
{
for (k = 0; k < 5 && ProdKey[i + k] != 0; k++)
{
if (ProdKey[i + k] >= 'a' && ProdKey[i + k] <= 'z')
ProdKey[i + k] -= 32;
for (m = 0; ValidDigits[m] != 0; m++)
if (ProdKey[i + k] == ValidDigits[m])
break;
if (ValidDigits[m] == 0)
{
fprintf(stderr, "Invalid character in group '");
for (k = 0; k < 5 && ProdKey[i + k] != 0; k++)
fprintf(stderr, "%c", ProdKey[i + k]);
fprintf(stderr, "'.\n");
return -1;
}
Aux = m;
m = 0;
do
{
Aux += Result[m] * NumDigits;
Result[m++] = (unsigned char)(Aux & 255);
Aux >>= 8;
}
while (m < ResLen);
}
if (ProdKey[i + k] != '-' && ProdKey[i + k] != 0)
{
fprintf(stderr, "Expected '-' character after group '");
for (k = 0; k < 5 && ProdKey[i + k] != 0; k++)
fprintf(stderr, "%c", ProdKey[i + k]);
fprintf(stderr, "'.\n");
return -1;
}
}
return 0;
}
unsigned int StringHash(char *String, int Num, int Off, int Step)
{
MD5_CTX Context;
unsigned char Digest[16];
unsigned int Result;
int i, Bit;
MD5_Init(&Context);
MD5_Update(&Context, String, strlen(String));
MD5_Final(Digest, &Context);
Result = 0;
Bit = Off;
for (i = 0; i < Num; i++)
{
Result <<= 1;
if ((Digest[Bit >> 3] & (1 << (~Bit & 7))) != 0)
Result |= 1;
Bit += Step;
}
return Result % ((1 << Num) - 1) + 1;
}
int ShowDiskIDHash(char *DiskID)
{
int i;
if (strlen(DiskID) != 9 || DiskID[4] != '-')
{
fprintf(stderr, "Required volume serial number format is XXXX-XXXX.\n");
return -1;
}
for (i = 0; DiskID[i] != 0; i++)
{
if (i == 4)
continue;
if (DiskID[i] >= 'a' && DiskID[i] <= 'f')
DiskID[i] -= 32;
if (DiskID[i] >= 'A' && DiskID[i] <= 'F')
continue;
if (DiskID[i] >= '0' && DiskID[i] <= '9')
continue;
break;
}
if (i != 9)
{
fprintf(stderr, "Invalid hex digit in serial number %s: '%c'.\n",
DiskID, DiskID[i]);
return -1;
}
printf("Hash of volume serial number %s is 0x%.3X.\n",
DiskID, StringHash(DiskID, 10, 3, 1));
return 0;
}
int ShowMACAddrHash(char *MACAddr)
{
int i, Nibble, Digit;
unsigned char BinMACAddr[6];
char ASCII[13];
if (strlen(MACAddr) != 17 || MACAddr[2] != '-' ||
MACAddr[5] != '-' || MACAddr[8] != '-' || MACAddr[11] != '-' ||
MACAddr[14] != '-')
{
fprintf(stderr, "Required MAC address format is XX-XX-XX-XX-XX-XX.\n");
return -1;
}
Nibble = 0;
memset(BinMACAddr, 0, 6);
for (i = 0; MACAddr[i] != 0; i++)
{
if (i % 3 == 2)
continue;
Digit = -1;
if (MACAddr[i] >= 'a' && MACAddr[i] <= 'f')
Digit = MACAddr[i] - 'a' + 10;
if (MACAddr[i] >= 'A' && MACAddr[i] <= 'F')
Digit = MACAddr[i] - 'A' + 10;
if (MACAddr[i] >= '0' && MACAddr[i] <= '9')
Digit = MACAddr[i] - '0';
if (Digit < 0)
{
fprintf(stderr, "Invalid hex digit in MAC address %s: '%c'.\n",
MACAddr, MACAddr[i]);
return -1;
}
if ((Nibble & 1) == 0)
Digit <<= 4;
BinMACAddr[Nibble >> 1] |= Digit;
Nibble++;
}
sprintf(ASCII, "%.2X%.2X%.2X%.2X%.2X%.2X",
BinMACAddr[0], BinMACAddr[1], BinMACAddr[2],
BinMACAddr[3], BinMACAddr[4], BinMACAddr[5]);
printf("Hash of MAC address %s is 0x%.3X\n",
MACAddr, StringHash(ASCII, 10, 1, 1));
return 0;
}
void KeyedHash(unsigned char *Data, unsigned char *Result)
{
SHA_CTX Context;
unsigned char Digest[20];
static unsigned char Key[4] =
{
#error The key has been removed from the source code. Please obtain the executable.
};
SHA1_Init(&Context);
SHA1_Update(&Context, Data, 8);
SHA1_Update(&Context, Key, 4);
SHA1_Final(Digest, &Context);
memcpy(Result, Digest, 8);
}
void DecryptInstID(unsigned char *InstID)
{
unsigned char *Left, *Right;
unsigned char Aux[8];
int i, k;
Left = InstID;
Right = InstID + 8;
for (i = 0; i < 4; i++)
{
KeyedHash(Left, Aux);
for (k = 0; k < 8; k++)
Aux[k] ^= Right[k];
memcpy(Right, Left, 8);
memcpy(Left, Aux, 8);
}
}
int DecodeInstID(char *InstID, unsigned char *Result, int ResLen)
{
int i, k, m, Groups;
int Sum, Digit, Aux;
if (strlen(InstID) != 58)
fprintf(stderr, "Warning: Installation ID has non-standard length.\n");
if (strlen(InstID) % 7 < 2)
{
fprintf(stderr, "Installation ID has invalid length.\n");
return -1;
}
memset(Result, 0, ResLen);
Groups = (strlen(InstID) + 6) / 7;
for (i = 0; i < Groups * 7; i += 7)
{
Sum = 0;
for (k = 0; k < 5 && InstID[i + k + 1] != 0; k++)
{
Digit = InstID[i + k] - '0';
if (Digit < 0 || Digit > 9)
{
fprintf(stderr, "Invalid digit in group '");
for (k = 0; k < 6 && InstID[i + k] != 0; k++)
fprintf(stderr, "%c", InstID[i + k]);
fprintf(stderr, "'.\n");
return -1;
}
Aux = Digit;
m = 0;
do
{
Aux += Result[m] * 10;
Result[m++] = (unsigned char)(Aux & 255);
Aux >>= 8;
}
while (m < ResLen);
if ((k & 1) != 0)
Digit *= 2;
Sum += Digit;
}
Digit = InstID[i + k++] - '0';
if (Digit != Sum % 7)
{
fprintf(stderr, "Invalid check digit in group '");
for (k = 0; k < 6 && InstID[i + k] != 0; k++)
fprintf(stderr, "%c", InstID[i + k]);
fprintf(stderr, "'.\n");
return -1;
}
if (InstID[i + k] != '-' && InstID[i + k] != 0)
{
fprintf(stderr, "Expected '-' character after group '");
for (k = 0; k < 6 && InstID[i + k] != 0; k++)
fprintf(stderr, "%c", InstID[i + k]);
fprintf(stderr, "'.\n");
return -1;
}
}
return 0;
}
int ShowProductID(unsigned char *InstID)
{
unsigned int Word1, Word2;
unsigned int Val1, Val2, Val3, Val4;
Word1 = *(unsigned long *)(InstID + 8);
Word2 = *(unsigned long *)(InstID + 12);
Val1 = Word1 & 0x1ffff;
Val2 = (Word1 >> 17) & 0x3ff;
Val3 = (Word1 >> 27) & 0x1f;
Val3 |= (Word2 & 0x7fffff) << 5;
Val3 &= 0x7ffffff;
Val4 = (Word2 >> 23) & 0x1ff;
Val4 |= InstID[16] << 9;
if (Val1 > 99999 || Val2 > 999 || Val3 > 9999999 || Val4 > 99999)
{
fprintf(stderr, "Invalid product ID.\n");
return -1;
}
printf("The transmitted product ID is %u-%.3u-%.7u-%.5u.\n", Val1, Val2, Val3, Val4);
return 0;
}
void ShowHardwareID(unsigned char *InstID)
{
unsigned int Word1, Word2, Hash;
static char *MemTable[7] =
{
"less than 32 MB",
"between 32 MB and 63 MB",
"between 64 MB and 127 MB",
"between 128 MB and 255 MB",
"between 256 MB and 511 MB",
"between 512 MB and 1023 MB",
"more than 1023 MB"
};
Word1 = *(unsigned long *)InstID;
Word2 = *(unsigned long *)(InstID + 4);
printf("Your hardware information is summarized in this table. A zero value\n");
printf("indicates that the respective field is not in use.\n\n");
printf(" Derived from Bits Range Value\n");
printf(" ------------------------------------------------------------\n");
Hash = (Word2 >> 25) & 0x7;
printf(" Processor model string 3 0x0 - 0x7 0x%.1X\n", Hash);
Hash = (Word2 >> 3) & 0x3f;
printf(" Processor serial number string 6 0x00 - 0x3F 0x%.2X\n", Hash);
Hash = (Word2 >> 28) & 0x7;
printf(" Memory 3 0x0 - 0x7 0x%.1X\n", Hash);
Hash = (Word1 >> 10) & 0x3ff;
printf(" MAC address string 10 0x000 - 0x3FF 0x%.3X\n", Hash);
Hash = (Word2 >> 16) & 0x1f;
printf(" SCSI host adapter ID string 5 0x00 - 0x1F 0x%.2X\n", Hash);
Hash = (Word2 >> 21) & 0xf;
printf(" IDE controller ID string 4 0x0 - 0xF 0x%.1X\n", Hash);
Hash = (Word2 >> 9) & 0x7f;
printf(" Harddrive ID string 7 0x00 - 0x7F 0x%.2X\n", Hash);
Hash = (Word1 >> 20) & 0x7f;
printf(" CD-ROM drive ID string 7 0x00 - 0x7F 0x%.2X\n", Hash);
Hash = Word1 & 0x3ff;
printf(" Volume serial number string 10 0x000 - 0x3FF 0x%.3X\n", Hash);
Hash = (Word1 >> 27) & 0x1f;
printf(" Graphics Adapter ID string 5 0x00 - 0x1F 0x%.2X\n", Hash);
Hash = (Word2 >> 31) & 0x1;
printf(" Dockable 1 0x0 - 0x1 0x%.1X\n", Hash);
Hash = Word2 & 0x7;
printf(" Unused (should be 0x1) 3 0x0 - 0x7 0x%.1X\n", Hash);
printf(" ------------------------------------------------------------\n\n");
Hash = (Word2 >> 28) & 0x7;
if (Hash != 0)
printf("Memory = 0x%x => Windows XP uses %s of RAM.\n",
Hash, MemTable[Hash - 1]);
}
void Usage(void)
{
fprintf(stderr, "Usage: xpdec -i Installation-ID\n");
fprintf(stderr, " xpdec -p Product-Key\n");
fprintf(stderr, " xpdec -v Volume-Serial-Number\n");
fprintf(stderr, " xpdec -m MAC-Address\n");
}
int main(int ac, char *av[])
{
unsigned char InstID[17], ProdKey[15];
printf(">>>\n");
printf(">>> XPDec I - Decrypt the XP RC1 Installation ID\n");
printf(">>>\n");
printf(">>> Copyright (C) 2001 Fully Licensed GmbH (www.licenturion.com)\n");
printf(">>> All rights reserved.\n");
printf(">>>\n");
printf(">>> This product includes software written by the OpenSSL project\n");
printf(">>> for use in the OpenSSL toolkit. (http://www.OpenSSL.org/)\n");
printf(">>>\n");
printf(">>> Copyright (C) 1999 the OpenSSL project. All rights reserved.\n");
printf(">>>\n");
printf(">>> This product includes cryptographic software written by\n");
printf(">>> Eric Young (eay@cryptsoft.com).\n");
printf(">>>\n");
printf(">>> Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)\n");
printf(">>> All rights reserved.\n");
printf(">>>\n\n");
if (ac != 3)
{
Usage();
return 1;
}
if (!strcmp(av[1], "-i"))
{
if (DecodeInstID(av[2], InstID, 17) < 0)
return 1;
DecryptInstID(InstID);
if (ShowProductID(InstID) < 0)
return 1;
printf("\n");
ShowHardwareID(InstID);
}
else if (!strcmp(av[1], "-p"))
{
if (DecodeProdKey(av[2], ProdKey, 15) < 0)
return 1;
if (ValidateProdKey(ProdKey, 15) < 0)
return 1;
ShowProdKey(ProdKey);
}
else if (!strcmp(av[1], "-v"))
{
if (ShowDiskIDHash(av[2]) < 0)
return 1;
}
else if (!strcmp(av[1], "-m"))
{
if (ShowMACAddrHash(av[2]) < 0)
return 1;
}
else
{
Usage();
return 1;
}
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -