如果你只想在 Windows 上运行它

如果你只想在 Windows 上运行它

我在硬盘仍在运行时意外断开了连接,导致 Windows 7 安装损坏;现在我完全无法启动 Windows。我尝试了各种方法修复安装:Windows 启动修复、chkdsk /r、SFC /scannow、bootrec /rebuildbcd 等,但都没有成功。我想执行全新安装,但问题是我没有在任何地方写下 Windows 产品密钥,而且我无法使用任何脚本或实用程序从注册表中检索它,因为我无法启动 Windows。

Windows 7 产品密钥以加密形式存储在注册表项 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion 的“DigitalProductId”值中。我能够从 Ubuntu Live CD 以只读方式安装损坏的 Windows 分区,并将包含相关密钥和值的 Windows\System32\config\SOFTWARE 注册表配置单元复制到闪存驱动器,但在运行的 Windows 安装中将此配置单元加载到 regedit 中,然后尝试使用脚本或实用程序解密加载的“DigitalProductId”值,无论我尝试多少次,都只会返回主机 Windows 安装的产品密钥。我尝试联系 Microsoft 支持,但他们没有提供任何帮助。有人能进一步指导我吗?也许还有其他方法可以从 Linux 检索产品密钥?

如果有人更熟悉脚本/加密技术,愿意尝试按照解密脚本手动解密产品密钥,我可以通过电子邮件向您发送导出的“DigitalProductId”值、SOFTWARE 注册表配置单元和解密脚本。

答案1

Linux 上有一个很棒的工具,叫做chntpw。你可以在 Debian/Ubuntu 上通过以下方式轻松获取它:

sudo apt install chntpw

要查看相关的注册表文件,请挂载 Windows 磁盘并按如下方式打开它:

chntpw -e /path/to/windisk/Windows/System32/config/software

现在要获取解码,DigitalProductId请输入以下命令:

dpi \Microsoft\Windows NT\CurrentVersion\DigitalProductId

答案2

适合那些不羞于做一点编码的人。

大约 10 年前,我发现了一个算法,并将其实现在C#(见下文)


如果你只想在 Windows 上运行它

我擅自将其转换为 powershell 脚本:

$dpid = Get-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -Name "DigitalProductId"

# Get the range we are interested in
$id = $dpid.DigitalProductId[52..(52+14)]

# Character table
$chars = "BCDFGHJKMPQRTVWXY2346789"

# Variable for the final product key
$pkey = ""

# Calculate the product key
for ($i=0; $i -le 24; $i++) {
    $c = 0

    for($j=14; $j -ge 0; $j--) {
        $c = ($c -shl 8) -bxor $id[$j]

        $id[$j] = [Math]::Floor($c / 24) -band 255

        $c = $c % 24
    }
    $pkey = $chars[$c] + $pkey
}
# Insert some dashes
for($i = 4; $i -gt 0; $i--) {
    $pkey = $pkey.Insert($i * 5, "-")
}
$pkey

运行此程序,您就会获得产品密钥。(因此您无需编写任何代码)


原始帖子

这是我挖掘并注释的实际 C# 代码。

public static string ConvertDigitalProductID(string regPath, string searchKey = "DigitalProductID") {
    // Open the sub key i.E.: "Software\Microsoft\Windows NT\CurrentVersion"
    var regkey = Registry.LocalMachine.OpenSubKey(regPath, false);
    // Retreive the value of "DigitalProductId"
    var dpid = (byte[])regkey.GetValue(searchKey);
    // Prepare an array for the relevant parts
    var idpart = new byte[15];

    // Copy the relevant parts of the array
    Array.Copy(dpid, 52, idpart, 0, 15);

    // Prepare the chars that will make up the key
    var charStore = "BCDFGHJKMPQRTVWXY2346789";

    // Prepare a string for the result
    string productkey = "";

    // We need 24 iterations (one for each character)
    for(int i = 0; i < 25; i++) {

        int c = 0;
        // Go through each of the 15 bytes of our dpid
        for(int j = 14; j >= 0; j--) {
            // Shift the current byte to the left and xor in the next byte
            c = (c << 8) ^ idpart[j];

            // Leave the result of the division in the current position
            idpart[j] = (byte)(c / 24);

            // Take the rest of the division forward to the next round
            c %= 24;
        }
        // After each round, add a character from the charStore to our key
        productkey = charStore[c] + productkey;
    }

    // Insert the dashes
    for(int i = 4; i > 0; i--) {
        productkey = productkey.Insert(i * 5, "-");
    }

    return productkey;
}

