从主板上检索Windows 8产品密钥


12

我的新笔记本电脑预装了Windows8。天真地,我只是格式化硬盘并安装了旧版Ubuntu。现在,我想再次安装Windows 8以进行双重引导,但是我没有DVD,并且确实要下载ISO,需要一个产品密钥。该键不再位于笔记本电脑的背面,而是位于主板上的某个位置。

有什么方法可以使用Ubuntu从主板上恢复产品密钥吗?

Answers:


16

通常,OEM制造商将密钥以电子方式预加载到ROM中。Windows将识别出此情况并自动激活您的安装。因此,通常,您不需要知道此代码。但是,您可能会看到一些使用

sudo dmidecode

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


我记得过去曾经在Lenovo Thinkpad上使用dmidecode,但似乎在此Lenovo Ideapad上,它在任何地方都不包含许可证密钥。最终,我在/sys/firmware/acpi/tables/MSDM下面其他答案中提到了Chuck R提到的问题。
卢克,

23

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

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

acpidump转储该表(默认为hexdump格式),但是-b选项告诉它输出原始数据。因为我们只需要表的最后一部分,所以将输出通过管道传递到dd,但是跳过不必要的垃圾。最后,在末尾添加回声以使其成为终端友好型= D

acpidump -t MSDM 也可以使用,但是该密钥在多行中被打断,因此很难复制。


感谢Lekensteyn更新:

acpidumpUbuntu随附的新版本的工作方式与上述不同。-b标志会导致acpidump在所有情况下都写入文件,因此另一种方法是使用以下命令

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

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

但是,应该注意的是,我使用此方法尝试使用自己的产品密钥在VM中安装Win8,但会自动停用,表示正在使用产品密钥。因此,它在所有现实中都没有多大用处。由于Win8 OEM密钥被设计为绑定到该特定计算机,因此如果您要求Microsoft取消注册密钥,以便可以在VM中使用它,更不用说另一台计算机了,您将遇到麻烦。

唯一可以使用该密钥的方法是,如果从未启动过Win8,或者当启动时没有连接到网络。即使这样,如果曾经允许您的VM /新计算机连接到网络,它将自动注册密钥,从而使您的实际安装无法使用。


只是尝试了一下,上面的命令切断了其中一个字符。我用过了sudo acpidump -b -t MSDM | dd bs=1 skip=56 2>/dev/null;echo,我拿出了完整的钥匙。
安德鲁C

您是正确的,对此感到抱歉。更新我的答案。
Chuck R

1
-b选项特定于acpidump内核树随附的工具。较新的Ubuntu版本附带了具有不同选项的其他acpidump工具(来自iasl)。我无法测试此命令,但它应该可以工作:sudo acpidump -n HPET | tail -n+2 | xxd -r | head -c+57。替代方法:sudo tail -c+57 /sys/firmware/acpi/tables/MSDM
Lekensteyn 2014年

@Lekensteyn我最近在与MS通话时也注意到了这一点。如果执行-b选项,则由于某种原因,它默认现在会碰撞到文件。我想知道是否有一种方法可以在管道上没有更多数据时标记销毁管道……这是另一天的话题。您的第一个命令对我不起作用,但是第二个命令很好。我将更新我的答案以包括它=)
Chuck R

1
使用Ubuntu 16.04 LTS的更新版本:“ sudo tail -c + 57 / sys / firmware / acpi / tables / MSDM”可以确认我从三星笔记本电脑获得Windows密钥就好=)
Valross.nu

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

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


3

如果上面的代码对您不起作用,或者您只想查看带有密钥的十六进制输出,那么您就可以全部使用此代码。它类似于bless hex二进制编辑器。Windows将以常规格式HAN50-0L00M-4D31T-CR4ZY拥有其密钥。5组中的5个字母或数字。

$ ls /sys/firmware/acpi/tables
$ sudo hd /sys/firmware/acpi/tables/MSDM

00000000  ha ns oo lo oe at es ap  pl le sa uc ef or li fe  |Key in area|
00000010  cu si ca nb ro ha ms am  cu si ca nb ro ha ms am  |In key area|
00000020  it sj us ho wz ir ol lz  it sj us ho wz ir ol lz  |Area in key|
00000000  ha ns oo lo oe at es ap  pl le sa uc ef or li fe  |It is 5 x 5|
00000010  cu si ca nb ro ha ms am  cu si ca nb ro ha ms am  |Key in area|
00000020  it sj us ho wz ir ol lz  it sj us ho wz ir ol lz  |In key area|
00000050  ha ns oo lo ow az he re                           |Area in key|
00000055                                                    |It is 5 x 5|

运行以下命令将以标准Microsoft格式转储产品密钥。

sudo hexdump -s 56 -e '"MSDM key: " /29 "%s\n"' /sys/firmware/acpi/tables/MSDM

0

所以我在这里看到了其他答案,需要鸣叫。发现

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)的选项。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.