11

Я случайно отключил жесткий диск, когда он еще работал, и повредил установку Windows 7; Теперь я полностью не могу загрузиться в Windows. Я перепробовал все, чтобы попытаться восстановить установку: Восстановление при загрузке Windows, chkdsk /r, SFC /scannow, bootrec /rebuildbcd и т.д., И не повезло. Я хочу просто выполнить новую установку, но моя проблема в том, что у меня нигде не записан ключ продукта Windows, и я не могу использовать какие-либо сценарии или утилиты для его извлечения из реестра, потому что не могу загрузиться в Windows.

Ключи продуктов Windows 7 хранятся в зашифрованном виде в значении "DigitalProductId" раздела реестра HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion. Мне удалось смонтировать поврежденный раздел Windows, доступный только для чтения, с живого компакт-диска Ubuntu и скопировать куст реестра Windows\System32\config\SOFTWARE, который содержит соответствующий ключ и значение, на флэш-диск, но загрузить этот куст в regedit. при работающей установке Windows, а затем при попытке использовать сценарии или утилиты для расшифровки загруженного значения "DigitalProductId" возвращается только ключ продукта установки хоста Windows, независимо от того, сколько я пытаюсь поиграться. Я пытался связаться со службой поддержки Microsoft, и они были довольно бесполезны. Кто-нибудь сможет направить меня дальше? Возможно, есть ли другой способ получить ключ продукта из Linux?

Если кто-то, более знакомый со сценариями / криптографией, захочет попробовать выполнить расшифровку ключа продукта вручную, следуя сценарию дешифрования, я могу отправить вам по электронной почте экспортированное значение "DigitalProductId", куст реестра ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ и сценарий дешифрования.

3 ответа3

20

Для 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
3

Для тех, кто не стесняется сделать немного кодирования.

Я нашел алгоритм около 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 Products использовала тот же алгоритм, поэтому, предоставляя функцию с соответствующим ключом реестра, она также могла рассчитывать эти ключи продукта.

Вы, конечно, можете реорганизовать функцию так, чтобы она принимала байтовый массив в качестве входных данных.

На сегодня. Я только что проверил его на своей машине с Windows 10, и он все еще работает.

2

Вот порт 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)]))

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .