Base24 Algorithmus decodieren mit Batch?
Hallo,
wie der Titel schon sagt habe ich ein Verständnissproblem mit dem Base24 Algorithmus.
Ziel ist es, mit reinem Batch, den Microsoft Product Key zu decodieren.
Es gibt schon genügend Programme die das machen und auch Codes in Powershell und VBScript.
Hier mal ein Beispiel in VBScript:
Leider verstehe ich die Funktion nicht und würde mich freuen wenn mir die jemand etwas genauer erklären könnte.
Kenne mich mit VBScript noch nicht aus. (Kämpfe noch mit Batch )
Auf Wunsch kann ich noch ein alternatives VBScript und ein Powershell Script posten wenn das weiter hilft.
So siehts in Batch bis jetzt aus um den Key aus der Registry zu lesen :
Danke
wie der Titel schon sagt habe ich ein Verständnissproblem mit dem Base24 Algorithmus.
Ziel ist es, mit reinem Batch, den Microsoft Product Key zu decodieren.
Es gibt schon genügend Programme die das machen und auch Codes in Powershell und VBScript.
Hier mal ein Beispiel in VBScript:
Set WshShell = CreateObject("WScript.Shell")
msgbox ConvertToKey(WshShell.RegRead("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DigitalProductId")), 64, "Windows Product Key"
Function ConvertToKey(Key)
Const KeyOffset = 52
i = 28
Chars = "BCDFGHJKMPQRTVWXY2346789"
Do
Cur = 0
x = 14
Do
Cur = Cur * 256
Cur = Key(x + KeyOffset) + Cur
Key(x + KeyOffset) = (Cur \ 24) And 255
Cur = Cur Mod 24
x = x -1
Loop While x >= 0
i = i -1
KeyOutput = Mid(Chars, Cur + 1, 1) & KeyOutput
If (((29 - i) Mod 6) = 0) And (i <> -1) Then
i = i -1
KeyOutput = "-" & KeyOutput
End If
Loop While i >= 0
ConvertToKey = KeyOutput
End Function
Leider verstehe ich die Funktion nicht und würde mich freuen wenn mir die jemand etwas genauer erklären könnte.
Kenne mich mit VBScript noch nicht aus. (Kämpfe noch mit Batch )
Auf Wunsch kann ich noch ein alternatives VBScript und ein Powershell Script posten wenn das weiter hilft.
So siehts in Batch bis jetzt aus um den Key aus der Registry zu lesen :
for /f "tokens=3 delims= " %%a in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v DigitalProductId') do set keyhex=%%a
set keyhex=%keyhex:~104,30%
Danke
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 178418
Url: https://administrator.de/forum/base24-algorithmus-decodieren-mit-batch-178418.html
Ausgedruckt am: 27.01.2025 um 04:01 Uhr
15 Kommentare
Neuester Kommentar
moin sinsizer,
meiner Ansicht nach hat es gar keinen Sinn den Algorithmus aus einer VBS 1:1 in eine Batch zu übertragen.
Das auslesen des Keys erfolgt ja auf eine Art wie es in "Base24" (wobei die 24 nur die Anzahl der zu verwendeten Zeichen beschreibt) gemacht wird. In den Dokumentationen über "Base16"; "Base 32"; "Base 32hex" oder "Base 64" etc. wird die genaue Vorgehensweise beschrieben.
Rechnen in Batch ist auch schon etwas anders als in VBS.
Auf jeden Fall musst Du erst den Base... Algorithmus kennen um den Batch entwerfen zu können.
Gruß Phil
meiner Ansicht nach hat es gar keinen Sinn den Algorithmus aus einer VBS 1:1 in eine Batch zu übertragen.
Das auslesen des Keys erfolgt ja auf eine Art wie es in "Base24" (wobei die 24 nur die Anzahl der zu verwendeten Zeichen beschreibt) gemacht wird. In den Dokumentationen über "Base16"; "Base 32"; "Base 32hex" oder "Base 64" etc. wird die genaue Vorgehensweise beschrieben.
Rechnen in Batch ist auch schon etwas anders als in VBS.
Auf jeden Fall musst Du erst den Base... Algorithmus kennen um den Batch entwerfen zu können.
Gruß Phil
Hallo zusammen.
Ich habe mich zwar nie mit einem Base24 Algorithmus oder Ähnlichem beschäftig, die "Übersetzung" nach Batch ist aber relativ simpel. Vielleicht hilft es beim Verständnis.
Grüße
rubberman
Ich habe mich zwar nie mit einem Base24 Algorithmus oder Ähnlichem beschäftig, die "Übersetzung" nach Batch ist aber relativ simpel. Vielleicht hilft es beim Verständnis.
@echo off &setlocal
if "%~1"==":doWhile" call :doWhile
setlocal EnableDelayedExpansion
:: HEX String lesen
for /f "tokens=3" %%i in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v "DigitalProductId"') do set "hex=%%i"
:: Länge des HEX Strings
set "str=A%hex%"
set "len=0"
for /l %%i in (12,-1,0) do (
set /a "len |= 1 << %%i"
for %%j in (!len!) do if "!str:~%%j,1!"=="" set /a "len &= ~1 << %%i"
)
:: Pseudo-Array anlegen
set /a "len -= 2"
for /l %%i in (0,2,%len%) do (
set /a "n = %%i / 2"
set /a "Key_!n! = 0x!hex:~%%i,2!"
)
:: Do While simulieren
for /f %%K in ('cmd /c "%~f0" :doWhile') do (endlocal &set "WinProdKey=%%K")
echo Windows Product Key: %WinProdKey%
echo(
pause
goto :eof
:doWhile
setlocal EnableDelayedExpansion
set "KeyOffset=52"
set "Chars=BCDFGHJKMPQRTVWXY2346789"
set "i=28"
for /l %%# in (0) do (
set "Cur=0"
for /l %%x in (14,-1,0) do (
set /a "Cur *= 256 , el = KeyOffset + %%x"
for %%j in (!el!) do (
set /a "Cur = !Key_%%j! + Cur , Key_%%j = (Cur / 24) & 255 , Cur %%= 24"
)
)
set /a "i -= 1 , z = (29 - i) %% 6"
for %%j in (!Cur!) do set "KeyOutput=!Chars:~%%j,1!!KeyOutput!"
if !z!==0 if !i! neq -1 (
set /a "i -= 1"
set "KeyOutput=-!KeyOutput!"
)
if !i! lss 0 (echo !KeyOutput!&exit)
)
Grüße
rubberman
Hallo @all!
Der Vollständigkeit halber noch eine etwas vereinfachte VBS-Version:
Gruß Dieter
[edit] Codezeile 12 geändert (XOR durch + ersetzt) [/edit]
Der Vollständigkeit halber noch eine etwas vereinfachte VBS-Version:
Const sKeyChar = "BCDFGHJKMPQRTVWXY2346789"
Const sRegKey = "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DigitalProductId"
MsgBox GetProductKey(CreateObject("WScript.Shell").RegRead(sRegKey)), 64, "Windows Product Key"
Function GetProductKey(ByRef aRegValue)
Dim sProductKey, b, c, i
For b = 24 To 0 Step -1
c = 0
For i = 66 To 52 Step -1
c = c * 256 + aRegValue(i)
aRegValue(i) = CByte(c \ 24)
c = c Mod 24
Next
sProductKey = Mid(sKeyChar, c + 1, 1) & sProductKey
If b And b Mod 5 = 0 Then sProductKey = "-" & sProductKey
Next
GetProductKey = sProductKey
End Function
Gruß Dieter
[edit] Codezeile 12 geändert (XOR durch + ersetzt) [/edit]
Hallo Zusammen.
@Dieter,
nachdem ich vorher nur stupide VBS zu Batch konvertiert habe, ist mir die Funktionsweise dank deines Scripts nun auch klar.
@sinsizer,
Cur (bzw. c) bezeichnet die Position des Zeichens im String BCDFGHJKMPQRTVWXY2346789. Der Wert der Variablen startet zwar mit 0, wird aber sofort in der inneren Schleife neu berechnet.
Dieters VBS 2 Batch:
Grüße
rubberman
@Dieter,
nachdem ich vorher nur stupide VBS zu Batch konvertiert habe, ist mir die Funktionsweise dank deines Scripts nun auch klar.
@sinsizer,
Cur (bzw. c) bezeichnet die Position des Zeichens im String BCDFGHJKMPQRTVWXY2346789. Der Wert der Variablen startet zwar mit 0, wird aber sofort in der inneren Schleife neu berechnet.
Dieters VBS 2 Batch:
@echo off &setlocal
call :GetProductKey sWinProdKey
echo Windows Product Key: %sWinProdKey%
echo(
pause
goto :eof
:GetProductKey outVarName
setlocal EnableDelayedExpansion
set "sKeyChar=BCDFGHJKMPQRTVWXY2346789"
set "sRegKey=HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
set "sRegVal=DigitalProductId"
for /f "tokens=3" %%i in ('reg query "%sRegKey%" /v "%sRegVal%"') do set "sHex=%%i"
set /a "n = 52"
for /l %%i in (104,2,132) do set /a "aRegValue_!n! = 0x!sHex:~%%i,2! , n += 1"
for /l %%b in (24,-1,0) do (
set /a "c = 0 , n = %%b %% 5"
for /l %%i in (66,-1,52) do set /a "c = c * 256 ^^ !aRegValue_%%i! , aRegValue_%%i = c / 24 , c %%= 24"
for %%j in (!c!) do set "sProductKey=!sKeyChar:~%%j,1!!sProductKey!"
if %%b neq 0 if !n!==0 set "sProductKey=-!sProductKey!"
)
endlocal &set "%~1=%sProductKey%" &goto :eof
Grüße
rubberman
Hallo sinsizer!
Na dann, versuche ich es mal zu erklären
Schleife entsprechend der Anzahl Charakter im Produkt-Key (25-Zeichen)
Position im String "BCDFGHJKMPQRTVWXY2346789" pro Produkt-Key-Zeichen auf 0 setzen
Schleife entsprechend der Positonen von den auszulesenden 15 Byte-Werten aus dem Reg-Byte-Array (164 Byte)
Den aktuellen Wert in c (c * 256) auf ein WORD (16-Bit) erweitern sprich in's High-Byte (Bit 8-15) schieben + Low-Byte (Bit 0-7) aus dem Reg-Byte-Array
Beispiel:
Position (i) = 66 und c enthält den Startwert 0:
c = 0 und Wert im Reg-Byte-Array an Position 66 = 5:
c = 0 * 256 (0000 hex) + 5 ergibt 5 (0005 hex)
aRegValue(66) = Ganzahl 5 / 24 (aRegValue(i) = CByte(c \ 24)) ergibt 0 (00 hex)
Position (i) = 65 und c enthält aktuell von Position 66 den Restwert aus 5 / 24 (c = c Mod 24):
c = 5 und Wert im Reg-Byte-Array an Position 65 = 60:
c = 5 * 256 (0500hex) + 60 (003C hex) ergibt 1340 (053C hex)
aRegValue(65) = Ganzahl 1340 / 24 (aRegValue(i) = CByte(c \ 24)) ergibt 55 (37 hex)
Position (i) = 64 und c enthält aktuell von Position 65 den Restwert aus 20 / 24 (c = c Mod 24):
c = 20 und Wert im Reg-Byte-Array an Position 64 = 147:
c = 20 * 256 (1400hex) + 147 (0093 hex) ergibt 5267 (1493 hex)
aRegValue(64) = Ganzahl 5267 / 24 (aRegValue(i) = CByte(c \ 24)) ergibt 219 (DB hex)
...........
Hoffe, ich hab's einigermaßen verständlich erklärt?
@rubberman
Gruß Dieter
PS. Codezeile 12 geändert:
XOR durch (+) ersetzt
Na dann, versuche ich es mal zu erklären
For b = 24 To 0 Step -1 |
c = 0 |
For i = 66 To 52 Step -1 |
c = c * 256 + aRegValue(i) |
aRegValue(i) = CByte(c \ 24) |
c = c Mod 24 |
for /l %%i in (66,-1,52) do set /a "c = c * 256 ^^ !aRegValue_%%i! , aRegValue_%%i = c / 24 , c %%= 24" |
Beispiel:
Position (i) = 66 und c enthält den Startwert 0:
c = 0 und Wert im Reg-Byte-Array an Position 66 = 5:
c = 0 * 256 (0000 hex) + 5 ergibt 5 (0005 hex)
aRegValue(66) = Ganzahl 5 / 24 (aRegValue(i) = CByte(c \ 24)) ergibt 0 (00 hex)
Position (i) = 65 und c enthält aktuell von Position 66 den Restwert aus 5 / 24 (c = c Mod 24):
c = 5 und Wert im Reg-Byte-Array an Position 65 = 60:
c = 5 * 256 (0500hex) + 60 (003C hex) ergibt 1340 (053C hex)
aRegValue(65) = Ganzahl 1340 / 24 (aRegValue(i) = CByte(c \ 24)) ergibt 55 (37 hex)
Position (i) = 64 und c enthält aktuell von Position 65 den Restwert aus 20 / 24 (c = c Mod 24):
c = 20 und Wert im Reg-Byte-Array an Position 64 = 147:
c = 20 * 256 (1400hex) + 147 (0093 hex) ergibt 5267 (1493 hex)
aRegValue(64) = Ganzahl 5267 / 24 (aRegValue(i) = CByte(c \ 24)) ergibt 219 (DB hex)
...........
Hoffe, ich hab's einigermaßen verständlich erklärt?
@rubberman
@Dieter,
nachdem ich vorher nur stupide VBS zu Batch konvertiert habe, ist mir die Funktionsweise dank deines Scripts nun auch klar.
Freut mich zu hören und der Erfolg läßt sich nun ja auch an der Kürze des neuen Batch-Scripts erkennennachdem ich vorher nur stupide VBS zu Batch konvertiert habe, ist mir die Funktionsweise dank deines Scripts nun auch klar.
Gruß Dieter
PS. Codezeile 12 geändert:
c = c * 256 + aRegValue(i) |
Hallo sinsizer.
Vielleicht wird es einfacher, wenn du dir die binären Entsprechungen ansiehst.
Ein Byte hat eine Breite von 8 Bit. Das WORD hat eine Breite von 2 Byte = 16 Bit. Das linke Byte wird High-Byte genannt, das rechte Low-Byte.
Nehmen wir noch einmal das Beispiel von Dieter:
c = 5 * 256 (0500hex) + 60 (003C hex) ergibt 1340 (053C hex)
Statt der Multiplikation mit 256 könntest du auch ein Left-Shift um 8 Bit anwenden:
Was nun den Unterschied zwischen Addition und XOR ausmacht ist einfach erklärt: Es sind 2 völlig unterschiedliche Operationen, die allerdings in diesem Fall exakt das gleiche Ergebnis liefern.
Die Addition muss ich sicher nicht erklären. Zum XOR:
Da alle Bits des Low-Bytes nach der Multiplikation mit 256 den Wert 0 haben, ist klar dass die Bits nach der XOR Operation nur dann den Wert 1 haben, wenn der 2. Operand an dieser Stelle 1 ist.
Grüße
rubberman
Vielleicht wird es einfacher, wenn du dir die binären Entsprechungen ansiehst.
Ein Byte hat eine Breite von 8 Bit. Das WORD hat eine Breite von 2 Byte = 16 Bit. Das linke Byte wird High-Byte genannt, das rechte Low-Byte.
Nehmen wir noch einmal das Beispiel von Dieter:
c = 5 * 256 (0500hex) + 60 (003C hex) ergibt 1340 (053C hex)
High-Byte Low-Byte
5 00000000 00000101
* 256 00000101 00000000
+ 60 00000101 00111100
Statt der Multiplikation mit 256 könntest du auch ein Left-Shift um 8 Bit anwenden:
5 00000000 00000101
<< 8 00000101 00000000
Was nun den Unterschied zwischen Addition und XOR ausmacht ist einfach erklärt: Es sind 2 völlig unterschiedliche Operationen, die allerdings in diesem Fall exakt das gleiche Ergebnis liefern.
Die Addition muss ich sicher nicht erklären. Zum XOR:
0 XOR 0 = 0
1 XOR 0 = 1
0 XOR 1 = 1
1 XOR 1 = 0
Da alle Bits des Low-Bytes nach der Multiplikation mit 256 den Wert 0 haben, ist klar dass die Bits nach der XOR Operation nur dann den Wert 1 haben, wenn der 2. Operand an dieser Stelle 1 ist.
Grüße
rubberman
Hallo rubberman!
Das hast Du sehr schön erklärt
Gruß Dieter
Das hast Du sehr schön erklärt
Gruß Dieter
Hallo sinsizer,
kommt darauf an was du damit vorhast. Die Breite von 16 Bit wird zur Dekodierung gebraucht. Das heist, dieser Algorithmus verlangt es so. Wenn du ein Array Byte für Byte abarbeitest, reicht die Breite von 2 Byte in diesem Fall. Kreierst du deinen eigenen Kodierungs-/Dekodierungsalgorithmus, kann das anders sein.
Deine Frage lässt sich also nicht so einfach mit Ja oder Nein beantworten.
Grüße
rubberman
<EDIT: @Dieter - Danke für die Blumen />
kommt darauf an was du damit vorhast. Die Breite von 16 Bit wird zur Dekodierung gebraucht. Das heist, dieser Algorithmus verlangt es so. Wenn du ein Array Byte für Byte abarbeitest, reicht die Breite von 2 Byte in diesem Fall. Kreierst du deinen eigenen Kodierungs-/Dekodierungsalgorithmus, kann das anders sein.
Deine Frage lässt sich also nicht so einfach mit Ja oder Nein beantworten.
Grüße
rubberman
<EDIT: @Dieter - Danke für die Blumen />
Hallo sinsizer!
Ergänzend noch die Grenzwerte der Bases für die Byte-Decodierung:
Gruß Dieter
Dieser Algorithmus verlangt eine byteweise Abarbeitung. Davon abgesehen ist sie sinnvoll. Mit einer Breite von 4 Byte
wärst du bereits an der Grenze angelangt, die die Kommandozeile noch als Zahl interpretieren kann.
Mal davon abgesehen, werden die Bytes im RegValue-Array für jeden Buchstaben neu geschrieben, also 25 mal alle 15 Bytes verändertwärst du bereits an der Grenze angelangt, die die Kommandozeile noch als Zahl interpretieren kann.
Ergänzend noch die Grenzwerte der Bases für die Byte-Decodierung:
Base | Formel | Binär | Dez | Hex | Anzahl Bits | |||
16 | 15 * 256 + 255 | 0000 1111 1111 1111 | 4095 | 0FFF | 12 | |||
24 | 23 * 256 + 255 | 0001 0111 1111 1111 | 6143 | 17FF | 13 | |||
32 | 31 * 256 + 255 | 0001 1111 1111 1111 | 8191 | 1FFF | 13 | |||
64 | 63 * 256 + 255 | 0011 1111 1111 1111 | 16383 | 3FFF | 14 | |||
128 | 127 * 256 + 255 | 0111 1111 1111 1111 | 32767 | 7FFF | 15 |
Gruß Dieter