properly decipher registry REG_BINARY with python 3 winreg?
trying to read the information of the subkey Render in the key "ComputerHKEY_USERSS-1-5-19SoftwareMicrosoftWindowsCurrentVersionAudioJournal".
windows makes changes to that registry REG_BINARY entry when switching audio output devices.
i've tried to decode with ascii, utf-8, cp1252 and iso-8859-15 and a couple others from this list. ascii and utf-8 seem to yield the most "readable" string but they still don't decode the full string.
import winreg
from codecs import decode
reg_hive = winreg.HKEY_USERS
main_key = r"S-1-5-19SoftwareMicrosoftWindowsCurrentVersionAudioJournal"
with winreg.ConnectRegistry(None, reg_hive) as hive:
with winreg.OpenKey(
hive, main_key, 0, winreg.KEY_READ) as target_key:
renderInfo = winreg.EnumValue(target_key, 2)
# print(renderInfo)
print(decode(renderInfo[1], "ascii", "ignore"))
it prints this:
SWDMMDEVAPI{0.0.0.00000000}.{01921bca-0488-492c-b0ac-c8a3f5e42f9d}S@SWDMMDEVAPI{0.0.0.00000000}.{93f5ee17-4bef-4b43-8507-e27271065e61} iW@
trying to decrypt those weird characters (close to "S@" and "iW@
", stackoverflow doesn't seem to be able to render them.) so i can make better sense of it all.
sofar my guesses are:
- "SWDMMDEVAPI" is a abbreviation for a registry path? MultiMediaDEviceApi? not sure about SWD
- {0.0.0.00000000} could be a time stamp? although seems weird with all zeros.
- {01921bca-0488-492c-b0ac-c8a3f5e42f9d} and {93f5ee17-4bef-4b43-8507-e27271065e61} are registry keys.
windows binary registry decode winreg
|
show 1 more comment
trying to read the information of the subkey Render in the key "ComputerHKEY_USERSS-1-5-19SoftwareMicrosoftWindowsCurrentVersionAudioJournal".
windows makes changes to that registry REG_BINARY entry when switching audio output devices.
i've tried to decode with ascii, utf-8, cp1252 and iso-8859-15 and a couple others from this list. ascii and utf-8 seem to yield the most "readable" string but they still don't decode the full string.
import winreg
from codecs import decode
reg_hive = winreg.HKEY_USERS
main_key = r"S-1-5-19SoftwareMicrosoftWindowsCurrentVersionAudioJournal"
with winreg.ConnectRegistry(None, reg_hive) as hive:
with winreg.OpenKey(
hive, main_key, 0, winreg.KEY_READ) as target_key:
renderInfo = winreg.EnumValue(target_key, 2)
# print(renderInfo)
print(decode(renderInfo[1], "ascii", "ignore"))
it prints this:
SWDMMDEVAPI{0.0.0.00000000}.{01921bca-0488-492c-b0ac-c8a3f5e42f9d}S@SWDMMDEVAPI{0.0.0.00000000}.{93f5ee17-4bef-4b43-8507-e27271065e61} iW@
trying to decrypt those weird characters (close to "S@" and "iW@
", stackoverflow doesn't seem to be able to render them.) so i can make better sense of it all.
sofar my guesses are:
- "SWDMMDEVAPI" is a abbreviation for a registry path? MultiMediaDEviceApi? not sure about SWD
- {0.0.0.00000000} could be a time stamp? although seems weird with all zeros.
- {01921bca-0488-492c-b0ac-c8a3f5e42f9d} and {93f5ee17-4bef-4b43-8507-e27271065e61} are registry keys.
windows binary registry decode winreg
Device manager —> Sound, video and game… —> <audio> controller —> Properties —> Details tab —> Property —> Bus relations (or Children). Also note this answer aboutMMDevAPI.dll
- how to enumerate audio device endpoints and get their device IDs.
– JosefZ
Jan 19 at 1:18
so the readable part is the info found in Bus relations but what about the encrypted part? this is what it looks like in my text editor since stackoverflow just ignores characters it doesn't know: ibb.co/6WvrtQ0 the link you posted is related to java, is python not able to decrypte the full string?
– theoka
Jan 19 at 12:54
The registry binary type is packed data. It may contain text, but may also have numeric data mixed in. You need to know the structure to unpack it.
– eryksun
Jan 19 at 17:59
FYI, theConnectRegistry
call serves no point when accessing the local registry. Also,HKEY_USERS
is not a hive. It's a predefined handle for the local registry key where user hives (e.g. ntuser.dat) are loaded by default, which is "RegistryUser". The predefined handles are a starting point, since the Windows registry API only uses NT handle-relative opens instead of exposing NT's root key in the object namespace "Registry". The system opens a real kernel handle for "RegistryUser" in place of the predefined handle, or an RPC handle if we're connected to a remote registry.
– eryksun
Jan 19 at 18:06
how do i know the data structure of a reg_binary befor i unpack it? i ended up at that key path with the help of process monitor. i already knew the key names that decrypted reg_binary returned (which turn out to be "Bus relations" in the device manager) and where to find them. what i'm actually hoping to get from the rest of the reg_binary thats still encrypted are the FriendlyNames related to those keys (but i could be completely wrong with that guess).
– theoka
Jan 19 at 20:43
|
show 1 more comment
trying to read the information of the subkey Render in the key "ComputerHKEY_USERSS-1-5-19SoftwareMicrosoftWindowsCurrentVersionAudioJournal".
windows makes changes to that registry REG_BINARY entry when switching audio output devices.
i've tried to decode with ascii, utf-8, cp1252 and iso-8859-15 and a couple others from this list. ascii and utf-8 seem to yield the most "readable" string but they still don't decode the full string.
import winreg
from codecs import decode
reg_hive = winreg.HKEY_USERS
main_key = r"S-1-5-19SoftwareMicrosoftWindowsCurrentVersionAudioJournal"
with winreg.ConnectRegistry(None, reg_hive) as hive:
with winreg.OpenKey(
hive, main_key, 0, winreg.KEY_READ) as target_key:
renderInfo = winreg.EnumValue(target_key, 2)
# print(renderInfo)
print(decode(renderInfo[1], "ascii", "ignore"))
it prints this:
SWDMMDEVAPI{0.0.0.00000000}.{01921bca-0488-492c-b0ac-c8a3f5e42f9d}S@SWDMMDEVAPI{0.0.0.00000000}.{93f5ee17-4bef-4b43-8507-e27271065e61} iW@
trying to decrypt those weird characters (close to "S@" and "iW@
", stackoverflow doesn't seem to be able to render them.) so i can make better sense of it all.
sofar my guesses are:
- "SWDMMDEVAPI" is a abbreviation for a registry path? MultiMediaDEviceApi? not sure about SWD
- {0.0.0.00000000} could be a time stamp? although seems weird with all zeros.
- {01921bca-0488-492c-b0ac-c8a3f5e42f9d} and {93f5ee17-4bef-4b43-8507-e27271065e61} are registry keys.
windows binary registry decode winreg
trying to read the information of the subkey Render in the key "ComputerHKEY_USERSS-1-5-19SoftwareMicrosoftWindowsCurrentVersionAudioJournal".
windows makes changes to that registry REG_BINARY entry when switching audio output devices.
i've tried to decode with ascii, utf-8, cp1252 and iso-8859-15 and a couple others from this list. ascii and utf-8 seem to yield the most "readable" string but they still don't decode the full string.
import winreg
from codecs import decode
reg_hive = winreg.HKEY_USERS
main_key = r"S-1-5-19SoftwareMicrosoftWindowsCurrentVersionAudioJournal"
with winreg.ConnectRegistry(None, reg_hive) as hive:
with winreg.OpenKey(
hive, main_key, 0, winreg.KEY_READ) as target_key:
renderInfo = winreg.EnumValue(target_key, 2)
# print(renderInfo)
print(decode(renderInfo[1], "ascii", "ignore"))
it prints this:
SWDMMDEVAPI{0.0.0.00000000}.{01921bca-0488-492c-b0ac-c8a3f5e42f9d}S@SWDMMDEVAPI{0.0.0.00000000}.{93f5ee17-4bef-4b43-8507-e27271065e61} iW@
trying to decrypt those weird characters (close to "S@" and "iW@
", stackoverflow doesn't seem to be able to render them.) so i can make better sense of it all.
sofar my guesses are:
- "SWDMMDEVAPI" is a abbreviation for a registry path? MultiMediaDEviceApi? not sure about SWD
- {0.0.0.00000000} could be a time stamp? although seems weird with all zeros.
- {01921bca-0488-492c-b0ac-c8a3f5e42f9d} and {93f5ee17-4bef-4b43-8507-e27271065e61} are registry keys.
windows binary registry decode winreg
windows binary registry decode winreg
edited Jan 18 at 16:20
theoka
asked Jan 18 at 16:14
theokatheoka
12
12
Device manager —> Sound, video and game… —> <audio> controller —> Properties —> Details tab —> Property —> Bus relations (or Children). Also note this answer aboutMMDevAPI.dll
- how to enumerate audio device endpoints and get their device IDs.
– JosefZ
Jan 19 at 1:18
so the readable part is the info found in Bus relations but what about the encrypted part? this is what it looks like in my text editor since stackoverflow just ignores characters it doesn't know: ibb.co/6WvrtQ0 the link you posted is related to java, is python not able to decrypte the full string?
– theoka
Jan 19 at 12:54
The registry binary type is packed data. It may contain text, but may also have numeric data mixed in. You need to know the structure to unpack it.
– eryksun
Jan 19 at 17:59
FYI, theConnectRegistry
call serves no point when accessing the local registry. Also,HKEY_USERS
is not a hive. It's a predefined handle for the local registry key where user hives (e.g. ntuser.dat) are loaded by default, which is "RegistryUser". The predefined handles are a starting point, since the Windows registry API only uses NT handle-relative opens instead of exposing NT's root key in the object namespace "Registry". The system opens a real kernel handle for "RegistryUser" in place of the predefined handle, or an RPC handle if we're connected to a remote registry.
– eryksun
Jan 19 at 18:06
how do i know the data structure of a reg_binary befor i unpack it? i ended up at that key path with the help of process monitor. i already knew the key names that decrypted reg_binary returned (which turn out to be "Bus relations" in the device manager) and where to find them. what i'm actually hoping to get from the rest of the reg_binary thats still encrypted are the FriendlyNames related to those keys (but i could be completely wrong with that guess).
– theoka
Jan 19 at 20:43
|
show 1 more comment
Device manager —> Sound, video and game… —> <audio> controller —> Properties —> Details tab —> Property —> Bus relations (or Children). Also note this answer aboutMMDevAPI.dll
- how to enumerate audio device endpoints and get their device IDs.
– JosefZ
Jan 19 at 1:18
so the readable part is the info found in Bus relations but what about the encrypted part? this is what it looks like in my text editor since stackoverflow just ignores characters it doesn't know: ibb.co/6WvrtQ0 the link you posted is related to java, is python not able to decrypte the full string?
– theoka
Jan 19 at 12:54
The registry binary type is packed data. It may contain text, but may also have numeric data mixed in. You need to know the structure to unpack it.
– eryksun
Jan 19 at 17:59
FYI, theConnectRegistry
call serves no point when accessing the local registry. Also,HKEY_USERS
is not a hive. It's a predefined handle for the local registry key where user hives (e.g. ntuser.dat) are loaded by default, which is "RegistryUser". The predefined handles are a starting point, since the Windows registry API only uses NT handle-relative opens instead of exposing NT's root key in the object namespace "Registry". The system opens a real kernel handle for "RegistryUser" in place of the predefined handle, or an RPC handle if we're connected to a remote registry.
– eryksun
Jan 19 at 18:06
how do i know the data structure of a reg_binary befor i unpack it? i ended up at that key path with the help of process monitor. i already knew the key names that decrypted reg_binary returned (which turn out to be "Bus relations" in the device manager) and where to find them. what i'm actually hoping to get from the rest of the reg_binary thats still encrypted are the FriendlyNames related to those keys (but i could be completely wrong with that guess).
– theoka
Jan 19 at 20:43
Device manager —> Sound, video and game… —> <audio> controller —> Properties —> Details tab —> Property —> Bus relations (or Children). Also note this answer about
MMDevAPI.dll
- how to enumerate audio device endpoints and get their device IDs.– JosefZ
Jan 19 at 1:18
Device manager —> Sound, video and game… —> <audio> controller —> Properties —> Details tab —> Property —> Bus relations (or Children). Also note this answer about
MMDevAPI.dll
- how to enumerate audio device endpoints and get their device IDs.– JosefZ
Jan 19 at 1:18
so the readable part is the info found in Bus relations but what about the encrypted part? this is what it looks like in my text editor since stackoverflow just ignores characters it doesn't know: ibb.co/6WvrtQ0 the link you posted is related to java, is python not able to decrypte the full string?
– theoka
Jan 19 at 12:54
so the readable part is the info found in Bus relations but what about the encrypted part? this is what it looks like in my text editor since stackoverflow just ignores characters it doesn't know: ibb.co/6WvrtQ0 the link you posted is related to java, is python not able to decrypte the full string?
– theoka
Jan 19 at 12:54
The registry binary type is packed data. It may contain text, but may also have numeric data mixed in. You need to know the structure to unpack it.
– eryksun
Jan 19 at 17:59
The registry binary type is packed data. It may contain text, but may also have numeric data mixed in. You need to know the structure to unpack it.
– eryksun
Jan 19 at 17:59
FYI, the
ConnectRegistry
call serves no point when accessing the local registry. Also, HKEY_USERS
is not a hive. It's a predefined handle for the local registry key where user hives (e.g. ntuser.dat) are loaded by default, which is "RegistryUser". The predefined handles are a starting point, since the Windows registry API only uses NT handle-relative opens instead of exposing NT's root key in the object namespace "Registry". The system opens a real kernel handle for "RegistryUser" in place of the predefined handle, or an RPC handle if we're connected to a remote registry.– eryksun
Jan 19 at 18:06
FYI, the
ConnectRegistry
call serves no point when accessing the local registry. Also, HKEY_USERS
is not a hive. It's a predefined handle for the local registry key where user hives (e.g. ntuser.dat) are loaded by default, which is "RegistryUser". The predefined handles are a starting point, since the Windows registry API only uses NT handle-relative opens instead of exposing NT's root key in the object namespace "Registry". The system opens a real kernel handle for "RegistryUser" in place of the predefined handle, or an RPC handle if we're connected to a remote registry.– eryksun
Jan 19 at 18:06
how do i know the data structure of a reg_binary befor i unpack it? i ended up at that key path with the help of process monitor. i already knew the key names that decrypted reg_binary returned (which turn out to be "Bus relations" in the device manager) and where to find them. what i'm actually hoping to get from the rest of the reg_binary thats still encrypted are the FriendlyNames related to those keys (but i could be completely wrong with that guess).
– theoka
Jan 19 at 20:43
how do i know the data structure of a reg_binary befor i unpack it? i ended up at that key path with the help of process monitor. i already knew the key names that decrypted reg_binary returned (which turn out to be "Bus relations" in the device manager) and where to find them. what i'm actually hoping to get from the rest of the reg_binary thats still encrypted are the FriendlyNames related to those keys (but i could be completely wrong with that guess).
– theoka
Jan 19 at 20:43
|
show 1 more comment
1 Answer
1
active
oldest
votes
To decipher a complex binary value, you need to know it's structure. Let's start analyzing the following raw output:
reg query HKEY_USERSS-1-5-19SoftwareMicrosoftWindowsCurrentVersionAudioJournal -v Render
HKEY_USERSS-1-5-19SoftwareMicrosoftWindowsCurrentVersionAudioJournal
Render REG_BINARY 5300570044005C004D004D004400450056004100500049005C007B0030002E0030002E0030002E00300030003000300030003000300030007D002E007B00650033003700380063003900310035002D0064003000360039002D0034003900310066002D0038003000380039002D006200310030003600310039003000360061006100390034007D000000000000000000010000004B000000000000000000000000000000000000006A9A65709D075F400000000000000000000000000000000000000000000000005300570044005C004D004D004400450056004100500049005C007B0030002E0030002E0030002E00300030003000300030003000300030007D002E007B00340032003000620063006500650064002D0037003500370031002D0034003300350030002D0039003300610034002D003500650030006300310065003200350035003400660030007D0000000000000000000300000001000000000000000000000000000000000000004162F5AC588503400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
The following table shows above Render
registry entry structure (based on my own finding):
offset bytes caption format comment
------ ----- ------- ------ -------
0x0000 136 DeviceID char (68 chars; encoding UCS-2 LE)
0x0088 8 unknown_88 uint64
0x0090 4 EndPointNo uint32 (LE); constant for given end point
0x0094 4 Counter_94 uint32 (LE); increases if a sound is played
0x0098 8 unknown_98 uint64
0x00a0 8 unknown_a0 uint64
0x00a8 8 Strange_a8 uint64 changes unpredictably even for identical sound
0x00b0 8 unknown_b0 uint64
0x00b8 8 unknown_b8 uint64
0x00c0 8 unknown_c0 uint64
The above structure iterates three (or even more?) times within the Render
value. All the parts denominated unknown_*
constantly keep zero value so it's hard to guess their format and meaning, and don't change even if the system sounds (audio alerts) are forced to be shown visually (in the Ease of access settings).
Let's decrypt the Render
value - as soon as it's structure is at least partially known. In Python, use the struct
module (performs conversions between Python values and C structs represented as Python bytes objects).
Unfortunately, I don't speak Python fluently enough; so here is my Powershell solution:
#Requires -RunAsAdministrator
[CmdletBinding()]param(
[Parameter(Mandatory=$False,Position=0)][string]$PlaySound=''
)
if ( $PlaySound -eq '' ) {
Write-Information -infa Continue "Retrieving current values"
} else {
# play the file once
$soundLoc = "c:WINDOWSMedianotify.wav"
Write-Information -infa Continue "Playing $soundLoc"
$sound = new-Object System.Media.SoundPlayer
$sound.SoundLocation = $soundLoc
$sound.Play()
Start-Sleep -Seconds 1
}
$key = 'Registry::HKEY_USERSS-1-5-19SoftwareMicrosoftWindows' +
'CurrentVersionAudioJournal'
$keyItems = Get-ItemProperty -Path $key
$render = $keyItems.Render
$csvStruct=@"
offset,bytes,caption,format,comment
0x0000, 136,DeviceID,char,(68 chars; encoding UCS-2 LE)
0x0088, 8,unknown_88,uint64,
0x0090, 4,EndPointNo,uint32,(LE); constant for given end point
0x0094, 4,Counter_94,uint32,(LE); increases if a sound is played
0x0098, 8,unknown_98,uint64,
0x00a0, 8,unknown_a0,uint64,
0x00a8, 8,Strange_a8,uint64,changes unpredictably even for identical sound
0x00b0, 8,unknown_b0,uint64,
0x00b8, 8,unknown_b8,uint64,
0x00c0, 8,unknown_c0,uint64,
"@ | ConvertFrom-Csv
$unicode=[System.Text.UnicodeEncoding]::Unicode
$renderParts=@()
$renderInfos=@()
$renderNext = $renderCnt = 0
While ( $renderNext -lt $render.Count -and ( <# go over all value #>
$render[$renderNext + 0xaf] -ne 0 -or <# 0x40 if not zero #>
$render[$renderNext] -ne 0 )) { <# DeviceID not empty #>
for ($i=0; $i -lt $csvStruct.Count; $i++) {
$part = $csvStruct[$i]
If ( $part.format -eq 'char' ) {
$renderParts += @{
$part.caption = $unicode.GetString($render,
$renderNext + [int]$part.offset, [int]$part.bytes)
}
} else {
$hexLE='0x' # Little Endian
for ($j=[int]$part.bytes -1; $j -ge 0; $j--) {
$hexLE+= '{0:x2}' -f $render[$renderNext + [int]$part.offset + $j]
}
$hexBE='0X' # Big Endian
for ($j=0; $j -le [int]$part.bytes -1; $j++) {
$hexBE+= '{0:x2}' -f $render[$renderNext + [int]$part.offset + $j]
}
$hexBE = $hexBE.ToUpper()
$renderParts += @{
$part.caption = $hexLE
}
if ( $part.caption -eq 'Strange_a8') {
Write-Information $(
[System.Environment]::NewLine +
$renderParts[ $renderCnt ].DeviceID )
Write-Information $(
'EndPointNo = ' +
[int32]$renderParts[ 2 + $renderCnt ].EndPointNo +
', Counter_94 = ' +
[int32]$renderParts[ 3 + $renderCnt ].Counter_94 )
Write-Information $( "$($part.caption)`t`t$hexLE`t`t$hexBE" )
#Write-Information $(
# [System.Text.UnicodeEncoding]::Default.GetString($render,
# 0x00a8 + $renderNext, 8) )
Write-Information $(
'uint64 {0,20}' -f [uint64]$hexLE )
Write-Information $(
'uint32 {0,10} {1,10}' -f
[uint32]('0x' + $hexLE.Substring(10,8)),
[uint32]('0x' + $hexLE.Substring( 2,8)) )
Write-Information $(
' int16 {0,6} {1,6} {2,6} {3,6}' -f
[int16]('0x' + $hexLE.Substring(14,4)),
[int16]('0x' + $hexLE.Substring(10,4)),
[int16]('0x' + $hexLE.Substring( 6,4)),
[int16]('0x' + $hexLE.Substring( 2,4)) )
Write-Information $(
'uint16 {0,6} {1,6} {2,6} {3,6}' -f
[uint16]('0x' + $hexLE.Substring(14,4)),
[uint16]('0x' + $hexLE.Substring(10,4)),
[uint16]('0x' + $hexLE.Substring( 6,4)),
[uint16]('0x' + $hexLE.Substring( 2,4)) )
Write-Information $(
' byte {0,3} {1,3} {2,3} {3,3} {4,3} {5,3} {6,3} {7,3}' -f
[byte]('0x' + $hexLE.Substring(16,2)),
[byte]('0x' + $hexLE.Substring(14,2)),
[byte]('0x' + $hexLE.Substring(12,2)),
[byte]('0x' + $hexLE.Substring(10,2)),
[byte]('0x' + $hexLE.Substring( 8,2)),
[byte]('0x' + $hexLE.Substring( 6,2)),
[byte]('0x' + $hexLE.Substring( 4,2)),
[byte]('0x' + $hexLE.Substring( 2,2)) )
}
}
}
$renderNext+=200
$renderCnt +=10
}
$renderParts
Sample usage:
D:PShelltestsMMDEVAPI_Journal_Registry.ps1
retrieves currentRender
value.
D:PShelltestsMMDEVAPI_Journal_Registry.ps1 x
plays a system sound before retrieving theRender
value (added after theRender
value suddenly became zeroized for unknown reason).
D:PShelltestsMMDEVAPI_Journal_Registry.ps1 -InformationAction Continue
prints additional analysis of theStrange_a8
subvalue (shows it as structured in various numeric types).
Output (formatted by piping to Format-Table -Autosize
):
Name Value
---- -----
DeviceID SWDMMDEVAPI{0.0.0.00000000}.{e378c915-d069-491f-8089-b1061906aa94}
unknown_88 0x0000000000000000
EndPointNo 0x00000001
Counter_94 0x0000004a
unknown_98 0x0000000000000000
unknown_a0 0x0000000000000000
Strange_a8 0x405eb3c4b7ffda6f
unknown_b0 0x0000000000000000
unknown_b8 0x0000000000000000
unknown_c0 0x0000000000000000
DeviceID SWDMMDEVAPI{0.0.0.00000000}.{420bceed-7571-4350-93a4-5e0c1e2554f0}
unknown_88 0x0000000000000000
EndPointNo 0x00000003
Counter_94 0x00000001
unknown_98 0x0000000000000000
unknown_a0 0x0000000000000000
Strange_a8 0x40038558acf56241
unknown_b0 0x0000000000000000
unknown_b8 0x0000000000000000
unknown_c0 0x0000000000000000
Note. The EndPointNo
part seems to be related to the obscure registry key HKLMSOFTWAREMicrosoftWindowsCurrentVersionMMDevicesAudio
as shown in the following script:
$computer = $env:COMPUTERNAME
$namespace = "ROOTCIMV2"
$classname = "Win32_PnPEntity"
$auxPnP = Get-WmiObject -Class $classname `
-ComputerName $computer `
-Namespace $namespace |
Where-object PNPDeviceID -match `
'{[0-9a-fA-F].[0-9a-fA-F].[0-9a-fA-F].[0-9a-fA-F]{8}}' |
Select-Object * -ExcludeProperty PSComputerName,
Scope, Path, Options, ClassPath, Properties,
SystemProperties, Qualifiers, Site, Container
$auxPnP | Format-List -property Name,DeviceID <# -Property [a-z]* <##>
'--- DeviceId index ---'
$devIndex = '{1da5d803-d492-4edd-8c23-e0c0ffee7f0e},0'
$devDriver= '{b3f8fa53-0004-438e-9003-51a46e139bfc},6'
$devDevice= '{a45c254e-df1c-4efd-8020-67d146a850e0},2'
$keyAbove = 'Registry::HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows' +
'CurrentVersionMMDevicesAudio'
$keyTempl = $keyAbove + 'RenderDeviceIdEndingProperties'
$auxPnP | ForEach-Object {
$DeviceIdEnding = $_.DeviceID.Substring($_.DeviceID.LastIndexOf('.')+1)
$keyItems = Get-ItemProperty -ErrorAction SilentlyContinue `
-Path $keyTempl.Replace('DeviceIdEnding',$DeviceIdEnding)
if ( $keyItems ) {
@($DeviceIdEnding,
$keyItems.$devIndex, # index
$keyItems.$devDriver, # driver
$keyItems.$devDevice # device
) -join "`t"
}
}
Output:
Name : Mikrofon (VIA HD Audio)
DeviceID : SWDMMDEVAPI{0.0.1.00000000}.{D2E3C581-8C7B-4A32-A35B-1F42DA18733D}
Name : Reproduktory (VIA HD Audio)
DeviceID : SWDMMDEVAPI{0.0.0.00000000}.{E378C915-D069-491F-8089-B1061906AA94}
Name : Headphone (VIA HD Audio)
DeviceID : SWDMMDEVAPI{0.0.0.00000000}.{420BCEED-7571-4350-93A4-5E0C1E2554F0}
--- DeviceId index ---
{E378C915-D069-491F-8089-B1061906AA94} 1 VIA HD Audio Reproduktory
{420BCEED-7571-4350-93A4-5E0C1E2554F0} 3 VIA HD Audio Headphone
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54257685%2fproperly-decipher-registry-reg-binary-with-python-3-winreg%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
To decipher a complex binary value, you need to know it's structure. Let's start analyzing the following raw output:
reg query HKEY_USERSS-1-5-19SoftwareMicrosoftWindowsCurrentVersionAudioJournal -v Render
HKEY_USERSS-1-5-19SoftwareMicrosoftWindowsCurrentVersionAudioJournal
Render REG_BINARY 5300570044005C004D004D004400450056004100500049005C007B0030002E0030002E0030002E00300030003000300030003000300030007D002E007B00650033003700380063003900310035002D0064003000360039002D0034003900310066002D0038003000380039002D006200310030003600310039003000360061006100390034007D000000000000000000010000004B000000000000000000000000000000000000006A9A65709D075F400000000000000000000000000000000000000000000000005300570044005C004D004D004400450056004100500049005C007B0030002E0030002E0030002E00300030003000300030003000300030007D002E007B00340032003000620063006500650064002D0037003500370031002D0034003300350030002D0039003300610034002D003500650030006300310065003200350035003400660030007D0000000000000000000300000001000000000000000000000000000000000000004162F5AC588503400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
The following table shows above Render
registry entry structure (based on my own finding):
offset bytes caption format comment
------ ----- ------- ------ -------
0x0000 136 DeviceID char (68 chars; encoding UCS-2 LE)
0x0088 8 unknown_88 uint64
0x0090 4 EndPointNo uint32 (LE); constant for given end point
0x0094 4 Counter_94 uint32 (LE); increases if a sound is played
0x0098 8 unknown_98 uint64
0x00a0 8 unknown_a0 uint64
0x00a8 8 Strange_a8 uint64 changes unpredictably even for identical sound
0x00b0 8 unknown_b0 uint64
0x00b8 8 unknown_b8 uint64
0x00c0 8 unknown_c0 uint64
The above structure iterates three (or even more?) times within the Render
value. All the parts denominated unknown_*
constantly keep zero value so it's hard to guess their format and meaning, and don't change even if the system sounds (audio alerts) are forced to be shown visually (in the Ease of access settings).
Let's decrypt the Render
value - as soon as it's structure is at least partially known. In Python, use the struct
module (performs conversions between Python values and C structs represented as Python bytes objects).
Unfortunately, I don't speak Python fluently enough; so here is my Powershell solution:
#Requires -RunAsAdministrator
[CmdletBinding()]param(
[Parameter(Mandatory=$False,Position=0)][string]$PlaySound=''
)
if ( $PlaySound -eq '' ) {
Write-Information -infa Continue "Retrieving current values"
} else {
# play the file once
$soundLoc = "c:WINDOWSMedianotify.wav"
Write-Information -infa Continue "Playing $soundLoc"
$sound = new-Object System.Media.SoundPlayer
$sound.SoundLocation = $soundLoc
$sound.Play()
Start-Sleep -Seconds 1
}
$key = 'Registry::HKEY_USERSS-1-5-19SoftwareMicrosoftWindows' +
'CurrentVersionAudioJournal'
$keyItems = Get-ItemProperty -Path $key
$render = $keyItems.Render
$csvStruct=@"
offset,bytes,caption,format,comment
0x0000, 136,DeviceID,char,(68 chars; encoding UCS-2 LE)
0x0088, 8,unknown_88,uint64,
0x0090, 4,EndPointNo,uint32,(LE); constant for given end point
0x0094, 4,Counter_94,uint32,(LE); increases if a sound is played
0x0098, 8,unknown_98,uint64,
0x00a0, 8,unknown_a0,uint64,
0x00a8, 8,Strange_a8,uint64,changes unpredictably even for identical sound
0x00b0, 8,unknown_b0,uint64,
0x00b8, 8,unknown_b8,uint64,
0x00c0, 8,unknown_c0,uint64,
"@ | ConvertFrom-Csv
$unicode=[System.Text.UnicodeEncoding]::Unicode
$renderParts=@()
$renderInfos=@()
$renderNext = $renderCnt = 0
While ( $renderNext -lt $render.Count -and ( <# go over all value #>
$render[$renderNext + 0xaf] -ne 0 -or <# 0x40 if not zero #>
$render[$renderNext] -ne 0 )) { <# DeviceID not empty #>
for ($i=0; $i -lt $csvStruct.Count; $i++) {
$part = $csvStruct[$i]
If ( $part.format -eq 'char' ) {
$renderParts += @{
$part.caption = $unicode.GetString($render,
$renderNext + [int]$part.offset, [int]$part.bytes)
}
} else {
$hexLE='0x' # Little Endian
for ($j=[int]$part.bytes -1; $j -ge 0; $j--) {
$hexLE+= '{0:x2}' -f $render[$renderNext + [int]$part.offset + $j]
}
$hexBE='0X' # Big Endian
for ($j=0; $j -le [int]$part.bytes -1; $j++) {
$hexBE+= '{0:x2}' -f $render[$renderNext + [int]$part.offset + $j]
}
$hexBE = $hexBE.ToUpper()
$renderParts += @{
$part.caption = $hexLE
}
if ( $part.caption -eq 'Strange_a8') {
Write-Information $(
[System.Environment]::NewLine +
$renderParts[ $renderCnt ].DeviceID )
Write-Information $(
'EndPointNo = ' +
[int32]$renderParts[ 2 + $renderCnt ].EndPointNo +
', Counter_94 = ' +
[int32]$renderParts[ 3 + $renderCnt ].Counter_94 )
Write-Information $( "$($part.caption)`t`t$hexLE`t`t$hexBE" )
#Write-Information $(
# [System.Text.UnicodeEncoding]::Default.GetString($render,
# 0x00a8 + $renderNext, 8) )
Write-Information $(
'uint64 {0,20}' -f [uint64]$hexLE )
Write-Information $(
'uint32 {0,10} {1,10}' -f
[uint32]('0x' + $hexLE.Substring(10,8)),
[uint32]('0x' + $hexLE.Substring( 2,8)) )
Write-Information $(
' int16 {0,6} {1,6} {2,6} {3,6}' -f
[int16]('0x' + $hexLE.Substring(14,4)),
[int16]('0x' + $hexLE.Substring(10,4)),
[int16]('0x' + $hexLE.Substring( 6,4)),
[int16]('0x' + $hexLE.Substring( 2,4)) )
Write-Information $(
'uint16 {0,6} {1,6} {2,6} {3,6}' -f
[uint16]('0x' + $hexLE.Substring(14,4)),
[uint16]('0x' + $hexLE.Substring(10,4)),
[uint16]('0x' + $hexLE.Substring( 6,4)),
[uint16]('0x' + $hexLE.Substring( 2,4)) )
Write-Information $(
' byte {0,3} {1,3} {2,3} {3,3} {4,3} {5,3} {6,3} {7,3}' -f
[byte]('0x' + $hexLE.Substring(16,2)),
[byte]('0x' + $hexLE.Substring(14,2)),
[byte]('0x' + $hexLE.Substring(12,2)),
[byte]('0x' + $hexLE.Substring(10,2)),
[byte]('0x' + $hexLE.Substring( 8,2)),
[byte]('0x' + $hexLE.Substring( 6,2)),
[byte]('0x' + $hexLE.Substring( 4,2)),
[byte]('0x' + $hexLE.Substring( 2,2)) )
}
}
}
$renderNext+=200
$renderCnt +=10
}
$renderParts
Sample usage:
D:PShelltestsMMDEVAPI_Journal_Registry.ps1
retrieves currentRender
value.
D:PShelltestsMMDEVAPI_Journal_Registry.ps1 x
plays a system sound before retrieving theRender
value (added after theRender
value suddenly became zeroized for unknown reason).
D:PShelltestsMMDEVAPI_Journal_Registry.ps1 -InformationAction Continue
prints additional analysis of theStrange_a8
subvalue (shows it as structured in various numeric types).
Output (formatted by piping to Format-Table -Autosize
):
Name Value
---- -----
DeviceID SWDMMDEVAPI{0.0.0.00000000}.{e378c915-d069-491f-8089-b1061906aa94}
unknown_88 0x0000000000000000
EndPointNo 0x00000001
Counter_94 0x0000004a
unknown_98 0x0000000000000000
unknown_a0 0x0000000000000000
Strange_a8 0x405eb3c4b7ffda6f
unknown_b0 0x0000000000000000
unknown_b8 0x0000000000000000
unknown_c0 0x0000000000000000
DeviceID SWDMMDEVAPI{0.0.0.00000000}.{420bceed-7571-4350-93a4-5e0c1e2554f0}
unknown_88 0x0000000000000000
EndPointNo 0x00000003
Counter_94 0x00000001
unknown_98 0x0000000000000000
unknown_a0 0x0000000000000000
Strange_a8 0x40038558acf56241
unknown_b0 0x0000000000000000
unknown_b8 0x0000000000000000
unknown_c0 0x0000000000000000
Note. The EndPointNo
part seems to be related to the obscure registry key HKLMSOFTWAREMicrosoftWindowsCurrentVersionMMDevicesAudio
as shown in the following script:
$computer = $env:COMPUTERNAME
$namespace = "ROOTCIMV2"
$classname = "Win32_PnPEntity"
$auxPnP = Get-WmiObject -Class $classname `
-ComputerName $computer `
-Namespace $namespace |
Where-object PNPDeviceID -match `
'{[0-9a-fA-F].[0-9a-fA-F].[0-9a-fA-F].[0-9a-fA-F]{8}}' |
Select-Object * -ExcludeProperty PSComputerName,
Scope, Path, Options, ClassPath, Properties,
SystemProperties, Qualifiers, Site, Container
$auxPnP | Format-List -property Name,DeviceID <# -Property [a-z]* <##>
'--- DeviceId index ---'
$devIndex = '{1da5d803-d492-4edd-8c23-e0c0ffee7f0e},0'
$devDriver= '{b3f8fa53-0004-438e-9003-51a46e139bfc},6'
$devDevice= '{a45c254e-df1c-4efd-8020-67d146a850e0},2'
$keyAbove = 'Registry::HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows' +
'CurrentVersionMMDevicesAudio'
$keyTempl = $keyAbove + 'RenderDeviceIdEndingProperties'
$auxPnP | ForEach-Object {
$DeviceIdEnding = $_.DeviceID.Substring($_.DeviceID.LastIndexOf('.')+1)
$keyItems = Get-ItemProperty -ErrorAction SilentlyContinue `
-Path $keyTempl.Replace('DeviceIdEnding',$DeviceIdEnding)
if ( $keyItems ) {
@($DeviceIdEnding,
$keyItems.$devIndex, # index
$keyItems.$devDriver, # driver
$keyItems.$devDevice # device
) -join "`t"
}
}
Output:
Name : Mikrofon (VIA HD Audio)
DeviceID : SWDMMDEVAPI{0.0.1.00000000}.{D2E3C581-8C7B-4A32-A35B-1F42DA18733D}
Name : Reproduktory (VIA HD Audio)
DeviceID : SWDMMDEVAPI{0.0.0.00000000}.{E378C915-D069-491F-8089-B1061906AA94}
Name : Headphone (VIA HD Audio)
DeviceID : SWDMMDEVAPI{0.0.0.00000000}.{420BCEED-7571-4350-93A4-5E0C1E2554F0}
--- DeviceId index ---
{E378C915-D069-491F-8089-B1061906AA94} 1 VIA HD Audio Reproduktory
{420BCEED-7571-4350-93A4-5E0C1E2554F0} 3 VIA HD Audio Headphone
add a comment |
To decipher a complex binary value, you need to know it's structure. Let's start analyzing the following raw output:
reg query HKEY_USERSS-1-5-19SoftwareMicrosoftWindowsCurrentVersionAudioJournal -v Render
HKEY_USERSS-1-5-19SoftwareMicrosoftWindowsCurrentVersionAudioJournal
Render REG_BINARY 5300570044005C004D004D004400450056004100500049005C007B0030002E0030002E0030002E00300030003000300030003000300030007D002E007B00650033003700380063003900310035002D0064003000360039002D0034003900310066002D0038003000380039002D006200310030003600310039003000360061006100390034007D000000000000000000010000004B000000000000000000000000000000000000006A9A65709D075F400000000000000000000000000000000000000000000000005300570044005C004D004D004400450056004100500049005C007B0030002E0030002E0030002E00300030003000300030003000300030007D002E007B00340032003000620063006500650064002D0037003500370031002D0034003300350030002D0039003300610034002D003500650030006300310065003200350035003400660030007D0000000000000000000300000001000000000000000000000000000000000000004162F5AC588503400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
The following table shows above Render
registry entry structure (based on my own finding):
offset bytes caption format comment
------ ----- ------- ------ -------
0x0000 136 DeviceID char (68 chars; encoding UCS-2 LE)
0x0088 8 unknown_88 uint64
0x0090 4 EndPointNo uint32 (LE); constant for given end point
0x0094 4 Counter_94 uint32 (LE); increases if a sound is played
0x0098 8 unknown_98 uint64
0x00a0 8 unknown_a0 uint64
0x00a8 8 Strange_a8 uint64 changes unpredictably even for identical sound
0x00b0 8 unknown_b0 uint64
0x00b8 8 unknown_b8 uint64
0x00c0 8 unknown_c0 uint64
The above structure iterates three (or even more?) times within the Render
value. All the parts denominated unknown_*
constantly keep zero value so it's hard to guess their format and meaning, and don't change even if the system sounds (audio alerts) are forced to be shown visually (in the Ease of access settings).
Let's decrypt the Render
value - as soon as it's structure is at least partially known. In Python, use the struct
module (performs conversions between Python values and C structs represented as Python bytes objects).
Unfortunately, I don't speak Python fluently enough; so here is my Powershell solution:
#Requires -RunAsAdministrator
[CmdletBinding()]param(
[Parameter(Mandatory=$False,Position=0)][string]$PlaySound=''
)
if ( $PlaySound -eq '' ) {
Write-Information -infa Continue "Retrieving current values"
} else {
# play the file once
$soundLoc = "c:WINDOWSMedianotify.wav"
Write-Information -infa Continue "Playing $soundLoc"
$sound = new-Object System.Media.SoundPlayer
$sound.SoundLocation = $soundLoc
$sound.Play()
Start-Sleep -Seconds 1
}
$key = 'Registry::HKEY_USERSS-1-5-19SoftwareMicrosoftWindows' +
'CurrentVersionAudioJournal'
$keyItems = Get-ItemProperty -Path $key
$render = $keyItems.Render
$csvStruct=@"
offset,bytes,caption,format,comment
0x0000, 136,DeviceID,char,(68 chars; encoding UCS-2 LE)
0x0088, 8,unknown_88,uint64,
0x0090, 4,EndPointNo,uint32,(LE); constant for given end point
0x0094, 4,Counter_94,uint32,(LE); increases if a sound is played
0x0098, 8,unknown_98,uint64,
0x00a0, 8,unknown_a0,uint64,
0x00a8, 8,Strange_a8,uint64,changes unpredictably even for identical sound
0x00b0, 8,unknown_b0,uint64,
0x00b8, 8,unknown_b8,uint64,
0x00c0, 8,unknown_c0,uint64,
"@ | ConvertFrom-Csv
$unicode=[System.Text.UnicodeEncoding]::Unicode
$renderParts=@()
$renderInfos=@()
$renderNext = $renderCnt = 0
While ( $renderNext -lt $render.Count -and ( <# go over all value #>
$render[$renderNext + 0xaf] -ne 0 -or <# 0x40 if not zero #>
$render[$renderNext] -ne 0 )) { <# DeviceID not empty #>
for ($i=0; $i -lt $csvStruct.Count; $i++) {
$part = $csvStruct[$i]
If ( $part.format -eq 'char' ) {
$renderParts += @{
$part.caption = $unicode.GetString($render,
$renderNext + [int]$part.offset, [int]$part.bytes)
}
} else {
$hexLE='0x' # Little Endian
for ($j=[int]$part.bytes -1; $j -ge 0; $j--) {
$hexLE+= '{0:x2}' -f $render[$renderNext + [int]$part.offset + $j]
}
$hexBE='0X' # Big Endian
for ($j=0; $j -le [int]$part.bytes -1; $j++) {
$hexBE+= '{0:x2}' -f $render[$renderNext + [int]$part.offset + $j]
}
$hexBE = $hexBE.ToUpper()
$renderParts += @{
$part.caption = $hexLE
}
if ( $part.caption -eq 'Strange_a8') {
Write-Information $(
[System.Environment]::NewLine +
$renderParts[ $renderCnt ].DeviceID )
Write-Information $(
'EndPointNo = ' +
[int32]$renderParts[ 2 + $renderCnt ].EndPointNo +
', Counter_94 = ' +
[int32]$renderParts[ 3 + $renderCnt ].Counter_94 )
Write-Information $( "$($part.caption)`t`t$hexLE`t`t$hexBE" )
#Write-Information $(
# [System.Text.UnicodeEncoding]::Default.GetString($render,
# 0x00a8 + $renderNext, 8) )
Write-Information $(
'uint64 {0,20}' -f [uint64]$hexLE )
Write-Information $(
'uint32 {0,10} {1,10}' -f
[uint32]('0x' + $hexLE.Substring(10,8)),
[uint32]('0x' + $hexLE.Substring( 2,8)) )
Write-Information $(
' int16 {0,6} {1,6} {2,6} {3,6}' -f
[int16]('0x' + $hexLE.Substring(14,4)),
[int16]('0x' + $hexLE.Substring(10,4)),
[int16]('0x' + $hexLE.Substring( 6,4)),
[int16]('0x' + $hexLE.Substring( 2,4)) )
Write-Information $(
'uint16 {0,6} {1,6} {2,6} {3,6}' -f
[uint16]('0x' + $hexLE.Substring(14,4)),
[uint16]('0x' + $hexLE.Substring(10,4)),
[uint16]('0x' + $hexLE.Substring( 6,4)),
[uint16]('0x' + $hexLE.Substring( 2,4)) )
Write-Information $(
' byte {0,3} {1,3} {2,3} {3,3} {4,3} {5,3} {6,3} {7,3}' -f
[byte]('0x' + $hexLE.Substring(16,2)),
[byte]('0x' + $hexLE.Substring(14,2)),
[byte]('0x' + $hexLE.Substring(12,2)),
[byte]('0x' + $hexLE.Substring(10,2)),
[byte]('0x' + $hexLE.Substring( 8,2)),
[byte]('0x' + $hexLE.Substring( 6,2)),
[byte]('0x' + $hexLE.Substring( 4,2)),
[byte]('0x' + $hexLE.Substring( 2,2)) )
}
}
}
$renderNext+=200
$renderCnt +=10
}
$renderParts
Sample usage:
D:PShelltestsMMDEVAPI_Journal_Registry.ps1
retrieves currentRender
value.
D:PShelltestsMMDEVAPI_Journal_Registry.ps1 x
plays a system sound before retrieving theRender
value (added after theRender
value suddenly became zeroized for unknown reason).
D:PShelltestsMMDEVAPI_Journal_Registry.ps1 -InformationAction Continue
prints additional analysis of theStrange_a8
subvalue (shows it as structured in various numeric types).
Output (formatted by piping to Format-Table -Autosize
):
Name Value
---- -----
DeviceID SWDMMDEVAPI{0.0.0.00000000}.{e378c915-d069-491f-8089-b1061906aa94}
unknown_88 0x0000000000000000
EndPointNo 0x00000001
Counter_94 0x0000004a
unknown_98 0x0000000000000000
unknown_a0 0x0000000000000000
Strange_a8 0x405eb3c4b7ffda6f
unknown_b0 0x0000000000000000
unknown_b8 0x0000000000000000
unknown_c0 0x0000000000000000
DeviceID SWDMMDEVAPI{0.0.0.00000000}.{420bceed-7571-4350-93a4-5e0c1e2554f0}
unknown_88 0x0000000000000000
EndPointNo 0x00000003
Counter_94 0x00000001
unknown_98 0x0000000000000000
unknown_a0 0x0000000000000000
Strange_a8 0x40038558acf56241
unknown_b0 0x0000000000000000
unknown_b8 0x0000000000000000
unknown_c0 0x0000000000000000
Note. The EndPointNo
part seems to be related to the obscure registry key HKLMSOFTWAREMicrosoftWindowsCurrentVersionMMDevicesAudio
as shown in the following script:
$computer = $env:COMPUTERNAME
$namespace = "ROOTCIMV2"
$classname = "Win32_PnPEntity"
$auxPnP = Get-WmiObject -Class $classname `
-ComputerName $computer `
-Namespace $namespace |
Where-object PNPDeviceID -match `
'{[0-9a-fA-F].[0-9a-fA-F].[0-9a-fA-F].[0-9a-fA-F]{8}}' |
Select-Object * -ExcludeProperty PSComputerName,
Scope, Path, Options, ClassPath, Properties,
SystemProperties, Qualifiers, Site, Container
$auxPnP | Format-List -property Name,DeviceID <# -Property [a-z]* <##>
'--- DeviceId index ---'
$devIndex = '{1da5d803-d492-4edd-8c23-e0c0ffee7f0e},0'
$devDriver= '{b3f8fa53-0004-438e-9003-51a46e139bfc},6'
$devDevice= '{a45c254e-df1c-4efd-8020-67d146a850e0},2'
$keyAbove = 'Registry::HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows' +
'CurrentVersionMMDevicesAudio'
$keyTempl = $keyAbove + 'RenderDeviceIdEndingProperties'
$auxPnP | ForEach-Object {
$DeviceIdEnding = $_.DeviceID.Substring($_.DeviceID.LastIndexOf('.')+1)
$keyItems = Get-ItemProperty -ErrorAction SilentlyContinue `
-Path $keyTempl.Replace('DeviceIdEnding',$DeviceIdEnding)
if ( $keyItems ) {
@($DeviceIdEnding,
$keyItems.$devIndex, # index
$keyItems.$devDriver, # driver
$keyItems.$devDevice # device
) -join "`t"
}
}
Output:
Name : Mikrofon (VIA HD Audio)
DeviceID : SWDMMDEVAPI{0.0.1.00000000}.{D2E3C581-8C7B-4A32-A35B-1F42DA18733D}
Name : Reproduktory (VIA HD Audio)
DeviceID : SWDMMDEVAPI{0.0.0.00000000}.{E378C915-D069-491F-8089-B1061906AA94}
Name : Headphone (VIA HD Audio)
DeviceID : SWDMMDEVAPI{0.0.0.00000000}.{420BCEED-7571-4350-93A4-5E0C1E2554F0}
--- DeviceId index ---
{E378C915-D069-491F-8089-B1061906AA94} 1 VIA HD Audio Reproduktory
{420BCEED-7571-4350-93A4-5E0C1E2554F0} 3 VIA HD Audio Headphone
add a comment |
To decipher a complex binary value, you need to know it's structure. Let's start analyzing the following raw output:
reg query HKEY_USERSS-1-5-19SoftwareMicrosoftWindowsCurrentVersionAudioJournal -v Render
HKEY_USERSS-1-5-19SoftwareMicrosoftWindowsCurrentVersionAudioJournal
Render REG_BINARY 5300570044005C004D004D004400450056004100500049005C007B0030002E0030002E0030002E00300030003000300030003000300030007D002E007B00650033003700380063003900310035002D0064003000360039002D0034003900310066002D0038003000380039002D006200310030003600310039003000360061006100390034007D000000000000000000010000004B000000000000000000000000000000000000006A9A65709D075F400000000000000000000000000000000000000000000000005300570044005C004D004D004400450056004100500049005C007B0030002E0030002E0030002E00300030003000300030003000300030007D002E007B00340032003000620063006500650064002D0037003500370031002D0034003300350030002D0039003300610034002D003500650030006300310065003200350035003400660030007D0000000000000000000300000001000000000000000000000000000000000000004162F5AC588503400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
The following table shows above Render
registry entry structure (based on my own finding):
offset bytes caption format comment
------ ----- ------- ------ -------
0x0000 136 DeviceID char (68 chars; encoding UCS-2 LE)
0x0088 8 unknown_88 uint64
0x0090 4 EndPointNo uint32 (LE); constant for given end point
0x0094 4 Counter_94 uint32 (LE); increases if a sound is played
0x0098 8 unknown_98 uint64
0x00a0 8 unknown_a0 uint64
0x00a8 8 Strange_a8 uint64 changes unpredictably even for identical sound
0x00b0 8 unknown_b0 uint64
0x00b8 8 unknown_b8 uint64
0x00c0 8 unknown_c0 uint64
The above structure iterates three (or even more?) times within the Render
value. All the parts denominated unknown_*
constantly keep zero value so it's hard to guess their format and meaning, and don't change even if the system sounds (audio alerts) are forced to be shown visually (in the Ease of access settings).
Let's decrypt the Render
value - as soon as it's structure is at least partially known. In Python, use the struct
module (performs conversions between Python values and C structs represented as Python bytes objects).
Unfortunately, I don't speak Python fluently enough; so here is my Powershell solution:
#Requires -RunAsAdministrator
[CmdletBinding()]param(
[Parameter(Mandatory=$False,Position=0)][string]$PlaySound=''
)
if ( $PlaySound -eq '' ) {
Write-Information -infa Continue "Retrieving current values"
} else {
# play the file once
$soundLoc = "c:WINDOWSMedianotify.wav"
Write-Information -infa Continue "Playing $soundLoc"
$sound = new-Object System.Media.SoundPlayer
$sound.SoundLocation = $soundLoc
$sound.Play()
Start-Sleep -Seconds 1
}
$key = 'Registry::HKEY_USERSS-1-5-19SoftwareMicrosoftWindows' +
'CurrentVersionAudioJournal'
$keyItems = Get-ItemProperty -Path $key
$render = $keyItems.Render
$csvStruct=@"
offset,bytes,caption,format,comment
0x0000, 136,DeviceID,char,(68 chars; encoding UCS-2 LE)
0x0088, 8,unknown_88,uint64,
0x0090, 4,EndPointNo,uint32,(LE); constant for given end point
0x0094, 4,Counter_94,uint32,(LE); increases if a sound is played
0x0098, 8,unknown_98,uint64,
0x00a0, 8,unknown_a0,uint64,
0x00a8, 8,Strange_a8,uint64,changes unpredictably even for identical sound
0x00b0, 8,unknown_b0,uint64,
0x00b8, 8,unknown_b8,uint64,
0x00c0, 8,unknown_c0,uint64,
"@ | ConvertFrom-Csv
$unicode=[System.Text.UnicodeEncoding]::Unicode
$renderParts=@()
$renderInfos=@()
$renderNext = $renderCnt = 0
While ( $renderNext -lt $render.Count -and ( <# go over all value #>
$render[$renderNext + 0xaf] -ne 0 -or <# 0x40 if not zero #>
$render[$renderNext] -ne 0 )) { <# DeviceID not empty #>
for ($i=0; $i -lt $csvStruct.Count; $i++) {
$part = $csvStruct[$i]
If ( $part.format -eq 'char' ) {
$renderParts += @{
$part.caption = $unicode.GetString($render,
$renderNext + [int]$part.offset, [int]$part.bytes)
}
} else {
$hexLE='0x' # Little Endian
for ($j=[int]$part.bytes -1; $j -ge 0; $j--) {
$hexLE+= '{0:x2}' -f $render[$renderNext + [int]$part.offset + $j]
}
$hexBE='0X' # Big Endian
for ($j=0; $j -le [int]$part.bytes -1; $j++) {
$hexBE+= '{0:x2}' -f $render[$renderNext + [int]$part.offset + $j]
}
$hexBE = $hexBE.ToUpper()
$renderParts += @{
$part.caption = $hexLE
}
if ( $part.caption -eq 'Strange_a8') {
Write-Information $(
[System.Environment]::NewLine +
$renderParts[ $renderCnt ].DeviceID )
Write-Information $(
'EndPointNo = ' +
[int32]$renderParts[ 2 + $renderCnt ].EndPointNo +
', Counter_94 = ' +
[int32]$renderParts[ 3 + $renderCnt ].Counter_94 )
Write-Information $( "$($part.caption)`t`t$hexLE`t`t$hexBE" )
#Write-Information $(
# [System.Text.UnicodeEncoding]::Default.GetString($render,
# 0x00a8 + $renderNext, 8) )
Write-Information $(
'uint64 {0,20}' -f [uint64]$hexLE )
Write-Information $(
'uint32 {0,10} {1,10}' -f
[uint32]('0x' + $hexLE.Substring(10,8)),
[uint32]('0x' + $hexLE.Substring( 2,8)) )
Write-Information $(
' int16 {0,6} {1,6} {2,6} {3,6}' -f
[int16]('0x' + $hexLE.Substring(14,4)),
[int16]('0x' + $hexLE.Substring(10,4)),
[int16]('0x' + $hexLE.Substring( 6,4)),
[int16]('0x' + $hexLE.Substring( 2,4)) )
Write-Information $(
'uint16 {0,6} {1,6} {2,6} {3,6}' -f
[uint16]('0x' + $hexLE.Substring(14,4)),
[uint16]('0x' + $hexLE.Substring(10,4)),
[uint16]('0x' + $hexLE.Substring( 6,4)),
[uint16]('0x' + $hexLE.Substring( 2,4)) )
Write-Information $(
' byte {0,3} {1,3} {2,3} {3,3} {4,3} {5,3} {6,3} {7,3}' -f
[byte]('0x' + $hexLE.Substring(16,2)),
[byte]('0x' + $hexLE.Substring(14,2)),
[byte]('0x' + $hexLE.Substring(12,2)),
[byte]('0x' + $hexLE.Substring(10,2)),
[byte]('0x' + $hexLE.Substring( 8,2)),
[byte]('0x' + $hexLE.Substring( 6,2)),
[byte]('0x' + $hexLE.Substring( 4,2)),
[byte]('0x' + $hexLE.Substring( 2,2)) )
}
}
}
$renderNext+=200
$renderCnt +=10
}
$renderParts
Sample usage:
D:PShelltestsMMDEVAPI_Journal_Registry.ps1
retrieves currentRender
value.
D:PShelltestsMMDEVAPI_Journal_Registry.ps1 x
plays a system sound before retrieving theRender
value (added after theRender
value suddenly became zeroized for unknown reason).
D:PShelltestsMMDEVAPI_Journal_Registry.ps1 -InformationAction Continue
prints additional analysis of theStrange_a8
subvalue (shows it as structured in various numeric types).
Output (formatted by piping to Format-Table -Autosize
):
Name Value
---- -----
DeviceID SWDMMDEVAPI{0.0.0.00000000}.{e378c915-d069-491f-8089-b1061906aa94}
unknown_88 0x0000000000000000
EndPointNo 0x00000001
Counter_94 0x0000004a
unknown_98 0x0000000000000000
unknown_a0 0x0000000000000000
Strange_a8 0x405eb3c4b7ffda6f
unknown_b0 0x0000000000000000
unknown_b8 0x0000000000000000
unknown_c0 0x0000000000000000
DeviceID SWDMMDEVAPI{0.0.0.00000000}.{420bceed-7571-4350-93a4-5e0c1e2554f0}
unknown_88 0x0000000000000000
EndPointNo 0x00000003
Counter_94 0x00000001
unknown_98 0x0000000000000000
unknown_a0 0x0000000000000000
Strange_a8 0x40038558acf56241
unknown_b0 0x0000000000000000
unknown_b8 0x0000000000000000
unknown_c0 0x0000000000000000
Note. The EndPointNo
part seems to be related to the obscure registry key HKLMSOFTWAREMicrosoftWindowsCurrentVersionMMDevicesAudio
as shown in the following script:
$computer = $env:COMPUTERNAME
$namespace = "ROOTCIMV2"
$classname = "Win32_PnPEntity"
$auxPnP = Get-WmiObject -Class $classname `
-ComputerName $computer `
-Namespace $namespace |
Where-object PNPDeviceID -match `
'{[0-9a-fA-F].[0-9a-fA-F].[0-9a-fA-F].[0-9a-fA-F]{8}}' |
Select-Object * -ExcludeProperty PSComputerName,
Scope, Path, Options, ClassPath, Properties,
SystemProperties, Qualifiers, Site, Container
$auxPnP | Format-List -property Name,DeviceID <# -Property [a-z]* <##>
'--- DeviceId index ---'
$devIndex = '{1da5d803-d492-4edd-8c23-e0c0ffee7f0e},0'
$devDriver= '{b3f8fa53-0004-438e-9003-51a46e139bfc},6'
$devDevice= '{a45c254e-df1c-4efd-8020-67d146a850e0},2'
$keyAbove = 'Registry::HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows' +
'CurrentVersionMMDevicesAudio'
$keyTempl = $keyAbove + 'RenderDeviceIdEndingProperties'
$auxPnP | ForEach-Object {
$DeviceIdEnding = $_.DeviceID.Substring($_.DeviceID.LastIndexOf('.')+1)
$keyItems = Get-ItemProperty -ErrorAction SilentlyContinue `
-Path $keyTempl.Replace('DeviceIdEnding',$DeviceIdEnding)
if ( $keyItems ) {
@($DeviceIdEnding,
$keyItems.$devIndex, # index
$keyItems.$devDriver, # driver
$keyItems.$devDevice # device
) -join "`t"
}
}
Output:
Name : Mikrofon (VIA HD Audio)
DeviceID : SWDMMDEVAPI{0.0.1.00000000}.{D2E3C581-8C7B-4A32-A35B-1F42DA18733D}
Name : Reproduktory (VIA HD Audio)
DeviceID : SWDMMDEVAPI{0.0.0.00000000}.{E378C915-D069-491F-8089-B1061906AA94}
Name : Headphone (VIA HD Audio)
DeviceID : SWDMMDEVAPI{0.0.0.00000000}.{420BCEED-7571-4350-93A4-5E0C1E2554F0}
--- DeviceId index ---
{E378C915-D069-491F-8089-B1061906AA94} 1 VIA HD Audio Reproduktory
{420BCEED-7571-4350-93A4-5E0C1E2554F0} 3 VIA HD Audio Headphone
To decipher a complex binary value, you need to know it's structure. Let's start analyzing the following raw output:
reg query HKEY_USERSS-1-5-19SoftwareMicrosoftWindowsCurrentVersionAudioJournal -v Render
HKEY_USERSS-1-5-19SoftwareMicrosoftWindowsCurrentVersionAudioJournal
Render REG_BINARY 5300570044005C004D004D004400450056004100500049005C007B0030002E0030002E0030002E00300030003000300030003000300030007D002E007B00650033003700380063003900310035002D0064003000360039002D0034003900310066002D0038003000380039002D006200310030003600310039003000360061006100390034007D000000000000000000010000004B000000000000000000000000000000000000006A9A65709D075F400000000000000000000000000000000000000000000000005300570044005C004D004D004400450056004100500049005C007B0030002E0030002E0030002E00300030003000300030003000300030007D002E007B00340032003000620063006500650064002D0037003500370031002D0034003300350030002D0039003300610034002D003500650030006300310065003200350035003400660030007D0000000000000000000300000001000000000000000000000000000000000000004162F5AC588503400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
The following table shows above Render
registry entry structure (based on my own finding):
offset bytes caption format comment
------ ----- ------- ------ -------
0x0000 136 DeviceID char (68 chars; encoding UCS-2 LE)
0x0088 8 unknown_88 uint64
0x0090 4 EndPointNo uint32 (LE); constant for given end point
0x0094 4 Counter_94 uint32 (LE); increases if a sound is played
0x0098 8 unknown_98 uint64
0x00a0 8 unknown_a0 uint64
0x00a8 8 Strange_a8 uint64 changes unpredictably even for identical sound
0x00b0 8 unknown_b0 uint64
0x00b8 8 unknown_b8 uint64
0x00c0 8 unknown_c0 uint64
The above structure iterates three (or even more?) times within the Render
value. All the parts denominated unknown_*
constantly keep zero value so it's hard to guess their format and meaning, and don't change even if the system sounds (audio alerts) are forced to be shown visually (in the Ease of access settings).
Let's decrypt the Render
value - as soon as it's structure is at least partially known. In Python, use the struct
module (performs conversions between Python values and C structs represented as Python bytes objects).
Unfortunately, I don't speak Python fluently enough; so here is my Powershell solution:
#Requires -RunAsAdministrator
[CmdletBinding()]param(
[Parameter(Mandatory=$False,Position=0)][string]$PlaySound=''
)
if ( $PlaySound -eq '' ) {
Write-Information -infa Continue "Retrieving current values"
} else {
# play the file once
$soundLoc = "c:WINDOWSMedianotify.wav"
Write-Information -infa Continue "Playing $soundLoc"
$sound = new-Object System.Media.SoundPlayer
$sound.SoundLocation = $soundLoc
$sound.Play()
Start-Sleep -Seconds 1
}
$key = 'Registry::HKEY_USERSS-1-5-19SoftwareMicrosoftWindows' +
'CurrentVersionAudioJournal'
$keyItems = Get-ItemProperty -Path $key
$render = $keyItems.Render
$csvStruct=@"
offset,bytes,caption,format,comment
0x0000, 136,DeviceID,char,(68 chars; encoding UCS-2 LE)
0x0088, 8,unknown_88,uint64,
0x0090, 4,EndPointNo,uint32,(LE); constant for given end point
0x0094, 4,Counter_94,uint32,(LE); increases if a sound is played
0x0098, 8,unknown_98,uint64,
0x00a0, 8,unknown_a0,uint64,
0x00a8, 8,Strange_a8,uint64,changes unpredictably even for identical sound
0x00b0, 8,unknown_b0,uint64,
0x00b8, 8,unknown_b8,uint64,
0x00c0, 8,unknown_c0,uint64,
"@ | ConvertFrom-Csv
$unicode=[System.Text.UnicodeEncoding]::Unicode
$renderParts=@()
$renderInfos=@()
$renderNext = $renderCnt = 0
While ( $renderNext -lt $render.Count -and ( <# go over all value #>
$render[$renderNext + 0xaf] -ne 0 -or <# 0x40 if not zero #>
$render[$renderNext] -ne 0 )) { <# DeviceID not empty #>
for ($i=0; $i -lt $csvStruct.Count; $i++) {
$part = $csvStruct[$i]
If ( $part.format -eq 'char' ) {
$renderParts += @{
$part.caption = $unicode.GetString($render,
$renderNext + [int]$part.offset, [int]$part.bytes)
}
} else {
$hexLE='0x' # Little Endian
for ($j=[int]$part.bytes -1; $j -ge 0; $j--) {
$hexLE+= '{0:x2}' -f $render[$renderNext + [int]$part.offset + $j]
}
$hexBE='0X' # Big Endian
for ($j=0; $j -le [int]$part.bytes -1; $j++) {
$hexBE+= '{0:x2}' -f $render[$renderNext + [int]$part.offset + $j]
}
$hexBE = $hexBE.ToUpper()
$renderParts += @{
$part.caption = $hexLE
}
if ( $part.caption -eq 'Strange_a8') {
Write-Information $(
[System.Environment]::NewLine +
$renderParts[ $renderCnt ].DeviceID )
Write-Information $(
'EndPointNo = ' +
[int32]$renderParts[ 2 + $renderCnt ].EndPointNo +
', Counter_94 = ' +
[int32]$renderParts[ 3 + $renderCnt ].Counter_94 )
Write-Information $( "$($part.caption)`t`t$hexLE`t`t$hexBE" )
#Write-Information $(
# [System.Text.UnicodeEncoding]::Default.GetString($render,
# 0x00a8 + $renderNext, 8) )
Write-Information $(
'uint64 {0,20}' -f [uint64]$hexLE )
Write-Information $(
'uint32 {0,10} {1,10}' -f
[uint32]('0x' + $hexLE.Substring(10,8)),
[uint32]('0x' + $hexLE.Substring( 2,8)) )
Write-Information $(
' int16 {0,6} {1,6} {2,6} {3,6}' -f
[int16]('0x' + $hexLE.Substring(14,4)),
[int16]('0x' + $hexLE.Substring(10,4)),
[int16]('0x' + $hexLE.Substring( 6,4)),
[int16]('0x' + $hexLE.Substring( 2,4)) )
Write-Information $(
'uint16 {0,6} {1,6} {2,6} {3,6}' -f
[uint16]('0x' + $hexLE.Substring(14,4)),
[uint16]('0x' + $hexLE.Substring(10,4)),
[uint16]('0x' + $hexLE.Substring( 6,4)),
[uint16]('0x' + $hexLE.Substring( 2,4)) )
Write-Information $(
' byte {0,3} {1,3} {2,3} {3,3} {4,3} {5,3} {6,3} {7,3}' -f
[byte]('0x' + $hexLE.Substring(16,2)),
[byte]('0x' + $hexLE.Substring(14,2)),
[byte]('0x' + $hexLE.Substring(12,2)),
[byte]('0x' + $hexLE.Substring(10,2)),
[byte]('0x' + $hexLE.Substring( 8,2)),
[byte]('0x' + $hexLE.Substring( 6,2)),
[byte]('0x' + $hexLE.Substring( 4,2)),
[byte]('0x' + $hexLE.Substring( 2,2)) )
}
}
}
$renderNext+=200
$renderCnt +=10
}
$renderParts
Sample usage:
D:PShelltestsMMDEVAPI_Journal_Registry.ps1
retrieves currentRender
value.
D:PShelltestsMMDEVAPI_Journal_Registry.ps1 x
plays a system sound before retrieving theRender
value (added after theRender
value suddenly became zeroized for unknown reason).
D:PShelltestsMMDEVAPI_Journal_Registry.ps1 -InformationAction Continue
prints additional analysis of theStrange_a8
subvalue (shows it as structured in various numeric types).
Output (formatted by piping to Format-Table -Autosize
):
Name Value
---- -----
DeviceID SWDMMDEVAPI{0.0.0.00000000}.{e378c915-d069-491f-8089-b1061906aa94}
unknown_88 0x0000000000000000
EndPointNo 0x00000001
Counter_94 0x0000004a
unknown_98 0x0000000000000000
unknown_a0 0x0000000000000000
Strange_a8 0x405eb3c4b7ffda6f
unknown_b0 0x0000000000000000
unknown_b8 0x0000000000000000
unknown_c0 0x0000000000000000
DeviceID SWDMMDEVAPI{0.0.0.00000000}.{420bceed-7571-4350-93a4-5e0c1e2554f0}
unknown_88 0x0000000000000000
EndPointNo 0x00000003
Counter_94 0x00000001
unknown_98 0x0000000000000000
unknown_a0 0x0000000000000000
Strange_a8 0x40038558acf56241
unknown_b0 0x0000000000000000
unknown_b8 0x0000000000000000
unknown_c0 0x0000000000000000
Note. The EndPointNo
part seems to be related to the obscure registry key HKLMSOFTWAREMicrosoftWindowsCurrentVersionMMDevicesAudio
as shown in the following script:
$computer = $env:COMPUTERNAME
$namespace = "ROOTCIMV2"
$classname = "Win32_PnPEntity"
$auxPnP = Get-WmiObject -Class $classname `
-ComputerName $computer `
-Namespace $namespace |
Where-object PNPDeviceID -match `
'{[0-9a-fA-F].[0-9a-fA-F].[0-9a-fA-F].[0-9a-fA-F]{8}}' |
Select-Object * -ExcludeProperty PSComputerName,
Scope, Path, Options, ClassPath, Properties,
SystemProperties, Qualifiers, Site, Container
$auxPnP | Format-List -property Name,DeviceID <# -Property [a-z]* <##>
'--- DeviceId index ---'
$devIndex = '{1da5d803-d492-4edd-8c23-e0c0ffee7f0e},0'
$devDriver= '{b3f8fa53-0004-438e-9003-51a46e139bfc},6'
$devDevice= '{a45c254e-df1c-4efd-8020-67d146a850e0},2'
$keyAbove = 'Registry::HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows' +
'CurrentVersionMMDevicesAudio'
$keyTempl = $keyAbove + 'RenderDeviceIdEndingProperties'
$auxPnP | ForEach-Object {
$DeviceIdEnding = $_.DeviceID.Substring($_.DeviceID.LastIndexOf('.')+1)
$keyItems = Get-ItemProperty -ErrorAction SilentlyContinue `
-Path $keyTempl.Replace('DeviceIdEnding',$DeviceIdEnding)
if ( $keyItems ) {
@($DeviceIdEnding,
$keyItems.$devIndex, # index
$keyItems.$devDriver, # driver
$keyItems.$devDevice # device
) -join "`t"
}
}
Output:
Name : Mikrofon (VIA HD Audio)
DeviceID : SWDMMDEVAPI{0.0.1.00000000}.{D2E3C581-8C7B-4A32-A35B-1F42DA18733D}
Name : Reproduktory (VIA HD Audio)
DeviceID : SWDMMDEVAPI{0.0.0.00000000}.{E378C915-D069-491F-8089-B1061906AA94}
Name : Headphone (VIA HD Audio)
DeviceID : SWDMMDEVAPI{0.0.0.00000000}.{420BCEED-7571-4350-93A4-5E0C1E2554F0}
--- DeviceId index ---
{E378C915-D069-491F-8089-B1061906AA94} 1 VIA HD Audio Reproduktory
{420BCEED-7571-4350-93A4-5E0C1E2554F0} 3 VIA HD Audio Headphone
answered 11 hours ago
JosefZJosefZ
15.7k42040
15.7k42040
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54257685%2fproperly-decipher-registry-reg-binary-with-python-3-winreg%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Device manager —> Sound, video and game… —> <audio> controller —> Properties —> Details tab —> Property —> Bus relations (or Children). Also note this answer about
MMDevAPI.dll
- how to enumerate audio device endpoints and get their device IDs.– JosefZ
Jan 19 at 1:18
so the readable part is the info found in Bus relations but what about the encrypted part? this is what it looks like in my text editor since stackoverflow just ignores characters it doesn't know: ibb.co/6WvrtQ0 the link you posted is related to java, is python not able to decrypte the full string?
– theoka
Jan 19 at 12:54
The registry binary type is packed data. It may contain text, but may also have numeric data mixed in. You need to know the structure to unpack it.
– eryksun
Jan 19 at 17:59
FYI, the
ConnectRegistry
call serves no point when accessing the local registry. Also,HKEY_USERS
is not a hive. It's a predefined handle for the local registry key where user hives (e.g. ntuser.dat) are loaded by default, which is "RegistryUser". The predefined handles are a starting point, since the Windows registry API only uses NT handle-relative opens instead of exposing NT's root key in the object namespace "Registry". The system opens a real kernel handle for "RegistryUser" in place of the predefined handle, or an RPC handle if we're connected to a remote registry.– eryksun
Jan 19 at 18:06
how do i know the data structure of a reg_binary befor i unpack it? i ended up at that key path with the help of process monitor. i already knew the key names that decrypted reg_binary returned (which turn out to be "Bus relations" in the device manager) and where to find them. what i'm actually hoping to get from the rest of the reg_binary thats still encrypted are the FriendlyNames related to those keys (but i could be completely wrong with that guess).
– theoka
Jan 19 at 20:43