@ woot332 As you say your version is based off the sppcomapi.dll do you mind if the RE'd source is posted here?
Sorry to say that the " stoned" kernel exploit ain't new. Remember W8 is a dev preview not even beta . So how has anyone accept MS had access to the new bootloader ? Let alone break it.... I don't buy it. Besides , Secure boot is only half the story in W8.
Code: #include <windows.h> #include <defs.h> //------------------------------------------------------------------------- // Data declarations extern char SubKey[]; // idb extern char ValueName[]; // idb extern DWORD cbData[]; // idb extern char byte_10003046[]; // weak extern char ModuleName[]; // idb extern char ProcName[]; // idb extern char aB[2]; // weak extern HKEY phkResult; // idb extern BYTE Data; // idb extern int dword_100030B0; // weak extern char byte_100030EA; // weak extern _DWORD dword_10003170[16]; // idb extern int dword_100031B0; // weak extern char byte_100031B4[]; // weak extern int dword_100031D7; // weak extern int dword_100031DB; // weak extern int dword_100031DF; // weak extern int dword_100031E3; // weak extern int dword_100031E7; // weak extern int dword_100031EB; // weak extern int dword_100031EF; // weak extern int dword_100031F3; // weak extern int dword_100031F7; // weak extern int dword_100031FB; // weak extern _UNKNOWN unk_10003203; // weak extern int (__cdecl *dword_100032CB)(_DWORD, _DWORD, _DWORD); // weak extern int dword_100032CF; // weak //------------------------------------------------------------------------- // Function declarations BOOL __stdcall DllEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved); // signed int __usercall GetWindowsProductKey<eax>(int a1<ebx>, int a2); int __cdecl sub_10001035(); int __cdecl sub_1000104B(); // HMODULE __stdcall GetModuleHandleA(LPCSTR lpModuleName); // FARPROC __stdcall GetProcAddress(HMODULE hModule, LPCSTR lpProcName); // DWORD __stdcall GetVersion(); // LSTATUS __stdcall RegCloseKey(HKEY hKey); // LSTATUS __stdcall RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult); // LSTATUS __stdcall RegQueryValueExA(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData); //----- (10001000) -------------------------------------------------------- BOOL __stdcall DllEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) { return 1; } //----- (10001024) -------------------------------------------------------- signed int __usercall GetWindowsProductKey<eax>(int a1<ebx>, int a2) { BYTE *v2; // eax@3 int v3; // ecx@3 signed int v4; // ebx@5 signed int v5; // edi@8 unsigned int v6; // esi@8 int v7; // ecx@9 int v8; // ett@9 int v9; // eax@9 int v11; // eax@10 int v12; // eax@11 int v13; // edx@11 int v14; // ecx@11 signed int result; // eax@13 int v16; // ebx@15 HMODULE v17; // eax@15 signed int v18; // ecx@17 unsigned int v19; // edx@18 BYTE *v20; // ebx@18 signed int v21; // esi@18 unsigned int v22; // ett@19 int v23; // eax@21 int v24; // edx@21 int v25; // ecx@21 int v26; // esi@21 int v27; // edx@22 dword_100031EF = a2; sub_10001035(); sub_1000104B(); RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, 0x101u, &phkResult); RegQueryValueExA(phkResult, "DigitalProductId", 0, 0, &Data, "È"); RegCloseKey(phkResult); if ( dword_100030B0 ) { if ( (signed int)(GetVersion() >> 16) > 7601 ) { dword_100032CF = (int)((char *)&unk_10003203 + 100); v17 = GetModuleHandleA("msvcrt.dll"); dword_100032CB = (int (__cdecl *)(_DWORD, _DWORD, _DWORD))GetProcAddress(v17, "memmove"); v16 = 0; if ( (*((_DWORD *)&Data + 16) >> 16) & 0xF0 ) { result = 0; } else { dword_100031F3 = ((unsigned __int8)byte_100030EA >> 3) & 1; dword_100031F7 = dword_100031F3 != 0; dword_100031F3 = dword_100031F3 != 0; byte_100030EA = 4 * (dword_100031F7 & 2) | byte_100030EA & 0xF7; v18 = 24; dword_100031FB = 0; do { v19 = v16; v21 = 14; v20 = &Data + 52; do { v22 = (v19 << 8) + v20[v21]; v19 = ((v19 << 8) + v20[v21--]) % 0x18; v20[v21 + 1] = v22 / 0x18; } while ( v21 >= 0 ); *(_WORD *)dword_100032CF = *(_WORD *)&aB[2 * v19]; dword_100032CF -= 2; --v18; v16 = dword_100031FB; } while ( v18 != -1 ); v26 = 2 * v19; dword_100032CB(dword_100032CF + 2, dword_100032CF + 4, 2 * v19); v24 = dword_100032CF + 2; *(_WORD *)(dword_100032CF + 2 + v26) = 78; v25 = 0; v23 = dword_100031EF + 1; do { *(_BYTE *)(v23 - 1) = *(_BYTE *)v24; v27 = v24 + 1; ++v23; ++v25; if ( v25 == 5 ) { *(_BYTE *)(v23++ - 1) = 45; LOBYTE(dword_100032CB) = (_BYTE)dword_100032CB + 5; } v24 = v27 + 1; } while ( v25 != 25 ); *(_BYTE *)(v23 - 2) = 0; result = 1; } } else { dword_100031B0 = a1; v3 = 0; v2 = &Data + 52; do { *(_DWORD *)((char *)dword_10003170 + v3) = *v2; v3 += 4; ++v2; } while ( v3 != 60 ); v4 = 29; do { if ( !(v4 % 6) ) { --v4; byte_100031B4[v4] = 45; } v6 = 0; v5 = 15; dword_100031D7 = -15; do { --v5; dword_100031DB = v4; v7 = dword_10003170[14] | (v6 << 8); v8 = dword_10003170[14] | (v6 << 8); dword_100031DF = dword_100031DB; dword_10003170[14] = v8 / 0x18u; v4 = dword_100031DF; v6 = v7 % 0x18u; *((_BYTE *)&dword_100031B0 + dword_100031DF + 3) = byte_10003046[v7 % 0x18u]; dword_100031E7 = v7 / 0x18u; v9 = dword_100031E3; *(_BYTE *)v9 -= 4; *(_BYTE *)(v9 + 33) -= 4; } while ( dword_100031D7++ != -1 ); dword_100031EB = dword_100031E7; v11 = dword_100031E3; *(_BYTE *)dword_100031E3 = 56; *(_BYTE *)(v11 + 33) = 56; --v4; } while ( v4 ); v12 = dword_100031EF; v13 = (int)byte_100031B4; v14 = 0; do { *(_BYTE *)v12++ = *(_BYTE *)v13++; ++v14; } while ( v14 != 30 ); result = 1; } } else { result = 0; } return result; } // 10001024: could not find valid save-restore pair for ebp // 10001024: could not find valid save-restore pair for edi // 10001024: could not find valid save-restore pair for esi // 100030B0: using guessed type int dword_100030B0; // 100030EA: using guessed type char byte_100030EA; // 100031B0: using guessed type int dword_100031B0; // 100031D7: using guessed type int dword_100031D7; // 100031DB: using guessed type int dword_100031DB; // 100031DF: using guessed type int dword_100031DF; // 100031E3: using guessed type int dword_100031E3; // 100031E7: using guessed type int dword_100031E7; // 100031EB: using guessed type int dword_100031EB; // 100031EF: using guessed type int dword_100031EF; // 100031F3: using guessed type int dword_100031F3; // 100031F7: using guessed type int dword_100031F7; // 100031FB: using guessed type int dword_100031FB; // 100032CB: using guessed type int (__cdecl *dword_100032CB)(_DWORD, _DWORD, _DWORD); // 100032CF: using guessed type int dword_100032CF; //----- (10001035) -------------------------------------------------------- int __cdecl sub_10001035() { int result; // eax@1 int v1; // [sp+0h] [bp+0h]@1 result = v1 + 250; dword_100031E3 = v1 + 250; return result; } // 100031E3: using guessed type int dword_100031E3; //----- (1000104B) -------------------------------------------------------- int __cdecl sub_1000104B() { int result; // eax@1 int v1; // [sp+0h] [bp+0h]@1 result = v1 + 679; *(_DWORD *)(v1 + 689) = v1 + 679; return result; } I'm just looking through sppcomapi.dll too, trying to pin point what you've worked from. *EDIT* sppcomapi.dll: Code: int __thiscall sub_100107A0(void *this, int a2, int a3) { int v3; // ebx@1 int v4; // esi@2 signed int v5; // ecx@6 unsigned int v6; // edx@7 signed int v7; // esi@7 unsigned int v8; // ett@8 int v9; // esi@12 int v10; // eax@13 signed int v11; // edi@15 int v12; // esi@15 __int16 v13; // cx@16 int v14; // eax@16 int v16; // [sp-4h] [bp-9Ch]@2 void *v17; // [sp+Ch] [bp-8Ch]@1 int v18; // [sp+10h] [bp-88h]@1 bool v19; // [sp+14h] [bp-84h]@6 int v20; // [sp+18h] [bp-80h]@6 wchar_t v21; // [sp+1Ch] [bp-7Ch]@1 wchar_t v22; // [sp+4Ch] [bp-4Ch]@1 __int16 Dst; // [sp+50h] [bp-48h]@12 __int16 Src[25]; // [sp+52h] [bp-46h]@9 int v25; // [sp+84h] [bp-14h]@4 int v26; // [sp+88h] [bp-10h]@4 int v27; // [sp+8Ch] [bp-Ch]@4 unsigned int v28; // [sp+90h] [bp-8h]@4 unsigned int v29; // [sp+94h] [bp-4h]@1 int v30; // [sp+98h] [bp+0h]@1 v29 = (unsigned int)&v30 ^ dword_1001C008; v17 = this; memcpy(&v21, L"BCDFGHJKMPQRTVWXY2346789", 0x30u); v3 = 0; v18 = 0; v22 = aBcdfghjkmpqrtv[24]; if ( a3 != 16 ) { v4 = -2147024809; v16 = -2147024809; LABEL_3: sub_1000742D(v16); goto LABEL_18; } v25 = *(_DWORD *)a2; v26 = *(_DWORD *)(a2 + 4); v27 = *(_DWORD *)(a2 + 8); v28 = *(_DWORD *)(a2 + 12); if ( (v28 >> 16) & 0xF0 ) goto LABEL_23; v20 = (BYTE2(v28) >> 3) & 1; v19 = v20 != 0; v20 = v20 != 0; BYTE2(v28) = 4 * (v19 & 2) | BYTE2(v28) & 0xF7; v5 = 24; do { v6 = 0; v7 = 14; do { v8 = (v6 << 8) + *((_BYTE *)&v25 + v7); v6 = ((v6 << 8) + *((_BYTE *)&v25 + v7--)) % 0x18; *((_BYTE *)&v25 + v7 + 1) = v8 / 0x18; } while ( v7 >= 0 ); --v5; Src[v5] = *(&v21 + v6); } while ( v5 >= 0 ); if ( (_BYTE)v25 ) { LABEL_23: v4 = -2147024883; v16 = -2147024883; goto LABEL_3; } if ( v19 ) { v9 = 2 * v6; memmove(&Dst, Src, 2 * v6); *(__int16 *)((char *)&Dst + v9) = 78; } v10 = sub_1000D534(0x2Du, 30, (int)&v18); v4 = v10; v19 = v10; if ( v10 >= 0 ) { v12 = v18; v11 = 0; do { v13 = *(&Dst + v11); v14 = v11 + v11 / 5; ++v11; *(_WORD *)(v12 + 2 * v14) = v13; } while ( v11 < 25 ); *(_DWORD *)v17 = v12; v4 = v19; } else { sub_1000742D(v10); v3 = v18; } LABEL_18: sub_100073C2(v4); if ( v3 ) sub_1000732A(v3); return v4; } // 10003958: using guessed type wchar_t aBcdfghjkmpqrtv[25]; // 1001C008: using guessed type int dword_1001C008; // 100107A0: using guessed type __int16 var_7C[26]; // 100107A0: using guessed type __int16 Src[25];
Function 1 Code: signed int __stdcall sub_100086F7(int a1, int a2) { UINT v2; // esi@1 signed int v3; // edi@2 int v4; // eax@5 UINT ui; // [sp+Ch] [bp-8h]@1 OLECHAR *strIn; // [sp+10h] [bp-4h]@1 v2 = 0; strIn = 0; ui = 0; if ( !a2 ) { v3 = -2147024809; LABEL_3: sub_1000742D(v3); goto LABEL_8; } v3 = sub_1001387E(1, &strIn); if ( v3 < 0 ) goto LABEL_3; v4 = sub_100090B6(strIn, (UINT)&ui); v3 = v4; if ( v4 >= 0 ) { *(_DWORD *)a2 = ui; } else { sub_1000742D(v4); v2 = ui; } LABEL_8: sub_100073C2(v3); if ( v2 ) SysFreeString((BSTR)v2); if ( strIn ) sub_1000732A((int)strIn); return v3; } function 2 Code: signed int __stdcall sub_1001387E(int a1, void *a2) { const WCHAR *v2; // eax@1 int v3; // eax@3 HLOCAL v4; // edi@3 signed int v5; // esi@3 int v7; // [sp-Ch] [bp-10h]@5 HLOCAL hMem; // [sp+0h] [bp-4h]@1 hMem = 0; v2 = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\DefaultProductKey"; if ( !a1 ) v2 = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\"; v3 = sub_10013911(HKEY_LOCAL_MACHINE, v2, L"DigitalProductId", (int)&hMem, (int)&a1); v4 = hMem; v5 = v3; if ( v3 < 0 ) goto LABEL_16; if ( a1 != 164 || *(_DWORD *)hMem != 164 ) { v5 = -2147418113; v7 = -2147418113; LABEL_10: sub_1000742D(v7); goto LABEL_11; } if ( a2 ) { v5 = sub_10010754((int)((char *)hMem + 52), 16, a2); if ( v5 < 0 ) { LABEL_16: v7 = v5; goto LABEL_10; } } LABEL_11: sub_100073C2(v5); if ( v4 ) LocalFree(v4); return v5; } Function 3 Code: unsigned int __stdcall sub_10010754(int a1, int a2, void *a3) { unsigned int v3; // esi@2 unsigned int v4; // eax@5 int v6; // [sp-4h] [bp-8h]@2 if ( !a1 || !a2 || !a3 ) { v3 = -2147024809; v6 = -2147024809; LABEL_7: sub_1000742D(v6); goto LABEL_8; } v4 = sub_100107A0(a3, a1, a2); v3 = v4; if ( (v4 & 0x80000000u) != 0 ) { v6 = v4; goto LABEL_7; } LABEL_8: sub_100073C2(v3); return v3; } Final function Code: unsigned int __thiscall sub_100107A0(void *this, int a2, int a3) { int v3; // ebx@1 unsigned int v4; // esi@2 signed int v5; // ecx@6 unsigned int v6; // edx@7 signed int v7; // esi@7 unsigned int v8; // ett@8 int v9; // esi@12 int v10; // eax@13 int v11; // esi@15 signed int v12; // edi@15 __int16 v13; // cx@16 int v14; // eax@16 int v16; // [sp-4h] [bp-9Ch]@2 void *v17; // [sp+Ch] [bp-8Ch]@1 int v18; // [sp+10h] [bp-88h]@1 unsigned int v19; // [sp+14h] [bp-84h]@6 __int64 v20; // [sp+18h] [bp-80h]@1 wchar_t v21; // [sp+4Ch] [bp-4Ch]@1 __int16 Dst; // [sp+50h] [bp-48h]@12 __int16 Src[25]; // [sp+52h] [bp-46h]@9 int v24; // [sp+84h] [bp-14h]@4 int v25; // [sp+88h] [bp-10h]@4 int v26; // [sp+8Ch] [bp-Ch]@4 unsigned int v27; // [sp+90h] [bp-8h]@4 unsigned int v28; // [sp+94h] [bp-4h]@1 int v29; // [sp+98h] [bp+0h]@1 v28 = (unsigned int)&v29 ^ __security_cookie; v17 = this; memcpy((char *)&v20 + 4, L"BCDFGHJKMPQRTVWXY2346789", 0x30u); v3 = 0; v18 = 0; v21 = aBcdfghjkmpqrtv[24]; if ( a3 != 16 ) { v4 = -2147024809; v16 = -2147024809; LABEL_3: sub_1000742D(v16); goto LABEL_18; } v24 = *(_DWORD *)a2; v25 = *(_DWORD *)(a2 + 4); v26 = *(_DWORD *)(a2 + 8); v27 = *(_DWORD *)(a2 + 12); if ( (v27 >> 16) & 0xF0 ) goto LABEL_23; LODWORD(v20) = (BYTE2(v27) >> 3) & 1; v19 = v20 != 0; LODWORD(v20) = v20 != 0; BYTE2(v27) = 4 * (v19 & 2) | BYTE2(v27) & 0xF7; v5 = 24; do { v6 = 0; v7 = 14; do { v8 = (v6 << 8) + *((_BYTE *)&v24 + v7); v6 = ((v6 << 8) + *((_BYTE *)&v24 + v7--)) % 0x18; *((_BYTE *)&v24 + v7 + 1) = v8 / 0x18; } while ( v7 >= 0 ); --v5; Src[v5] = *((_WORD *)&v20 + v6 + 2); } while ( v5 >= 0 ); if ( (_BYTE)v24 ) { LABEL_23: v4 = -2147024883; v16 = -2147024883; goto LABEL_3; } if ( v19 ) { v9 = 2 * v6; memmove(&Dst, Src, 2 * v6); *(__int16 *)((char *)&Dst + v9) = 78; } v10 = sub_1000D534(0x2Du, 30, (int)&v18); v4 = v10; v19 = v10; if ( v10 >= 0 ) { v11 = v18; v12 = 0; do { v13 = *(&Dst + v12); v14 = v12 + v12 / 5; ++v12; *(_WORD *)(v11 + 2 * v14) = v13; } while ( v12 < 25 ); *(_DWORD *)v17 = v11; v4 = v19; } else { sub_1000742D(v10); v3 = v18; } LABEL_18: sub_100073C2(v4); if ( v3 ) sub_1000732A(v3); return v4; } // 10003958: using guessed type wchar_t aBcdfghjkmpqrtv[25]; // 1001C008: using guessed type int __security_cookie; // 100107A0: using guessed type __int16 Src[25]; This should help.
You see how it goes - 54 digits' decimal number takes 23 bytes, if i'm not wrong, so both installation ID code plus activation code would be suspiciously close to the length of MSDMData (49 bytes)...
sppcomapi.dll CPU Disasm Address Hex dump Command Comments 6AFD07A0 8BFF MOV EDI,EDI 6AFD07A2 55 PUSH EBP 6AFD07A3 8BEC MOV EBP,ESP 6AFD07A5 81EC 8C000000 SUB ESP,8C 6AFD07AB A1 08C0FD6A MOV EAX,DWORD PTR DS:[6AFDC008] 6AFD07B0 33C5 XOR EAX,EBP 6AFD07B2 8945 FC MOV DWORD PTR SS:[EBP-4],EAX 6AFD07B5 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] 6AFD07B8 53 PUSH EBX 6AFD07B9 56 PUSH ESI 6AFD07BA 57 PUSH EDI 6AFD07BB 898D 74FFFFFF MOV DWORD PTR SS:[EBP-8C],ECX 6AFD07C1 6A 0C PUSH 0C 6AFD07C3 59 POP ECX 6AFD07C4 BE 5839FC6A MOV ESI,OFFSET 6AFC3958 ; UNICODE "BCDFGHJKMPQRTVWXY2346789" unicode string 6AFD07C9 8D7D 84 LEA EDI,[EBP-7C] 6AFD07CC F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS 6AFD07CE 33DB XOR EBX,EBX 6AFD07D0 837D 0C 10 CMP DWORD PTR SS:[EBP+0C],10 6AFD07D4 899D 78FFFFFF MOV DWORD PTR SS:[EBP-88],EBX 6AFD07DA 66:A5 MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI] 6AFD07DC 74 10 JE SHORT 6AFD07EE 6AFD07DE BE 57000780 MOV ESI,80070057 6AFD07E3 56 PUSH ESI 6AFD07E4 E8 446CFFFF CALL 6AFC742D 6AFD07E9 E9 FA000000 JMP 6AFD08E8 6AFD07EE 8BF0 MOV ESI,EAX 6AFD07F0 8D7D EC LEA EDI,[EBP-14] 6AFD07F3 A5 MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ES ; buffer 6AFD07F4 A5 MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ES 6AFD07F5 A5 MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ES 6AFD07F6 A5 MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ES 6AFD07F7 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8] 6AFD07FA C1E8 10 SHR EAX,10 6AFD07FD A8 F0 TEST AL,F0 6AFD07FF 74 0A JE SHORT 6AFD080B 6AFD0801 B8 0D000780 MOV EAX,8007000D 6AFD0806 8BF0 MOV ESI,EAX 6AFD0808 50 PUSH EAX 6AFD0809 ^ EB D9 JMP SHORT 6AFD07E4 6AFD080B 8A4D FA MOV CL,BYTE PTR SS:[EBP-6] ; mov to cl magic byte 6AFD080E 8AC1 MOV AL,CL 6AFD0810 C0E8 03 SHR AL,3 6AFD0813 24 01 AND AL,01 6AFD0815 895D 80 MOV DWORD PTR SS:[EBP-80],EBX 6AFD0818 8845 80 MOV BYTE PTR SS:[EBP-80],AL 6AFD081B 33C0 XOR EAX,EAX 6AFD081D 3945 80 CMP DWORD PTR SS:[EBP-80],EAX 6AFD0820 6A 18 PUSH 18 6AFD0822 0F95C0 SETNE AL 6AFD0825 80E1 F7 AND CL,F7 6AFD0828 5F POP EDI 6AFD0829 8985 7CFFFFFF MOV DWORD PTR SS:[EBP-84],EAX 6AFD082F 8945 80 MOV DWORD PTR SS:[EBP-80],EAX 6AFD0832 24 02 AND AL,02 6AFD0834 C0E0 02 SHL AL,2 6AFD0837 0AC8 OR CL,AL 6AFD0839 884D FA MOV BYTE PTR SS:[EBP-6],CL ;new magic byte 6AFD083C 8BCF MOV ECX,EDI 6AFD083E 6A 0E PUSH 0E ; first loop lopp 14 times 6AFD0840 8BD3 MOV EDX,EBX 6AFD0842 5E POP ESI 6AFD0843 0FB64435 EC MOVZX EAX,BYTE PTR SS:[ESI+EBP-14]* ; mov eax magic byte 6AFD0848 C1E2 08 SHL EDX,8 6AFD084B 03C2 ADD EAX,EDX 6AFD084D 33D2 XOR EDX,EDX 6AFD084F F7F7 DIV EDI 6AFD0851 4E DEC ESI 6AFD0852 884435 ED MOV BYTE PTR SS:[ESI+EBP-13],AL ; mov result to same address as * 6AFD0856 ^ 79 EB JNS SHORT 6AFD0843 6AFD0858 49 DEC ECX 6AFD0859 66:8B4455 84 MOV AX,WORD PTR SS:[EDX*2+EBP-7C] ; mov to ax "BCDFGHJKMPQRTVWXY2346789" unicode string 6AFD085E 66:89444D BA MOV WORD PTR SS:[ECX*2+EBP-46],AX ; last char in product ket decoded mov to buffer 6AFD0863 ^ 79 D9 JNS SHORT 6AFD083E 6AFD0865 385D EC CMP BYTE PTR SS:[EBP-14],BL ; exception check? 6AFD0868 ^ 75 97 JNE SHORT 6AFD0801 6AFD086A 399D 7CFFFFFF CMP DWORD PTR SS:[EBP-84],EBX ; exception check? 6AFD0870 74 1D JE SHORT 6AFD088F 6AFD0872 8D3412 LEA ESI,[EDX+EDX] ; multiply edx*2 6AFD0875 56 PUSH ESI 6AFD0876 8D45 BA LEA EAX,[EBP-46] 6AFD0879 50 PUSH EAX ; push decoded string ignoring first char 6AFD087A 8D45 B8 LEA EAX,[EBP-48] 6AFD087D 50 PUSH EAX ; push whole string 6AFD087E FF15 2012FC6A CALL DWORD PTR DS:[6AFC1220] ; call to msvcrt.dll memmove api 6AFD0884 83C4 0C ADD ESP,0C 6AFD0887 6A 4E PUSH 4E ;N char pushed on stack 6AFD0889 58 POP EAX 6AFD088A 66:894435 B8 MOV WORD PTR SS:[ESI+EBP-48],AX ; this will fixes N char
Forum member B8 seems to think that theres N, 5 and Z in the new product keys. Theres no proof of the 5 or Z in use though.
I have seen this '23456789BCDFGHJKMNPQRTVWXYbcdfghjkmnpqrtvwxy'-range in the winsetup.dll file. It does contain the N and the 5. Adding two makes it more logical because they can go to Base26. Adding a third makes the calculation more difficult. They can easily change their calculation from Base24 to Base26. With all the products using the same range, I guess that the end is near for the old range. Maybe they are forced to change it.
What do you mean by forced? MS is running out of keys? PS: why does the range contain small letters? It would be more logical if they just converted the key to all capitals (requires only 1 extra line) so only capital letters need to be in the key.
based on the code from sppcomapi.dll Daz posted only an N is added for Win 8 they are determining if an N is inserted by looking at the input + 12 Code: v28 = *(_DWORD *)(a2 + 12); // v20 = (BYTE2(v28) >> 3) & 1; // v19 = v20 != 0; // if ( v19 ) { v9 = 2 * v6; memmove(&Dst, Src, 2 * v6); *(__int16 *)((char *)&Dst + v9) = 78; // 78 = 'N' } Work has me busy so I won't have time to work on this until the weekend. // EDIT updated VBS script and VS project to the proper way to decode Win 8 keys Code: Set WshShell = CreateObject("WScript.Shell") MsgBox ConvertToKey(WshShell.RegRead("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DigitalProductId")) Function ConvertToKey(Key) Const KeyOffset = 52 isWin8 = (Key(66) \ 6) And 1 Key(66) = (Key(66) And &HF7) Or ((isWin8 And 2) * 4) i = 24 Chars = "BCDFGHJKMPQRTVWXY2346789" Do Cur = 0 X = 14 Do Cur = Cur * 256 Cur = Key(X + KeyOffset) + Cur Key(X + KeyOffset) = (Cur \ 24) Cur = Cur Mod 24 X = X -1 Loop While X >= 0 i = i -1 KeyOutput = Mid(Chars, Cur + 1, 1) & KeyOutput Last = Cur Loop While i >= 0 If (isWin8 = 1) Then keypart1 = Mid(KeyOutput, 2, Last) insert = "N" KeyOutput = Replace(KeyOutput, keypart1, keypart1 & insert, 2, 1, 0) If Last = 0 Then KeyOutput = insert & KeyOutput End If a = Mid(KeyOutput, 1, 5) b = Mid(KeyOutput, 6, 5) c = Mid(KeyOutput, 11, 5) d = Mid(KeyOutput, 16, 5) e = Mid(KeyOutput, 21, 5) ConvertToKey = a & "-" & b & "-" & c & "-" & d & "-" & e End Function
An algo would work something like this "magic" byte is set decode product key Convert the decoded product key string to unicode if its not. ignore first char take a look at memmove api Then the edx register is multiply by 2 and is used as an index where the N char is goinng to be placed.
@nononsence May be the error is on my side, but when I download your attachment it becomes corrupted.
Erm, I don't get 54 digits = 23 bytes. I'd say 54 digits = 54 bytes (36h). So it doesn't fit. OA3.0 MSDMData field is specified there, it are 29 digits. MSDMACPIData = 49 bytes though. So I assume: -It only holds the product key -It will not change, there still will be 5*5 plus 4 hyphens. If hadware hashing then by creating the installation ID at once, no stored values. As said already, this probably needs to be reversed.