It could just be a coincidence, only tested 2 keys and if its alot of valid keys it will surely screwup
There should be keys with 5 in them too. Just check winsetup.dll and you'll see. Heres some of the MGADiag code: Code: int __stdcall sub_46B823(int a1, int a2) { int v2; // eax@1 unsigned int v3; // edi@3 signed int v4; // esi@3 int v5; // ecx@5 unsigned int v6; // ett@5 signed int v7; // edx@6 int result; // eax@6 bool v9; // sf@6 signed int v10; // [sp+10h] [bp-24h]@1 char v11; // [sp+14h] [bp-20h]@1 char v12; // [sp+2Ch] [bp-8h]@1 unsigned int v13; // [sp+30h] [bp-4h]@1 int v14; // [sp+34h] [bp+0h]@1 v13 = (unsigned int)&v14 ^ __security_cookie; v2 = a1; memcpy(&v11, "BCDFGHJKMPQRTVWXY2346789", 0x18u); v12 = aBcdfghjkmpqrtv[24]; *(_BYTE *)(v2 + 14) &= 7u; *(_BYTE *)(a2 + 5) = 45; *(_BYTE *)(a2 + 11) = 45; *(_BYTE *)(a2 + 17) = 45; *(_BYTE *)(a2 + 23) = 45; *(_BYTE *)(a2 + 29) = 0; v10 = 24; while ( 1 ) { v3 = 0; v4 = 14; while ( 1 ) { v5 = v4 + v2; v6 = *(_BYTE *)(v4-- + v2) + (v3 << 8); *(_BYTE *)v5 = v6 / 0x18; v3 = v6 % 0x18; if ( v4 < 0 ) break; v2 = a1; } v7 = v10; result = a2 + v10 / 5; v9 = v10-- - 1 < 0; *(_BYTE *)(result + v7) = *(&v11 + v3); if ( v9 ) break; v2 = a1; } return result; } Code: signed int __stdcall sub_46B985(int *a1, int *a2, HKEY hKey) { int v4; // ebx@5 int v5; // eax@5 int v6; // edx@5 __int32 v7; // eax@15 int v8; // eax@24 int v9; // [sp-14h] [bp-24h]@18 int v10; // [sp-10h] [bp-20h]@18 char v11; // [sp-Ch] [bp-1Ch]@18 DWORD Type; // [sp+4h] [bp-Ch]@5 DWORD cbData; // [sp+8h] [bp-8h]@5 LPBYTE lpData; // [sp+Ch] [bp-4h]@5 if ( !a1 && !a2 || !hKey ) return -2147024809; v4 = 0; Type = 1; cbData = 0; lpData = 0; v5 = RegQueryValueExA(hKey, "DigitalProductId", 0, &Type, 0, &cbData); if ( !v5 ) goto LABEL_43; if ( v5 > 0 ) v5 = (unsigned __int16)v5 | 0x80070000; v4 = v5; sub_461FB8((int)"77F760FE", 153, v5, 0); if ( v4 >= 0 ) { LABEL_43: if ( Type != 3 ) { v4 = -2147467259; sub_461FB8((int)"77F760FE", 161, -2147467259, 0); } if ( v4 >= 0 ) { lpData = (LPBYTE)sub_44B4F4(v6, v4, cbData); if ( !lpData ) { v4 = -2147024882; sub_461FB8((int)"77F760FE", 170, -2147024882, 0); } if ( v4 >= 0 ) { v7 = RegQueryValueExA(hKey, "DigitalProductId", 0, &Type, lpData, &cbData); if ( v7 ) { if ( v7 > 0 ) v7 = (unsigned __int16)v7 | 0x80070000; v11 = 0; v4 = v7; v10 = v7; v9 = 180; } else { if ( cbData >= 0x44 ) goto LABEL_22; v11 = 0; v4 = -2147467259; v10 = -2147467259; v9 = 185; } sub_461FB8((int)"77F760FE", v9, v10, v11); } } } LABEL_22: if ( a1 ) { if ( v4 < 0 ) { *a1 = 0; } else { v8 = sub_44B4F4(v6, v4, 30); *a1 = v8; if ( !v8 ) { v4 = -2147024882; sub_461FB8((int)"77F760FE", 199, -2147024882, 0); } if ( v4 >= 0 ) sub_46B823((int)(lpData + 52), *a1); } } if ( a2 ) { if ( v4 < 0 ) { *a2 = 0; } else { v4 = sub_45E37B(v4, (int)a2, (int)(lpData + 8)); if ( v4 < 0 ) { LABEL_35: if ( a2 ) { sub_44BB81(); *a2 = 0; } if ( v4 < 0 ) { if ( a1 ) { sub_44BB81(); *a1 = 0; } } goto LABEL_40; } v4 = sub_46B8C3(*a2, (int)lpData); } } if ( v4 < 0 ) goto LABEL_35; LABEL_40: sub_44BB81(); return v4; } Code: signed int __stdcall sub_49E741(LPCSTR lpString, int a2, int a3, int a4, int a5) { signed int result; // eax@2 const CHAR v6; // al@3 LPCSTR v7; // ecx@3 int v8; // edi@3 int v9; // edi@8 LPCSTR v10; // esi@10 const CHAR v11; // bl@10 char v12; // al@13 unsigned int v13; // edx@13 unsigned int v14; // eax@18 unsigned int v15; // edx@19 unsigned int v16; // [sp+14h] [bp-68h]@3 signed int v17; // [sp+18h] [bp-64h]@1 char v18; // [sp+1Ch] [bp-60h]@3 char v19; // [sp+1Dh] [bp-5Fh]@3 int v20; // [sp+20h] [bp-5Ch]@28 int v21; // [sp+24h] [bp-58h]@28 int v22; // [sp+28h] [bp-54h]@28 char v23; // [sp+5Ch] [bp-20h]@3 char v24[7]; // [sp+5Dh] [bp-1Fh]@15 int v25; // [sp+64h] [bp-18h]@28 int v26; // [sp+68h] [bp-14h]@28 int v27; // [sp+6Ch] [bp-10h]@28 int v28; // [sp+70h] [bp-Ch]@28 char v29; // [sp+74h] [bp-8h]@3 unsigned int v30; // [sp+78h] [bp-4h]@1 int v31; // [sp+7Ch] [bp+0h]@1 v30 = (unsigned int)&v31 ^ __security_cookie; v17 = 0; if ( !lpString ) return 5; v18 = 0; sub_44BBED(&v19, 0, 0x3Fu); v6 = *lpString; v16 = 0; memcpy(&v23, "BCDFGHJKMPQRTVWXY2346789", 0x18u); v29 = aBcdfghjkmpqrtv[24]; v7 = lpString; v8 = 0; while ( v6 ) { if ( v6 == 45 ) ++v8; ++v7; v6 = *v7; } v9 = 4585 * (lstrlenA(lpString) - v8) / 1000; if ( lstrlenA(lpString) >= 25 && v9 / 8 + (unsigned int)(v9 % 8 != 0) < 0x40 ) { sub_49E927((int)lpString); v10 = lpString; v11 = *lpString; while ( 1 ) { if ( !v11 ) goto LABEL_27; if ( v11 != 45 ) { v12 = v23; v13 = 0; while ( v12 != v11 && v12 ) v12 = v24[v13++]; if ( !*(&v23 + v13) ) goto LABEL_31; v14 = 0; if ( (v16 & 0x80000000u) == 0 ) { do { v15 = 24 * (unsigned __int8)*(&v18 + v14) + v13; *(&v18 + v14) = v15; v13 = v15 >> 8; ++v14; } while ( (signed int)v14 <= (signed int)v16 ); } if ( !v13 ) goto LABEL_24; if ( v14 < 0x40 ) { *(&v18 + v14) = v13; v16 = v14; } else { LABEL_31: v17 = 4; } } LABEL_24: ++v10; v11 = *v10; if ( v17 ) goto LABEL_27; } } v17 = 4; LABEL_27: result = v17; if ( !v17 ) { v25 = *(_DWORD *)&v18; v26 = v20; v27 = v21; v28 = v22; result = sub_49E5E6((int)&v25, a2, a3, a4, a5); } return result; } Code: unsigned __int64 __userpurge sub_50E94B<edx:eax>(unsigned __int64 a1<ebx:ecx>, int a2) { int v2; // eax@1 char v3; // cl@2 unsigned int v4; // edi@4 signed int v5; // esi@4 int v6; // eax@5 char v8; // [sp+18h] [bp-20h]@4 char v9; // [sp+30h] [bp-8h]@4 unsigned int v10; // [sp+34h] [bp-4h]@1 int v11; // [sp+38h] [bp+0h]@1 v10 = (unsigned int)&v11 ^ __security_cookie; v2 = a2; if ( a2 ) { do v3 = *(_BYTE *)v2++; while ( v3 ); if ( (unsigned int)(v2 - (a2 + 1)) >= 0x1D ) { memcpy(&v8, "BCDFGHJKMPQRTVWXY2346789", 0x18u); v9 = aBcdfghjkmpqrtv[24]; v4 = 0; v5 = 12; while ( 1 ) { v6 = sub_44FAFA((int)&v8, *(_BYTE *)(a2 - v5 / 5 - v5 + 28)); if ( !v6 ) break; a1 = sub_459C40(__PAIR__(HIDWORD(a1), v4), 24i64) + v6 - (signed int)&v8; --v5; v4 = a1; if ( v5 < 0 ) return a1; } } } return 0i64; } It don't think any of this will work for this new serial but it's a little more official.
What's that file that checks if a pk is valid? I don't mean online activation but there's some dll that checks if a pk's syntax is correct before installing it. I don't think the key requirements are that hard to find (though I can't do it ). So if we can generate a bunch of "valid" keys we can install it and then decrypt the key in registry. If we generate 1000 keys and the decryption is always correct then we can assume the algorithm is good. But it's probably not worth the effort to make a keygen just for testing the decryption algorithm. I think it's the file daz has just shown.
My process works on both available W8 keys that have been used for moving the N. Kinda need more key reg dumps to test but we might be stuck. I can't seem to find a key with 5 in it.
Pretty sure a key checker can do that, though not sure how those would respond to keygenned keys as there hasn't been a keygen since XP. Now I'm not sure if we'll encounter 5 but it is possible that 5 has a magic range like N does. I'd bet that if 5 occurs they use it in the last 3 blocks and the first digit dictates where. Can someone show the screen output of slmgr -dlv for W8? I could have sworn way back when I VM'd the WDP that 2 keys were installed and I can't remember if there was a 5 in the last 5 digits of the second key.
I think it's only by luck that it works at all at the moment. Code: *(_BYTE *)(v2 + 14) &= 7u; v2 = 52 So 52 + 14 = 66, which is of course: Code: Key(66) = Key(66) And 07 N and 5 are in MS's own key range, although I can't be sure as I've only seen it in the one DLL.
@Stannieman I only posted the keys with the letter 'N' in it. Other keys in the product.ini seems to be normal keys. @Everybody The file 'winsetup.dll' writes the DigitalProductID. Subrourine int '__stdcall sub_100C17B5(HKEY hKey, void *phkResult)' seems the function to write the data in the registry. This function is called from sub_100C13EA. The subroutine 'sub_100C13EA' is called by 'Module_Init_Productkey'. This 'Module_Init_Productkey' is an export in the dll-file. So now the question remaings what uses winsetup.dll? That file should hold the logic on how the reg-key 'DigitalProductID' is created. Hmm, I wonder if Microsoft has some humor? The sourcecode file used for this function (sub_100C17B5) is called 'mdl_pkey.cpp'
This time the license itself will be a new one. There will be no OEM_SLP / COA_SLP. OA3.0 will require a new EULA. SLP versions are dependant on BIOS / UEFI (Mainborad), I guess this won't change. Non SLP OEM licenses require re-activation if a particular amount of hardware is changed, there are classes and hence different weighting. AFAIK you have 35 points, each change of hardware will lower it (depending on hardware points), re-activation requirement: below 25 points. M$ could calculate an hardware ID hash and store it together with the key at activating process on their server to detect mimicked PCs. But IMO this would be against laws and violates privacy. They can ask the OEMs to do that as a production step of OEM PCs. So the OEM licensing would be to write a product key into NVRAM and to calculate an hardware ID hash and to store it. But a change of this hardware ID hash cannot mean to lose the license. TPM is not a part of OA3.0, it can be excluded. The product key is related to OEMIDs, if M$ determines the OEM by reading the ACPITable IDs only, I don't know.
hmm in winsetup.dll the "old" product key algo can be found, but it probably cant decode N or 5. lets see if the win8 beta will use N or 5 in the product keys
I hope I'm right about the 5 thing. I'm certain the N position works as I kind of get what MS is doing. They want to add new characters but not break their algorithms, so they make the first letter an index for a new character. Of course when you do things like send your key to MS via VAMT, they just want the PID, which is all numbers and seems to just be a key hash of some kind. I wouldn't be surprised if the real key never gets used in activation, but simply a hash. Hard to tell how 5 is handled until we run into a key with 5 and can check the DigitalProductID reg dump to see how 5 is handled. Until then I'll be leaving my code setup the way it is with N as it seems to handle any W8 key we have so far with N in it. If it breaks later its no issue as we are dealing with a BETA. If MS wanted to they could implement a whole new key scheme in W8 BETA, they only have to commit to it once they RTM it.
there are 2 negative numbers in the key (n > 0x7F are negative) Code: fe,04,c0,fc,b0,bf,18,2b,02,68,60,aa,a1,c2,09 maybe n < 0 has a separate set of Char's EDIT: the reason I bring it up, is I went through the code Daz posted and compared it to the VBS script and the only thing I can't account for is the "And 255" which when I manually calculate the key changes negative numbers to positive. Code: Key(x + KeyOffset) = (Cur \ 24) And 255
As long they store only the hardware ID hash and the key, there shouldn't be an privacy issue nor should it violate any law. These two alone could never point directly to a person or a system.