你必须将它Software\Microsoft\Windows NT\CurrentVersion作为密钥传递,这样它才能找到DigitalProductId

当时,MS Office 产品使用相同的算法,因此通过向该函数提供相关的注册表项,它也可以计算出这些产品密钥。

当然,您可以重构该函数,以便它接受字节数组作为输入。

至于今天。我刚刚在我的 Windows 10 机器上测试了它,它仍然有效。

答案3

这是另一个答案的 Python 端口(适用于 Windows 8.1)。 相比之下,它的优点chntpw是即使驱动器处于只读状态,它也能工作。

要求:

pip install python-registry

代码:

#!/usr/bin/env python
import sys
from Registry import Registry
reg = Registry.Registry("/path/to/drive/Windows/System32/config/RegBack/SOFTWARE")
# Uncomment for registry location for Windows 7 and below:
#reg = Registry.Registry("/path/to/drive/Windows/system32/config/software")
key = reg.open("Microsoft\Windows NT\CurrentVersion")
did = bytearray([v.value() for v in key.values() if v.name() == "DigitalProductId"][0])
idpart = did[52:52+15]
charStore = "BCDFGHJKMPQRTVWXY2346789";
productkey = "";
for i in range(25):
  c = 0
  for j in range(14, -1, -1):
    c = (c << 8) ^ idpart[j]
    idpart[j] = c // 24
    c %= 24
  productkey = charStore[c] + productkey
print('-'.join([productkey[i * 5:i * 5 + 5] for i in range(5)]))

答案4

非常感谢 Lenar Hoyt 提供上述 Python 解决方案。

我有一台运行 Windows 10 的 PC,其许可证是从 Windows 8 升级而来的,并且(根据下面的 penguinjeff 的 bash 版本)您需要进行一些修改才能处理此类许可证。

笔记:如果你在 Windows 上运行,你可以通过运行以下命令来部分验证解码的密钥slmgr -dli

在我的 PC 上,报告显示“部分产品密钥:3V66T”,而 Lenar 的代码(截至 2018 年 9 月)报告了一个虚假密钥“TY4CG-JDJH7-VJ2WF-DY4X9-HCFC6”

这是我对上述内容进行修改的版本,它正确(我相信)返回了“xxxxx-xxxxx-xxxxx-xxxxx-3V66T”形式的键

#!/usr/bin/env python
import sys
from Registry import Registry
reg = Registry.Registry("/path/to/drive/Windows/System32/config/RegBack/SOFTWARE")
# Uncomment for registry location for Windows 7 and below:
#reg = Registry.Registry("/path/to/drive/Windows/system32/config/software")
key = reg.open("Microsoft\Windows NT\CurrentVersion")
did = bytearray([v.value() for v in key.values() if v.name() == "DigitalProductId"][0])
isWin8 = (did[66] // 6) & 1
if isWin8:
  did[66] = (did[66] & 0xF7) | ((isWin8 & 2) * 4)

idpart = did[52:52+15]
charStore = "BCDFGHJKMPQRTVWXY2346789";
productkey = "";
lastC = 0    # isWin8 support
for i in range(25):
  c = 0
  for j in range(14, -1, -1):
    c = (c << 8) ^ idpart[j]
    idpart[j] = c // 24
    c %= 24
  productkey = charStore[c] + productkey
  lastC = c
if isWin8:
  insert = "N"
  if lastC == 0:
    productkey = insert + productkey
  else:
    keypart1 = productkey[1:1+lastC]
    productkey = productkey[1:].replace(keypart1, keypart1 + insert)

print('-'.join([productkey[i * 5:i * 5 + 5] for i in range(5)]))

相关内容