properly decipher registry REG_BINARY with python 3 winreg?












0















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.










share|improve this question

























  • 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


















0















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.










share|improve this question

























  • 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
















0












0








0








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.










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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





















  • 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



















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














1 Answer
1






active

oldest

votes


















0














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 current Render value.


  • D:PShelltestsMMDEVAPI_Journal_Registry.ps1 x plays a system sound before retrieving the Render value (added after the Render value suddenly became zeroized for unknown reason).


  • D:PShelltestsMMDEVAPI_Journal_Registry.ps1 -InformationAction Continue prints additional analysis of the Strange_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





share|improve this answer























    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
    });


    }
    });














    draft saved

    draft discarded


















    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









    0














    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 current Render value.


    • D:PShelltestsMMDEVAPI_Journal_Registry.ps1 x plays a system sound before retrieving the Render value (added after the Render value suddenly became zeroized for unknown reason).


    • D:PShelltestsMMDEVAPI_Journal_Registry.ps1 -InformationAction Continue prints additional analysis of the Strange_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





    share|improve this answer




























      0














      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 current Render value.


      • D:PShelltestsMMDEVAPI_Journal_Registry.ps1 x plays a system sound before retrieving the Render value (added after the Render value suddenly became zeroized for unknown reason).


      • D:PShelltestsMMDEVAPI_Journal_Registry.ps1 -InformationAction Continue prints additional analysis of the Strange_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





      share|improve this answer


























        0












        0








        0







        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 current Render value.


        • D:PShelltestsMMDEVAPI_Journal_Registry.ps1 x plays a system sound before retrieving the Render value (added after the Render value suddenly became zeroized for unknown reason).


        • D:PShelltestsMMDEVAPI_Journal_Registry.ps1 -InformationAction Continue prints additional analysis of the Strange_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





        share|improve this answer













        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 current Render value.


        • D:PShelltestsMMDEVAPI_Journal_Registry.ps1 x plays a system sound before retrieving the Render value (added after the Render value suddenly became zeroized for unknown reason).


        • D:PShelltestsMMDEVAPI_Journal_Registry.ps1 -InformationAction Continue prints additional analysis of the Strange_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






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 11 hours ago









        JosefZJosefZ

        15.7k42040




        15.7k42040






























            draft saved

            draft discarded




















































            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.




            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            Liquibase includeAll doesn't find base path

            How to use setInterval in EJS file?

            Petrus Granier-Deferre