Что нового

Получение ProductKey Windows и Office

k790

Новичок
Сообщения
239
Репутация
1
Здравствуйте, какой командой можно получить Product Key windows из реестра?
Имеется скрипт на vbs:
Код:
Set WshShell = WScript.CreateObject("WScript.Shell")
strDigitalProductId="HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DigitalProductId"
'strOffXP="HKLM\SOFTWARE\Microsoft\Office\10.0\Registration\{91110419-6000-11D3-8CFE-0050048383C9}\DigitalProductId"
'strOffXP="HKLM\SOFTWARE\Microsoft\Office\10.0\Registration\{90280409-6000-11D3-8CFE-0050048383C9}\DigitalProductId"
'strOffXP="HKLM\SOFTWARE\Microsoft\Office\11.0\Registration\{90170409-6000-11D3-8CFE-0150048383C9}\DigitalProductId"
'strOffXP="HKLM\SOFTWARE\Microsoft\Office\11.0\Registration\{90110419-6000-11D3-8CFE-0150048383C9}\DigitalProductId"
CRLF = Chr(13) & Chr(10)
strXPKey=GetKey(WshShell.RegRead(strDigitalProductId))
MsgBox "WinXP:" & strXPKey
'strOffXPKey=GetKey(WshShell.RegRead(strOffXP))
'CopytoClipboard
set ie=CreateObject("internetExplorer.application")
ie.navigate "about:blank"
do until ie.readystate=4: wscript.sleep 1: loop
ie.document.parentwindow.clipboardData.setData "Text", strXPKey
MsgBox "WinXP:" & strXPKey & chr(13) & "key in clipboard" & CRLF ''''''''''''''''''& "OffXP:" & strOffXPKey
Function GetKey(rpk)
Const rpkOffset=52:i=28
szPossibleChars="BCDFGHJKMPQRTVWXY2346789"
Do 'Rep1
dwAccumulator=0 : j=14
Do
dwAccumulator=dwAccumulator*256
dwAccumulator=rpk(j+rpkOffset)+dwAccumulator
rpk(j+rpkOffset)=(dwAccumulator\24) and 255
dwAccumulator=dwAccumulator Mod 24
j=j-1
Loop While j>=0
i=i-1 : szProductKey=mid(szPossibleChars,dwAccumulator+1,1)&szProductKey
if (((29-i) Mod 6)=0) and (i<>-1) then
i=i-1 : szProductKey="-"&szProductKey
End If
Loop While i>=0 'Goto Rep1
GetKey=szProductKey
End Function
Вот хочу его перевести на AutoIt.

Желаю понять как работает, поэтому и пишу в этот раздел.

Где можно найти rpk для autoit ?
 

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Код:
MsgBox(0, '', RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion", "ProductId"))


В WinXP
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Как то так:

Код:
$WshShell = ObjCreate("WScript.Shell")

$strDigitalProductId = "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DigitalProductId"
;strOffXP="HKLM\SOFTWARE\Microsoft\Office\10.0\Registration\{91110419-6000-11D3-8CFE-0050048383C9}\DigitalProductId"
;strOffXP="HKLM\SOFTWARE\Microsoft\Office\10.0\Registration\{90280409-6000-11D3-8CFE-0050048383C9}\DigitalProductId"
;strOffXP="HKLM\SOFTWARE\Microsoft\Office\11.0\Registration\{90170409-6000-11D3-8CFE-0150048383C9}\DigitalProductId"
;strOffXP="HKLM\SOFTWARE\Microsoft\Office\11.0\Registration\{90110419-6000-11D3-8CFE-0150048383C9}\DigitalProductId"

$strXPKey = $WshShell.RegRead($strDigitalProductId)
MsgBox(0, "", "WinXP: " & GetKey($strXPKey))

;~ ClipPut($strXPKey)

Func GetKey($rpk)
	Const $rpkOffset = 52
	Local $i = 28
	Local $szPossibleChars = "BCDFGHJKMPQRTVWXY2346789"
	Local $szProductKey
	
	While $i >= 0
		$dwAccumulator = 0
		$j = 14
		
		While $j >= 0
			$dwAccumulator *= 256
			$dwAccumulator = $rpk[$j + $rpkOffset] + $dwAccumulator
			$rpk[$j + $rpkOffset] = BitAND(($dwAccumulator / 24), 255)
			$dwAccumulator = Mod($dwAccumulator, 24)
			$j -= 1
		WEnd
		
		$i -= 1
		$szProductKey = StringMid($szPossibleChars, $dwAccumulator + 1, 1) & $szProductKey
		
		If ((Mod(29 - $i, 6)) = 0) And ($i <> -1) Then
			$i -= 1
			$szProductKey = "-" & $szProductKey
		EndIf
	WEnd
	
	Return $szProductKey
EndFunc


:stars:


Добавлено:
Сообщение автоматически объединено:

k790 [?]
Где можно найти rpk для autoit ?
rpk в данном скрипте это массив, хотя мне пока не понятно откуда он берётся...
 
Автор
K

k790

Новичок
Сообщения
239
Репутация
1
CreatoR
Спасибо, работает, но:
1) в самом начале есть 4 закомментированные строки, их можно удалять, так же понятно что эти ключи:
Код:
;strOffXP="HKLM\SOFTWARE\Microsoft\Office\10.0\Registration\{91110419-6000-11D3-8CFE-0050048383C9}\DigitalProductId"
;strOffXP="HKLM\SOFTWARE\Microsoft\Office\10.0\Registration\{90280409-6000-11D3-8CFE-0050048383C9}\DigitalProductId"
;strOffXP="HKLM\SOFTWARE\Microsoft\Office\11.0\Registration\{90170409-6000-11D3-8CFE-0150048383C9}\DigitalProductId"
;strOffXP="HKLM\SOFTWARE\Microsoft\Office\11.0\Registration\{90110419-6000-11D3-8CFE-0150048383C9}\DigitalProductId"

