Is there any way to crack/decrypt the WinXP CONSUMER activation system to generate Activation IDs?

Discussion in 'Windows XP / Older OS' started by ENZOLU, Aug 20, 2019.

  1. daniel_k

    daniel_k MDL Member

    Jan 21, 2019
    176
    370
    10
    Because it would be a major breakthrough.

    Crack/hack when you can't keygen it.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  2. NT Five

    NT Five MDL Novice

    Dec 8, 2014
    9
    1
    0
    You can use the hacked winlogon.exe from MicroXP 0.82.
    It allows you to get rid of the oembios.bin file in your system32 folder.
    I suppose it doesn't do any license checks.

    I've been using that for many years on all my machines.
    Zero problems.

    XP Embedded's minlogon.exe will probably work as well.

    I found my copy of the cracked pidgen.dll many years ago somewhere on the internet.
     
  3. NT Five

    NT Five MDL Novice

    Dec 8, 2014
    9
    1
    0
    The binaries in the download link I posted are identical to the ones on the machine I use to type this message.
    The hacked winlogon.exe is for the US version of Windows XP Pro so some dialog boxes and text will be in the English language.

    If that bothers you it's possible to use resource hacker to replace the text strings with the equivalent strings taken from your localized winlogon.exe file.
    In the past I've done just that in order to use it with my French language XP installations.

    Over the last 8 years I've created at least 50 XP ISO's by replacing the original files with the hacked versions.
    I've never encountered any problems.
    With the hacked files I can run XP both in classic mode or with the welcome screen.

    If you are using XP Home, Tablet or MCE it might not work. Maybe these versions use slightly different binaries and it might cause XP to switch to classic mode.

    What I like about this method is the fact that I don't have to install stuff like AntiWPA (used that before discovering my current method).
    If I remember correctly, AntiWPA and similar methods write a bunch of registry entries and need to run when you are logged in to make XP believe that it is running in fail safe mode, so it won't do any license checks.
    That method works fine, but it's a kludge.

    Just replacing original files on your ISO with hacked ones is more elegant.
    No additional software needs to run in the background and nothing needs to be installed.
    Works on all my machines for 8+ years.

    You don't need the hacked pidgen.dll in order to disable activation.
    The hacked file just allows you to use any random letter combination when XP asks for the license key during installation.
     
  4. WindowsMyStyle

    WindowsMyStyle MDL Member

    May 2, 2018
    174
    66
    10
    this is the complete script that AntiWAT uses:

    Code:
    copy /y "%PA%\freewat.dll" %sys%\freewat.dll
    regsvr32 /s %sys%\freewat.dll
    REG DELETE "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify\WgaLogon" /f 1>nul 2>nul
    REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WPAEvents" /f 1>nul 2>nul
    REG RESTORE "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WPAEvents" "%~dp0OOBE.hiv" 1>nul 2>nul
    REG QUERY "HKLM\Software\Microsoft\Windows NT\CurrentVersion" /v ProductName | findstr "XP" > nul
    IF NOT ERRORLEVEL 1 regedit /s "%~dp0xpgen.reg"
    setupapi,InstallHinfSection DEL_OOBE_ACTIVATE 132 syssetup.inf
    attrib %hosts% -h -s -r
    tskill wgatray.exe 1>nul 2>nul
    move "%sys%\WgaTray.exe" WgaTray.bak 1>nul 2>nul
    move "%sys%\wgalogon.dll" wgalogon.bak 1>nul 2>nul
    findstr /I mpa.one %hosts% >nul
    IF NOT ERRORLEVEL 1 GOTO skip
    echo. >> %hosts%
    echo 0.0.0.0 mpa.one.microsoft.com genuine.microsoft.com sls.microsoft.com >> %hosts%
    ipconfig /flushdns
    net stop dnscache
    net start dnscache
    :skip
    
    as you can see it only deletes and modifies two registry keys and modifies the two files that do the WGA control
    It is very easy to start as RunOnceEx when you first start Windows XP and works with all versions ...
    Unfortunately for almost all people in the forums there is only the Professional ... but many also use the other versions and this activates them all in a second.
     
  5. pottzman

    pottzman MDL Member

    Dec 8, 2009
    143
    105
    10
    not to be picky here but if you look at what this reg file contains you will find that it edits the ProductID of windows ("ProductId"="69831-640-1780577-45389").

    This ProductID would only be valid for Windows XP VLK being a "640" PID.

    I much prefer just "hardening" the "WPAEvents" registry setting so that the SYSTEM cannot access it anymore. :) No hacked files.....No extra freewat.dll files that autorun etc.

    open Registry Editor (Start->Run then enter regedit and push OK button)
    open the registry key at the location HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/WPAEvents
    delete the WPALastevent value
    edit the OOBETimer key value and set its value to "ff d5 71 d6 8b 6a 8d 6f d5 33 93 fd"
    right-click on the same key WPAEvents and select "Permissions". select SYSTEM group/user and check all DENY options (we won't allow XP to mess with us anymore, in fact we deny it firmly :eek:)
    click Advanced button then uncheck "Inherit from parent the permission...", press OK, when prompted at next step just answer with "Remove"
    click okay to return to WPAEvents properties and select "Permissions". Thers should just be only 1 SYSTEM entry now and it should have Deny for all options. Now just add "Administrators" to the list of users and click Allow for all.

    then I just save the WPAEvents key as a Registry hive ( not a reg. file) file this way it has all the permissions we just set.

    then I just use "RunOnceEx" to execute a few commands:

    REG DELETE "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify\WgaLogon" /f 1>nul 2>nul
    REG DELETE "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WPAEvents" /f 1>nul 2>nul
    REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WPAEvents" /f 1>nul 2>nul
    REG RESTORE "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WPAEvents" "%~dp0WPAEvents.hiv" 1>nul 2>nul

    rundll32 setupapi,InstallHinfSection DEL_OOBE_ACTIVATE 132 syssetup.inf

    and its done. works with 32 bit, 64 bit, XP, 2k3
     
  6. WindowsMyStyle

    WindowsMyStyle MDL Member

    May 2, 2018
    174
    66
    10
    nice ... then you try it and find that it only works with Windows XP Pro
    10 year old method ... there are dozens of videos where they keep saying it works with all versions of XP ... but it's all FALSE !!!
    Try this method with Windows XP Home, Tablet, MCE ... and then tell me if it works!
    To conclude with 64bit and all Windows Server 2003 no activation is needed ... just use the VL versions, they are all already active!
     
  7. pottzman

    pottzman MDL Member

    Dec 8, 2009
    143
    105
    10
    maybe you didn't do it properly, I've done it many times xp pro, xp home, media center tablet retail oem x64 they all work fine.
     
  8. WindowsMyStyle

    WindowsMyStyle MDL Member

    May 2, 2018
    174
    66
    10
    if I didn't, nobody should work
    instead with your Windows Xp Pro method it works perfectly ... home, tablet, mce ... they don't work!
    if you can try it and see ...
     
  9. pottzman

    pottzman MDL Member

    Dec 8, 2009
    143
    105
    10
    I can't understand what you are saying. it doesn't really make sense
     
  10. pottzman

    pottzman MDL Member

    Dec 8, 2009
    143
    105
    10
    okay you are right. i never used my virtual machine for longer than that before deleting it.

    REG DELETE "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify\WgaLogon" /f 1>nul 2>nul <----- I guess is to delete the registry key for the "Windows Genuine Advantage Notification" update. the AntiWAT tool also has it. I just dont also delete the wgalogon files because i was using it on a clean install.
     
  11. sk00ter

    sk00ter MDL Novice

    Apr 30, 2017
    25
    33
    0
    For the sake of all the people trying to play along at home:

    I recently looked into dpcdll.dll on XP RTM. It exports three functions, none of which have a name. I don't know where they get called, if anywhere.
    As it turns out, this is mostly interesting from a WPA cross-validation standpoint, but it's not useful for confirmation IDs. If anybody knows if symbols for licdll.dll ever were published somewhere, that'd be much more interesting.

    Function ID 122 has the following signature:
    Code:
    enum LicenseType : DWORD {
      LT_RETAIL,
      LT_UPGRADE,
      LT_OEM,
      LT_VOL, // volume license (previously? MS Select)
      LT_UNK0, // no idea
      LT_UNK1, // no idea
      LT_MSDN
    };
    struct Lic {
      DWORD dwIndex; // index into the license index
      DWORD dwIndex2; // same as dwIndex
      DWORD dwBinkId; // ID of the relevant BINK entry
      DWORD dwMinSiteId; // minimum channel/site ID
      DWORD dwMaxSiteId; // maximum channel/site ID
      LicenseType dwLicenseType; // type of license
      DWORD dwDaysToActivate; // time to activate before OS stops working, 0x7fffffff for no activation needed
      DWORD dwTrialDays; // time for a trial installation before it disables itself
      DWORD dwSignatureLength; // signature? length in bytes
      CONST BYTE *pabSignature; // signature? Not entirely sure since I haven't been able to find the public key and what this is actually signing, but going by the length, it's probably a RSA-1024 signature
    };
    HRESULT WINAPI DPCDLL122Func(DWORD dwBinkId, DWORD dwSiteId, DWORD dwBuildId, struct Lic *pLic);
    
    DPCDLL122Func() looks up a struct Lic in dpcdll.dll's list of license structs for a given build ID (e.g. 2600 for Windows XP RTM). This varies between individual disks.
    Return values:
    0: success
    0x80004003: pLic == NULL
    0x80070002: no match for the tuple (dwBinkId, dwSiteId, dwBuildId), which would suggest a forged/badly generated product key
    0x8007000e: could not allocate memory for the pabSignature in the output pLic (HeapAlloc returned NULL)

    Function ID 123 has the following signature:
    Code:
    // I'll skip the lengthy definition of DigitalProductId3, which is already well-known
    
    DWORD WINAPI DPCDLL123Func(CONST DigitalProductId3 *digitalProductId3);
    
    DPCDLL123Func() validates a DigitalProductId3 struct (such as the one at HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion). dpcdll.dll contains copies of all relevant BINKs for product key validation separate from pidgen.dll.
    Return values:
    0: success
    1: CRC mismatch
    2: impossible (invalid arguments to internal crypto library call with hardcoded argument)
    3: unknown, related to the internal BINKs
    4 and 6: bad signature on product key/internal crypto library error
    5: BINK has unexpected size

    DPCDLL125Func() is essentially PIDGenW() that checks against all BINKs stored in dpcdll.dll and returns 0 if any BINK matched for the given product key or the internal, non-zero PIDGen error code otherwise.
     
  12. diamondggg

    diamondggg MDL Novice

    Sep 30, 2016
    23
    72
    0
    Original symbols packages from MS include licdll.pdb. They are not available on MS site anymore, but WaybackMachine still keeps them: web.archive.org/web/20170710140215/ http: //msdl.microsoft.com/download/symbols/packages/windowsxp/windowsxp.x86.fre.rtm.symbols.exe . Also, the checker part is present inside winlogon.exe as well, symbols for winlogon.exe can be found in the same package.

    However, most interesting parts are stripped from those symbols (unless you're mostly interested in the details of bignum implementation), so don't put too much hope in them.

    The key has not changed, it is just obfuscated. Extra digits have appeared in SP1 (I think), they encode 12 bits from SHA1(full product key), so that the phone activator could protect against keygenned values. Extra bits are not actually used by the checker.

    Last digit of every block is the control digit (c0 + c1*2 + c2 + c3*2 + c4) % 7. The rule is the same for Installation and Confirmation IDs.

    Nope. They have devised an entirely different scheme that is NOT cryptographically secure. (Still, a specialist in number theory would come handy to break this.) It is based on a hyperelliptic curve of genus 2.

    In SageMath, the checking algorithm for phone verification is as follows:
    Code:
    import hashlib
    
    # 226512-274743-842923-777124-961370-722240-570042-517722-757426
    installationId = 226512747484292777129613772224570045177275742
    installationIdSize = 19 # 17 for XP Gold, 19 for SP1+ (includes 12 bits of sha1(product key))
    # all three of following are valid generated
    # 013705-060122-603141-961392-086136-909901-494476
    confirmationId = 01370060126031496139086139099049447
    # 022032-220754-159721-909624-985141-504586-914001
    #confirmationId = 02203220751597290962985145045891400
    # 137616-847280-708585-827476-874935-313366-790880
    #confirmationId = 13761847287085882747874933133679088
    
    def decrypt(encrypted, key):
        size_half = len(encrypted) // 2
        size_half_dwords = size_half - (size_half % 4)
        last = encrypted[size_half*2:]
        encrypted = encrypted[:size_half*2]
        for i in range(4):
            first = encrypted[:size_half]
            second = encrypted[size_half:]
            sha1_result = hashlib.sha1(first + key).digest()
            sha1_result = (sha1_result[:size_half_dwords] +
                           sha1_result[size_half_dwords+4-(size_half%4) : size_half+4-(size_half%4)])
            encrypted = bytes(x^^y for x,y in zip(second, sha1_result)) + first
        return encrypted + last
    
    # unpack&decrypt installationId
    iid = int(installationId).to_bytes(installationIdSize, byteorder='little')
    iid = decrypt(iid, b'\x6A\xC8\x5E\xD4')
    hwid = iid[:8]
    productid = int.from_bytes(iid[8:17], byteorder='little')
    productkeyhash = iid[17:]
    pid1 = productid & ((1 << 17) - 1)
    pid2 = (productid >> 17) & ((1 << 10) - 1)
    pid3 = (productid >> 27) & ((1 << 25) - 1)
    version = (productid >> 52) & 7
    pid4 = productid >> 55
    
    assert version == (4 if len(iid) == 17 else 5)
    
    key = hwid + int((pid1 << 41 | pid2 << 58 | pid3 << 17 | pid4) & ((1 << 64) - 1)).to_bytes(8, byteorder='little')
    # productkeyhash is not used for validation, it exists just to allow the activation server to reject keygenned pids
    
    # now the math
    
    p = 0x16A6B036D7F2A79
    Fp = GF(p)
    Fpx.<x> = Fp[]
    E = HyperellipticCurve(x^5+0x1400606322B3B04*x^4+0x1400606322B3B04*x^3+0x44197B83892AD0*x^2+0x21840136C85381*x)
    J = E.jacobian()
    
    # deserialize divisor
    x1 = confirmationId // (p + 1)
    x2 = confirmationId % (p + 1)
    if x1 <= p:
        # two or less points over GF(p)
        point1 = E.lift_x(Fp(-x1)) if x1 != p else None
        point2 = E.lift_x(Fp(-x2)) if x2 != p else None
        if point1 is not None and point2 is not None:
            # there are 4 variants of how lift_x() could select both y-s
            # we don't distinguish D and -D, but this still leaves 2 variants
            # the chosen one is encoded by order of x1 <=> x2
            lastbit1 = point1[1].lift() & 1
            lastbit2 = point2[1].lift() & 1
            if x2 < x1:
                if lastbit1 == lastbit2:
                    point2 = E(point2[0], -point2[1])
            else:
                if lastbit1 != lastbit2:
                    point2 = E(point2[0], -point2[1])
        point1 = J(point1) if point1 is not None else J(0)
        point2 = J(point2) if point2 is not None else J(0)
        divisor = point1 + point2
    else:
        # a pair of conjugate points over GF(p^2)
        f = (x+x2)*(x+x2)-43*x1*x1 # 43 is the minimal quadratic non-residue in Fp
        Fp2 = GF(p^2)
        point1 = E.lift_x(f.roots(Fp2)[0][0])
        point2 = E(Fp2)(point1[0].conjugate(), point1[1].conjugate())
        divisor = J(Fp2)(point1) + J(Fp2)(point2)
        divisor = J(Fpx(divisor[0]), Fpx(divisor[1])) #return from Fp2 to Fp
    
    d2 = divisor * 0x10001
    assert d2[0].degree() == 2
    x1 = d2[0][1]/2
    x2 = sqrt((x1*x1-d2[0][0])/43)
    
    encrypted = x1.lift() + (x2.lift() - 1) * p
    encrypted = int(encrypted).to_bytes(14,byteorder='little')
    
    # end of the math
    decrypted = decrypt(encrypted, key)
    print(decrypted.hex())
    # 0000000000000001000000000000 for the first confirmationId
    # 0000000000000002000000000000 for the second confirmationId
    # 0000000000000006000000000000 for the last confirmationId
    assert decrypted[8:] == b'\0' * 6
    assert decrypted[7] <= 0x80
    # all zeroes in decrypted[0:7] are okay for the checker
    # more precisely: if decrypted[6] == 0, first 6 bytes can be anything
    # otherwise, decrypted[0] = length, and decrypted[1:1+length] must match first length bytes of sha1(product key)
    
    As a side note, internet validation is just a standard certificate chain where the root certificate should match the one hardcoded inside licdll.dll and winlogon.exe, and the leaf certificate contains hardware info.

    I actually have a keygen for XP phone activation, but I'm not sure what the policy is here. Am I allowed to post the link?
     
  13. LostED

    LostED SVF Patch Lover

    Jul 30, 2009
    7,154
    21,094
    240
    you can share it through PM
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  14. diamondggg

    diamondggg MDL Novice

    Sep 30, 2016
    23
    72
    0
    We can only speculate. Generating the key from product-id uses a random number; in their place, I would take something like sha1(a-really-long-salt + product-id) as a random number, it would make the process deterministic and allow the check (given product-id, just regenerate the key and compare) while still looking random to the outsiders. But it can simply be a large database as well.

    Probably an improper wording on my side - I mean, the code I posted is necessary for keygenning (you can't generate a key without understanding how it is checked), but not sufficient, and the next part (actually creating data that would pass a known check) in this case definitely becomes easier if you know some number theory. Personally, I do have an acquaintance with some number theorists, that allowed me to write a keygen.
     
  15. diamondggg

    diamondggg MDL Novice

    Sep 30, 2016
    23
    72
    0
    #40 diamondggg, Jan 17, 2021
    Last edited: Jan 17, 2021
    The activation servers don't know the private key of Microsoft Root Authority, the chain is necessary because the activation servers are signing requests with their own certificate. In reality, there are 4 intermediate certificates in the chain (not counting the root and the leaf). Strictly speaking, breaking any of them would allow to create the necessary chain. The last intermediate certificate is only RSA-1024, good luck :)

    (By the way, I don't know whether the servers still sign anything, but at least they are alive and still respond to the handshake request as long as you use a modern TLS.)