Open source Windows 7 product key checker

Discussion in 'MDL Projects and Applications' started by Daz, Oct 15, 2009.

  1. urie

    urie Moderator
    Staff Member

    May 21, 2007
    9,039
    3,388
    300
  2. qewlpal

    qewlpal MDL Addicted

    Jun 25, 2010
    575
    2,010
    30
    #182 qewlpal, Aug 18, 2010
    Last edited: Aug 18, 2010
    Thanks for pid checker Daz
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  3. janek2012

    janek2012 MDL Member

    Dec 29, 2008
    214
    994
    10
    #183 janek2012, Oct 23, 2010
    Last edited by a moderator: Apr 20, 2017
    In C++:
    Code:
    // Note that TCHAR map should be set to "wchar_t" or you can change all "WCHAR" instances in code to "wchar_t"
    
    typedef HRESULT (__stdcall *PidGenXFn)
    (
    WCHAR* szProductKey, // Product Key to decode
    WCHAR* szPKeyConfigPath, // Path to "pkeyconfig.xrm-ms"
    WCHAR* szPID, // Microsoft Product ID Family (use "55041")
    void* pUnknown1, // Unknown (use NULL)
    WCHAR* szProductId, // Calculated Product ID ("55041-XXX-XXXXXXX-XXXXX")
    struct DigitalProductId* pDigPid, // Calculated DigitalProductId structure
    struct DigitalProductId4* pDigPid4 // Calculated DigitalProductId4 structure
    );
    
    struct DigitalProductId {
    unsigned int uiSize;
    BYTE bUnknown1[4];
    char szProductId[28];
    char szEditionId[16];
    BYTE bUnknown2[112];
    };
    
    struct DigitalProductId4 {
    unsigned int uiSize;
    BYTE bUnknown1[4];
    WCHAR szAdvancedPid[64];
    WCHAR szActivationId[72];
    WCHAR szEditionType[256];
    BYTE bUnknown2[96];
    WCHAR szEditionId[64];
    WCHAR szKeyType[64];
    WCHAR szEULA[64];
    };
    WCHAR* g_szPKeyConfigPath;
    PidGenXFn g_pPidGenX;
    
    HRESULT __fastcall DecodeKey(String szKey)
    {
    Memo1->Lines->Append("Product Key: " + szKey);
    WCHAR *pkeyconfig;
    WCHAR *lib;
    pkeyconfig = L"pkeyconfig.xrm-ms";
    lib = L"pidgenx.dll";
    // start load
    HMODULE hPidGenX = LoadLibrary(lib);
    if(hPidGenX == NULL)
    {
    Memo1->Lines->Append("Error: Could not load library - file not found?");
    return -1;
    }
    // assuming load succeeded, get the Memo1->Lines->Appendction pointer
    g_pPidGenX = (PidGenXFn)GetProcAddress(hPidGenX, "PidGenX");
    if(g_pPidGenX == NULL)
    {
    Memo1->Lines->Append("Error: Could not load library - wrong file?");
    return -1;
    }
    bool bLastWasComment = false;
    // end load
    
    WCHAR szProductId[24];
    szProductId[0] = L'\0';
    // not really used, as everything is in DigitalProductId4,
    DigitalProductId sDPid;
    sDPid.uiSize = sizeof(DigitalProductId);
    // nearly all the information (apart from Product Id) gets put in this structure
    DigitalProductId4 sDPid4;
    sDPid4.uiSize = sizeof(DigitalProductId4);
    // and finally...
    HRESULT hResult = g_pPidGenX(
    szKey.w_str(), // wchar_t of String with key
    pkeyconfig,  // pkeyconfig file path
    L"XXXXX", // You can put anything here, but in most PID checkers it's "XXXXX"
    NULL, // Unknown (?)
    szProductId,
    &sDPid,
    &sDPid4
    );
    // now interpret the results...
    String szValid;
    switch(hResult)
    {
    case PGX_OK: szValid = "Valid"; break;
    case PGX_INVALIDKEY: szValid = "Invalid"; break;
    case PGX_MALFORMEDKEY: szValid = "Malformed"; break;
    default: szValid = "ERROR"; break;
    }
    Memo1->Lines->Append("Validity: " + szValid); //
    
    if(hResult == PGX_OK)
    {
    Memo1->Lines->Append("Product ID: " + (String)szProductId); // ^^
    Memo1->Lines->Append("AdvID: " + (String)sDPid4.szAdvancedPid);
    Memo1->Lines->Append("Activation ID: " + (String)sDPid4.szActivationId);
    Memo1->Lines->Append("Edition Type: " + (String)sDPid4.szEditionType);
    Memo1->Lines->Append("Edition ID: " + (String)sDPid4.szEditionId);
    Memo1->Lines->Append("Key Type: " + (String)sDPid4.szKeyType);
    Memo1->Lines->Append("EULA: " + (String)sDPid4.szEULA);
    
    // Crypto ID - this is the id of the public key used
    WCHAR szCryptoId[4];
    szCryptoId[0] = L'\0';
    swscanf_s(sDPid4.szAdvancedPid, L"XXXXX-00%3s-%*3s-%*6s-%*2s-%*4s-%*9s-%*7s", szCryptoId, 4);
    Memo1->Lines->Append()"Crypto ID: " + (String)szCryptoId);
    }
    //unload library
    FreeLibrary(hPidGenX);
    return hResult;
    }
    Usage:
    Code:
    String key = Edit1->Text; // where "Edit1->Text" is the key in unicode
    DecodeKey(key); // Show the magic
    // End of the magic
    
    You should change "Memo1->Lines->Append" to your function which will print results on output :)

    Also, remember to change TCHAR map in compiler to wchar_t.
     
  4. janek2012

    janek2012 MDL Member

    Dec 29, 2008
    214
    994
    10
    #184 janek2012, Sep 19, 2011
    Last edited by a moderator: Apr 20, 2017
    Sorry for the new post but I think it is major update for you.

    I have reflected VAMT 2.0 and updated the DigitalProductId3 and DigitalProductId4 structures as follows:

    Code:
    struct DigitalProductId {
        unsigned int uiSize;
        unsigned short MajorVersion;
        unsigned short MinorVersion;
        char szProductId[24];
        unsigned int uiKeyIdx;
        char szEditionId[16];
        BYTE bCdKey[16];
        unsigned int uiCloneStatus;
        unsigned int uiTime;
        unsigned int uiRandom;
        unsigned int uiLt;
        unsigned int uiLicenseData[2];
        char sOemId[8];
        unsigned int uiBundleId;
        char sHardwareIdStatic[8];
        unsigned int uiHardwareIdTypeStatic;
        unsigned int uiBiosChecksumStatic;
        unsigned int uiVolSerStatic;
        unsigned int uiTotalRamStatic;
        unsigned int uiVideoBiosChecksumStatic;
        char sHardwareIdDynamic[8];
        unsigned int uiHardwareIdTypeDynamic;
        unsigned int uiBiosChecksumDynamic;
        unsigned int uiVolSerDynamic;
        unsigned int uiTotalRamDynamic;
        unsigned int uiVideoBiosChecksumDynamic;
        unsigned int uiCRC32;
    
    };
    
    
    struct DigitalProductId4 {
        unsigned int uiSize;
        unsigned short MajorVersion;
        unsigned short MinorVersion;
        WCHAR szAdvancedPid[64];
        WCHAR szActivationId[64];
        WCHAR szOemID[8];
        WCHAR szEditionType[260];
        BYTE bIsUpgrade;
        BYTE bReserved[7];
        BYTE bCDKey[16];
        BYTE bCDKey256Hash[32];
        BYTE b256Hash[32];
        WCHAR szEditionId[64];
        WCHAR szKeyType[64];
        WCHAR szEULA[64];
    };
    Now all the bytes of these structures are known but some of them are always just NULL so they are not that important.
    I hope you like it

    What is more, PidgenX's 4th argument is known now:
    Code:
    int PidGenX(string productKey, string configFile, string mpc, string oemId, [Out] DigitalProductId2 productId2, [In, Out] DigitalProductId3 productId3, [In, Out] DigitalProductId4 productId4);
    where DigitalProductId2 is just a structure of one String so can be simply replaced with String.
     
  5. ChouseCall

    ChouseCall MDL Novice

    Dec 30, 2011
    1
    1
    0
  6. Daz

    Daz MDL Developer / Admin
    Staff Member

    Jul 31, 2009
    9,534
    67,254
    300
    Thanks for sharing :)

    When I originally created this thread there were key checkers, although none of them were open source and most of the code floating around was either messy or incomplete. It's been great to see others posting their version of the code and the applications that have been developed in the process.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  7. FreeStyler

    FreeStyler MDL Guru

    Jun 23, 2007
    3,557
    3,832
    120
  8. Daz

    Daz MDL Developer / Admin
    Staff Member

    Jul 31, 2009
    9,534
    67,254
    300
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  9. woot332

    woot332 MDL Senior Member

    Feb 18, 2011
    390
    815
    10
    @FreeStyler Basically you set "magicbyte" nr 42h in the buffer that return DigitalProductId,
    loop decode and append N char if "magicbyte" is set.
     
  10. FreeStyler

    FreeStyler MDL Guru

    Jun 23, 2007
    3,557
    3,832
    120
  11. CODYQX4

    CODYQX4 MDL Developer

    Sep 4, 2009
    4,813
    45,775
    150
    #192 CODYQX4, Apr 25, 2012
    Last edited: Apr 12, 2019
    .
     
  12. FreeStyler

    FreeStyler MDL Guru

    Jun 23, 2007
    3,557
    3,832
    120
  13. janek2012

    janek2012 MDL Member

    Dec 29, 2008
    214
    994
    10
    #194 janek2012, Apr 25, 2012
    Last edited by a moderator: Apr 20, 2017
    My code is way more complicated but this is the most important thing I changed after Windows 8 CP release:
    Code:
    String prefix = StringReplace(Form5->XMLDocument1->DocumentElement->ChildNodes->First()->GetNodeName(), "Configurations", "", TReplaceFlags() << rfReplaceAll << rfIgnoreCase);
    
     //where `Form5->XMLDocument1->DocumentElement->ChildNodes->First()->GetNodeName()` is "pkc:Configurations" or "Configurations"
    
    String configurations = prefix + "Configurations";
    String actconfigid = prefix + "ActConfigId";
    String editionid = prefix + "EditionId";
    String productdescription = prefix + "ProductDescription";
    Note that this is C++ VCL code.

    The idea is simple:
    Let's make a string named prefix. The prefix is everything that stays before "Configurations", "ActConfigId", etc. To check which prefix you should use, open the first node (named for ex. "pkc:Configurations") and assign to prefix its name with replaced "Configurations" with empty string -> prefix == "pkc:" for win7 or "" for win8.
    Use prefix+your_node_name to open next XML nodes.
    I hope you understand what I mean :)
     
  14. user_hidden

    user_hidden MDL Expert

    Dec 18, 2007
    1,034
    1,061
    60
    Freestyler,

    in my pidchecker i found that when using the build 8250 xrm-ms along with pidgenx.dll from that build i get the error.
    if using the pidgenx.dll from build 8102 with the Win8CP xrm-ms there is no error.
     
  15. FreeStyler

    FreeStyler MDL Guru

    Jun 23, 2007
    3,557
    3,832
    120
  16. FreeStyler

    FreeStyler MDL Guru

    Jun 23, 2007
    3,557
    3,832
    120
  17. janek2012

    janek2012 MDL Member

    Dec 29, 2008
    214
    994
    10
    #199 janek2012, Apr 28, 2012
    Last edited: Apr 28, 2012
    I think we should create a single post with all the informations needed for coders - reading the whole topic may be a bit difficult, dont you think? :p

    @FreeStyler, yep, I have done it just after the Windows 8 CP release :)
     
  18. CODYQX4

    CODYQX4 MDL Developer

    Sep 4, 2009
    4,813
    45,775
    150
    #200 CODYQX4, Apr 28, 2012
    Last edited: Apr 12, 2019
    .