должны найти ключ от офиса, но не видит, почему??

2) каким образом переменная идёт в начале, а её значение ниже
Код:
MsgBox(0, "", "WinXP: " & GetKey($strXPKey)) ; это выводит ключ на экран
;~ ClipPut($strXPKey)

Func GetKey($rpk)
    Const $rpkOffset = 52
    Local $i = 28
    Local $szPossibleChars = "BCDFGHJKMPQRTVWXY2346789"
    Local $szProductKey
    
    While $i >= 0
        $dwAccumulator = 0
        $j = 14
        
        While $j >= 0
            $dwAccumulator *= 256
            $dwAccumulator = $rpk[$j + $rpkOffset] + $dwAccumulator
            $rpk[$j + $rpkOffset] = BitAND(($dwAccumulator / 24), 255)
            $dwAccumulator = Mod($dwAccumulator, 24)
            $j -= 1
        WEnd
        
        $i -= 1
        $szProductKey = StringMid($szPossibleChars, $dwAccumulator + 1, 1) & $szProductKey
        
        If ((Mod(29 - $i, 6)) = 0) And ($i <> -1) Then
            $i -= 1
            $szProductKey = "-" & $szProductKey
        EndIf
    WEnd
    
    Return $szProductKey
EndFunc   ; это получает GetKey


3) Как это можно перевести, то есть куда обращаться для справки, на что нужно смотреть при переводе из одного языка в другой?
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
CreatoR [?]
rpk в данном скрипте это массив, хотя мне пока не понятно откуда он берётся.
Похоже, что так.
Код:
;#include <Array.au3>
$bKey = RegRead('HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion', 'DigitalProductId')

$aKey = StringRegExp(Hex($bKey), '.{2}', 3)

For $i = 0 To UBound($aKey) - 1
	$aKey[$i] = Dec($aKey[$i])
Next
;_ArrayDisplay($aKey)
MsgBox(64, 'Info', GetKey($aKey))
Func GetKey($rpk)
	Const $rpkOffset = 52
	Local $i = 28
	Local $szPossibleChars = "BCDFGHJKMPQRTVWXY2346789"
	Local $szProductKey

	While $i >= 0
		$dwAccumulator = 0
		$j = 14

		While $j >= 0
			$dwAccumulator *= 256
			$dwAccumulator = $rpk[$j + $rpkOffset] + $dwAccumulator
			$rpk[$j + $rpkOffset] = BitAND(($dwAccumulator / 24), 255)
			$dwAccumulator = Mod($dwAccumulator, 24)
			$j -= 1
		WEnd

		$i -= 1
		$szProductKey = StringMid($szPossibleChars, $dwAccumulator + 1, 1) & $szProductKey

		If ((Mod(29 - $i, 6)) = 0) And ($i <> -1) Then
			$i -= 1
			$szProductKey = "-" & $szProductKey
		EndIf
	WEnd

	Return $szProductKey
EndFunc   ;==>GetKey
 
Автор
K

k790

Новичок
Сообщения
239
Репутация
1
Опять забыл уточнить, мне нужно получить только ключ windows


Добавлено:
Сообщение автоматически объединено:

