Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c# Registry System.Byte[] to string

I am currently writing a program that will read part of the windows system registry however some of the values of these keys are of type System.Byte[] when i try and decode these values I can produce a string that has some readable characters that makes but mostly the string is jiberish. I have tried several encoding types but none seem to produce the correct results. I am just wondering if there is anything that is known to fix this. this is the code i have

public void getMRU()
{
   String mru = @"Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSavePidlMRU";

   RegistryKey rk = Registry.CurrentUser.OpenSubKey(mru);

   foreach (string skName in rk.GetSubKeyNames())
   {
       RegistryKey sk = rk.OpenSubKey(skName);

       System.Text.Encoding enc = System.Text.Encoding.UTF8;
       string myString = enc.GetString((Byte[])sk.GetValue("0"));
       Console.WriteLine(myString)
   }
}
like image 938
SteveCapegoat Avatar asked Jul 06 '26 13:07

SteveCapegoat


2 Answers

The correct decoding and interpretation varies from key to key. For binary values there is no enforced format, applications are free to store any bytes they wish. You must know what you read in order to interpret it. If the key content is documented, then you can apply the documentation specifications to decode the content. If is undocumented, then you have no business reading it.

like image 98
Remus Rusanu Avatar answered Jul 08 '26 04:07

Remus Rusanu


Perhaps this is no longer an issue, but to help anyone else who might encounter this problem consider the following:

A PIDL, or pointer to an item identifier list only exists in Windows NT 6.x (Vista, Win7) and actually starts at the desktop rather than C:\... (I believe this was done due to the introduction of "libraries"). Thus, you need special handling to extract a file path from a PIDL.

The following method, GetPathFromPIDL(), will take a registry key's (byte[]) byteCode and covert it to a platform specific IntPtr. Then we take the IntPtr (given that it is a PIDL) and call the P/Invoke method SHGetPathFromIDListW(), which will put the string representation of the PIDL in our StringBuilder.

private string GetPathFromPIDL(byte[] byteCode)
    {
        //MAX_PATH = 260
        StringBuilder builder = new StringBuilder(260);

        IntPtr ptr = IntPtr.Zero;
        GCHandle h0 = GCHandle.Alloc(byteCode, GCHandleType.Pinned);
        try
        {
            ptr = h0.AddrOfPinnedObject();
        }
        finally
        {
            h0.Free();
        }

        SHGetPathFromIDListW(ptr, builder);

        return builder.ToString();
    }

Prototype for SHGetPathFromIDListW():

[DllImport("shell32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SHGetPathFromIDListW(IntPtr pidl, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder pszPath);
like image 26
matt.schechtman Avatar answered Jul 08 '26 02:07

matt.schechtman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!