从主板检索 Windows 8 产品密钥

从主板检索 Windows 8 产品密钥

我的新笔记本电脑预装了 Windows 8。我天真地格式化了硬盘并安装了老旧的 Ubuntu。现在我想再次安装 Windows 8 进行双启动,但我没有 DVD,下载 ISO 时需要产品密钥。该密钥不再位于笔记本电脑背面,而是位于主板上的某个地方。

有没有办法使用 Ubuntu 从主板恢复产品密钥?

答案1

另一种不需要查看大量输出的方法是:

sudo acpidump -b -t MSDM | dd bs=1 skip=56 2>/dev/null;echo

acpidump 转储表(默认为十六进制转储格式),但 -b 选项告诉它输出原始数据。由于我们只需要表的最后一部分,因此将输出通过管道传输到 dd,但要跳过不必要的垃圾。最后,在末尾添加一个 echo 以使其适合终端 =D

acpidump -t MSDM也可以工作,但是密钥被分成多行,很难复制。


感谢 Lekensteyn 提供更新:

Ubuntu 附带的新版本acpidump与上述不同。-b 标志导致acpidump在任何情况下都写入文件,因此另一种方法是使用命令

sudo tail -c+57 /sys/firmware/acpi/tables/MSDM

合法的 Windows 8 安装程序应该自动检测 ACPI 中的密钥并使用内置密钥继续安装。

但需要注意的是,我曾尝试使用这种方法在虚拟机中使用自己的产品密钥安装 Win8,但它自动停用,提示产品密钥正在使用中。所以,实际上它没什么用。由于 Win8 OEM 密钥旨在与特定计算机绑定,因此如果您要求 Microsoft 取消注册密钥以便您可以在虚拟机中使用它,那么您将碰壁,更不用说另一台计算机了。

唯一可以使用密钥的方式是,如果您从未启动过 Win8 或启动时未连接到网络。即便如此,如果您的虚拟机/新计算机被允许连接到网络,它将自动注册密钥,从而使您的实际安装无法使用。

答案2

通常,OEM 制造商会在 ROM 上预装电子密钥。Windows 会识别此密钥并自动激活您的安装。因此,通常您不需要知道此代码。但是,您可能看到一些使用这个的痕迹

sudo dmidecode

列为OEM-specific Types,编码/加密,可能包含它。HP 和 Dell 等主要 OEM 都使用它。在 Windows 网站上询问更多详细信息;这是错误的地方。我记得的唯一细节是需要 OEM 版本的 Windows 安装光盘(即非零售版)。

答案3

 sudo tail -c+57 /sys/firmware/acpi/tables/MSDM

这使我获得了 MSI 笔记本电脑上 OEM Windows 8 的产品密钥。

答案4

所以我在这里看到了其他的答案,需要加入进来。发现

strings /sys/firmware/acpi/tables/MSDM

如果原始密钥仍在使用,则效果很好。但是我有一些随家庭附加功能一起提供的系统,您需要从注册表中获取当前密钥。

winmount=/mnt
echo "hex \\Microsoft\\Windows NT\\CurrentVersion\\DigitalProductId\nq\nq" | chntpw -e ${winmount}/Windows/System32/config/SOFTWARE

然后我们需要通过算法运行它来获取密钥。

我发现了一些代码https://github.com/mrpeardotnet/WinProdKeyFinder/blob/master/WinProdKeyFind/KeyDecoder.cs

    /// <summary>
    /// Decodes Windows Product Key from the DigitalProductId. 
    /// This method applies to DigitalProductId from Windows 7 or lower versions of Windows.
    /// </summary>
    /// <param name="digitalProductId">DigitalProductId to decode</param>
    /// <returns>Decoded Windows Product Key as a string</returns>
    private static string DecodeProductKey(byte[] digitalProductId)
    {
        const int keyStartIndex = 52;
        const int keyEndIndex = keyStartIndex + 15;
        var digits = new[]
        {
            'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'M', 'P', 'Q', 'R',
            'T', 'V', 'W', 'X', 'Y', '2', '3', '4', '6', '7', '8', '9',
        };
        const int decodeLength = 29;
        const int decodeStringLength = 15;
        var decodedChars = new char[decodeLength];
        var hexPid = new ArrayList();
        for (var i = keyStartIndex; i <= keyEndIndex; i++)
        {
            hexPid.Add(digitalProductId[i]);
        }
        for (var i = decodeLength - 1; i >= 0; i--)
        {
            // Every sixth char is a separator.
            if ((i + 1) % 6 == 0)
            {
                decodedChars[i] = '-';
            }
            else
            {
                // Do the actual decoding.
                var digitMapIndex = 0;
                for (var j = decodeStringLength - 1; j >= 0; j--)
                {
                    var byteValue = (digitMapIndex << 8) | (byte)hexPid[j];
                    hexPid[j] = (byte)(byteValue / 24);
                    digitMapIndex = byteValue % 24;
                    decodedChars[i] = digits[digitMapIndex];
                }
            }
        }
        return new string(decodedChars);
    }

    /// <summary>
    /// Decodes Windows Product Key from the DigitalProductId. 
    /// This method applies to DigitalProductId from Windows 8 or newer versions of Windows.
    /// </summary>
    /// <param name="digitalProductId">DigitalProductId to decode</param>
    /// <returns>Decoded Windows Product Key as a string</returns>
    public static string DecodeProductKeyWin8AndUp(byte[] digitalProductId)
    {
        var key = String.Empty;
        const int keyOffset = 52;
        var isWin8 = (byte)((digitalProductId[66] / 6) & 1);
        digitalProductId[66] = (byte)((digitalProductId[66] & 0xf7) | (isWin8 & 2) * 4);

        const string digits = "BCDFGHJKMPQRTVWXY2346789";
        var last = 0;
        for (var i = 24; i >= 0; i--)
        {
            var current = 0;
            for (var j = 14; j >= 0; j--)
            {
                current = current*256;
                current = digitalProductId[j + keyOffset] + current;
                digitalProductId[j + keyOffset] = (byte)(current/24);
                current = current%24;
                last = current;
            }
            key = digits[current] + key;
        }

        var keypart1 = key.Substring(1, last);
        var keypart2 = key.Substring(last + 1, key.Length - (last + 1));
        key = keypart1 + "N" + keypart2;

        for (var i = 5; i < key.Length; i += 6)
        {
            key = key.Insert(i, "-");
        }

        return key;
    }

我将尝试解码算法并将其写入 bash。dmi 输出似乎是用于解码密钥的旧算法(<win8)。我还没有找到使用新算法(>win7)的选项。

相关内容