Массив включать или нет:?
Код:
;#include <Array.au3>
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
У меня и так работает. Проверял на Windows XP x86, Windows 7 x86 x64. Другие Office не могу проверить. На Windows 7, наверное, нужны права администратора для этой ветки реестра.
Код:
Dim $aKeyName[2][2] = [['Windows Key:', 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion'], _
		['MS Office 2003 Key:', 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\11.0\Registration\{90110419-6000-11D3-8CFE-0150048383C9}']]
If StringInStr(@OSArch, '64') Then
	$aKeyName[1][1] = 'HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Office\11.0\Registration\{90110419-6000-11D3-8CFE-0150048383C9}'
EndIf
For $i = 0 To 1
	MsgBox(64, 'Info', $aKeyName[$i][0] & @TAB & _GetKey(RegRead($aKeyName[$i][1], 'DigitalProductId')))
Next

Func _GetKey($bKey)
	Local $szPossibleChars = 'BCDFGHJKMPQRTVWXY2346789', $szProductKey, $dwAccumulator, _
			$a_rpk = StringRegExp(Hex(BinaryMid($bKey, 53, 15)), '.{2}', 3)
	If UBound($a_rpk) <> 15 Then Return SetError(1, 0, '')
	For $i = 0 To 14
		$a_rpk[$i] = Dec($a_rpk[$i])
	Next
	For $i = 1 To 25
		$dwAccumulator = 0
		For $j = 14 To 0 Step -1
			$dwAccumulator *= 256
			$dwAccumulator += $a_rpk[$j]
			$a_rpk[$j] = BitAND(($dwAccumulator / 24), 255)
			$dwAccumulator = Mod($dwAccumulator, 24)
		Next
		$szProductKey = StringMid($szPossibleChars, $dwAccumulator + 1, 1) & $szProductKey
	Next
	Return StringRegExpReplace($szProductKey, '(?<=.)(?=(.{5})+\z)', '-')
EndFunc   ;==>_GetKey



Добавлено:
Сообщение автоматически объединено:

k790 [?]
Опять забыл уточнить, мне нужно получить только ключ windows
Только Windows:
Код:
MsgBox(64, 'Info', 'Windows Key:' & @TAB & _GetKeyWindows())

Func _GetKeyWindows()
	Local $szPossibleChars = 'BCDFGHJKMPQRTVWXY2346789', $szProductKey, $dwAccumulator, _
			$b_Key = RegRead('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion', 'DigitalProductId'), _
			$a_rpk = StringRegExp(Hex(BinaryMid($b_Key, 53, 15)), '.{2}', 3)
	If UBound($a_rpk) <> 15 Then Return SetError(1, 0, '')
	For $i = 0 To 14
		$a_rpk[$i] = Dec($a_rpk[$i])
	Next
	For $i = 1 To 25
		$dwAccumulator = 0
		For $j = 14 To 0 Step -1
			$dwAccumulator *= 256
			$dwAccumulator += $a_rpk[$j]
			$a_rpk[$j] = BitAND(($dwAccumulator / 24), 255)
			$dwAccumulator = Mod($dwAccumulator, 24)
		Next
		$szProductKey = StringMid($szPossibleChars, $dwAccumulator + 1, 1) & $szProductKey
	Next
	Return StringRegExpReplace($szProductKey, '(?<=.)(?=(.{5})+\z)', '-')
EndFunc   ;==>_GetKeyWindows
 
Автор
K

k790

Новичок
Сообщения
239
Репутация
1
Что-то я перестал понимать.

Как упростить и получить только ключ для windows (без офиса).

А то столько рабочих вариантов и не один не понятный
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
k790
последний вариант от madmasles
прямо над твоим сообщением. упростить - куда еще. ведь ключ, как я понял из реестра, в двоичном коде..неизбежна функция, которая расшифровывает.
 
Автор
K

k790

Новичок
Сообщения
239
Репутация
1
А у кого-нибудь будет желание мне объяснить расшифровку?
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
madmasles
Можно пояснения, что вы сделали с кодом? :laugh:
Я никак врубиться не могу, в чём принцип массива :scratch:.


Добавлено:
Сообщение автоматически объединено:

Вот как можно улучшить получение ключей для office (попытка определения ключа для любой установленной(!) версии):

Код:
$sRegKey = 'HKLM\SOFTWARE'

If StringInStr(@OSArch, '64') Then
    $sRegKey &= '\Wow6432Node'
EndIf

$aKeys = _RegGetWinAndOfficeRegKeys($sRegKey)

For $i = 1 To UBound($aKeys)-1
	MsgBox(64, 'ProductKey Info', $aKeys[$i][0] & @CRLF & _RegGetProductKey($aKeys[$i][1]))
Next

Func _RegGetWinAndOfficeRegKeys($sRegKey)
	Local $sKey, $sSubKey
	Local $sOfficeRegKey = $sRegKey & '\Microsoft\Office'
	Local $sWinRegKey = $sRegKey & '\Microsoft\Windows NT\CurrentVersion'
	Local $aRet[2][2] = [[1], ['Microsoft Windows:', $sWinRegKey]]
	
	;Enum office versions
	For $i = 1 To 15
		$sKey = RegEnumKey($sOfficeRegKey, $i)
		If @error <> 0 Then ExitLoop
		
		If StringRegExp($sKey, '^((\d+\.?\d*)+)$') Then
			;Enum office GUIDs
			For $j = 1 To 10
				$sSubKey = RegEnumKey($sOfficeRegKey & '\' & $sKey & '\Registration', $j)
				If @error <> 0 Then ExitLoop
				
				If StringRegExp($sSubKey, '^{.*}$') Then
					$aRet[0][0] +=1
					ReDim $aRet[$aRet[0][0] + 1][2]
					$aRet[$aRet[0][0]][0] = RegRead($sOfficeRegKey & '\' & $sKey & '\Registration\' & $sSubKey, 'ProductName') & ':'
					$aRet[$aRet[0][0]][1] = $sOfficeRegKey & '\' & $sKey & '\Registration\' & $sSubKey
				EndIf
			Next
		EndIf
	Next
	
	Return $aRet
EndFunc

Func _RegGetProductKey($sRegKey)
	Local $bKey = RegRead($sRegKey, 'DigitalProductId')
    Local $szPossibleChars = 'BCDFGHJKMPQRTVWXY2346789', $szProductKey, $dwAccumulator
	Local $a_rpk = StringRegExp(Hex(BinaryMid($bKey, 53, 15)), '.{2}', 3)
    
	If @error Or UBound($a_rpk) < 15 Then
		Return SetError(1, 0, '')
	EndIf
	
    For $i = 0 To 14
        $a_rpk[$i] = Dec($a_rpk[$i])
    Next
	
    For $i = 1 To 25
        $dwAccumulator = 0
		
        For $j = 14 To 0 Step -1
            $dwAccumulator *= 256
            $dwAccumulator += $a_rpk[$j]
			
            $a_rpk[$j] = BitAND(($dwAccumulator / 24), 255)
            $dwAccumulator = Mod($dwAccumulator, 24)
        Next
		
        $szProductKey = StringMid($szPossibleChars, $dwAccumulator + 1, 1) & $szProductKey
    Next
	
    Return StringRegExpReplace($szProductKey, '(?<=.)(?=(.{5})+\z)', '-')
EndFunc
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
CreatoR [?]
Я никак врубиться не могу, в чём принцип массива
Код:
#include <Array.au3>

$WshShell = ObjCreate('WScript.Shell')

$strDigitalProductId = 'HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DigitalProductId'
$strXPKey = $WshShell.RegRead($strDigitalProductId)
_ArrayDisplay($strXPKey, 'VBS')
;здесь в массиве Dec значения каждого байта
;для расшифровки нужны только элементы массива 52-66
;выковыриваем их:
$b_Key = RegRead('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion', 'DigitalProductId')
ConsoleWrite('1. ' & $b_Key & @LF)
$b_Key = BinaryMid($b_Key, 53, 15)
ConsoleWrite('2. ' & $b_Key & @LF)
$b_Key = Hex($b_Key)
ConsoleWrite('3. ' & $b_Key & @LF)
;преобразуем в массив
$a_rpk = StringRegExp($b_Key, '.{2}', 3)
_ArrayDisplay($a_rpk, 'HEX - AutoIt')
Dim $aTemp[16][2] = [['VBS', 'AutoIt']]
For $i = 0 To 14
	$aTemp[$i + 1][0] = $strXPKey[$i + 52]
	$aTemp[$i + 1][1] = Dec($a_rpk[$i])
Next
_ArrayDisplay($aTemp, 'Итог')

ИМХО, проверка размерности здесь лишняя
Код:
;...
 If @error Or UBound($a_rpk) < 15
;...
Мне сложно представить случай, в котором после
Код:
;...
$a_rpk = StringRegExp(Hex(BinaryMid($b_Key, 53, 15)), '.{2}', 3)
;...
В массиве не будет 15 элементов.
 
Автор
K

k790

Новичок
Сообщения
239
Репутация
1
madmasles
Но что мы этим получили? У меня вместо колюча - фигня какая-то

CreatoR
Спасибо за поиск ключей, но

УВАЖАЕМЫЕ программисты расскажите как, что и зачем, а то начинающий ламер не может понять, спасибо за внимание
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
k790 [?]
У меня вместо колюча - фигня какая-то
madmasles [?]
На Windows 7, наверное, нужны права администратора для этой ветки реестра.
расскажите как, что и зачем
Открываете справку и читаете про каждую функцию, которая используется.
 
Автор
K

k790

Новичок
Сообщения
239
Репутация
1
madmasles
У меня xp sp3 Home Edition. фигня - цифры, буквы реже, но из них никак не получается ключ для windows.
 
Автор
K

k790

Новичок
Сообщения
239
Репутация
1
madmasles [?]
Значит для нее другой алгоритм расшифровки нужен. У меня на Windows XP Professional SP3 все нормально.
я бы скрины прислал, но вдруг можно по ним узнать ключ ... :( :-[
 
Верх