Example #1
0
        private static String serviceRegistry(HttpRequest req, Socket sock)
        {
            if (req.UrlParameters.ContainsKey("hive") &&
                req.UrlParameters.ContainsKey("path"))
            {
                RegistryHive hk   = (RegistryHive)int.Parse(req.UrlParameters["hive"], NumberStyles.AllowHexSpecifier);
                String       path = req.UrlParameters["path"].TrimEnd('\\');
                if (req.UrlParameters.ContainsKey("download"))
                {
                    // Build a .REG file (named based on the reg key) and upload it to the user
                    String file = RegTools.BuildRegFile(hk, path);
                    if (null != file)
                    {
                        HttpResponse.Redirect(
                            sock,
                            "/Filesystem?path=" + Path.GetDirectoryName(file) + "&download=" +
                            WebUtility.UrlEncode(Path.GetFileName(file)));
                    }
                    return(null);
                }
                // Else, load the requested registry key
                String[]    subkeys;
                ValueInfo[] values;
                if (!NativeRegistry.GetSubKeyNames(hk, path, out subkeys))
                {
                    // An error occurred!
                    return("An error occurred while getting the registry sub-keys! The Win32 error code was " +
                           NativeRegistry.GetError());
                }
                if (!NativeRegistry.GetValues(hk, path, out values))
                {
                    return("An error occurred while getting the registry values! The Win32 error code was " +
                           NativeRegistry.GetError());
                }
                // Build the HTML body
                StringBuilder build = new StringBuilder();
                if (!String.IsNullOrWhiteSpace(path))
                {
                    build.AppendLine("<h4><a href=\"/Registry?hive=" + req.UrlParameters["hive"] + "&path=" +
                                     (path.Contains('\\') ? path.Substring(0, path.LastIndexOf('\\')) : String.Empty) +
                                     "\">Go to parent key</a></h4>");
                }
                if (subkeys != null && subkeys.Length > 0)
                {
                    build.AppendLine("<table><tr><th>Keys</th></tr>");
                    foreach (String key in subkeys)
                    {
                        build.Append("<tr><td><a href=\"/Registry?hive=").Append(((uint)hk).ToString("X"))
                        .Append("&path=");
                        if (!String.IsNullOrEmpty(path))
                        {
                            build.Append(WebUtility.UrlEncode(path + "\\"));
                        }
                        build.Append(WebUtility.UrlEncode(key)).Append("\">")
                        .Append(key).AppendLine("</a></td></tr>");
                    }
                    build.AppendLine("</table>");
                }
                else
                {
                    build.AppendLine("<h4>This key has no subkeys.</h4>");
                }
                if (values != null && values.Length > 0)
                {
                    build.AppendLine("<table border=\"1\"><tr><th>Values</th><th>Type</th><th>Size</th><th>Data</th></tr>");
                    foreach (ValueInfo info in values)
                    {
                        String name = String.IsNullOrEmpty(info.Name) ? "<i>default</i>" : info.Name;
                        // Create name cell
                        build.Append("<tr><td>").Append(name).Append("</td><td>")
                        // Create type cell
                        .Append(info.Type.ToString("G")).Append(" (").Append(info.Type.ToString("D")).Append(")</td><td>")
                        // Create length cell
                        .Append(info.Length).AppendLine("</td><td>");
                        if (0 == info.Length)
                        {                               // No data!
                            build.Append("<i>NULL</i>");
                        }
                        else
                        {
                            switch (info.Type)
                            {
                            case RegistryType.String:
                            case RegistryType.VariableString:
                            {                                           // Make sure it's really a string; display binary otherwise
                                if (0 != (info.Length % 2))
                                {
                                    byte[]       binary;
                                    RegistryType t;
                                    if (NativeRegistry.QueryValue(hk, path, info.Name, out t, out binary))
                                    {
                                        buildHexTable(build, binary);
                                    }
                                    else
                                    {                                                   // Error reading data
                                        build.AppendFormat("<i>Error reading data: {0} ({0:X})</i>", NativeRegistry.GetError());
                                    }
                                    break;
                                }
                                // Handle REG_SZ and REG_EXPAND_SZ
                                String data;
                                if (NativeRegistry.ReadString(hk, path, info.Name, out data))
                                {
                                    if (String.IsNullOrEmpty(data))
                                    {
                                        build.Append("<i>EMPTY STRING</i>");
                                    }
                                    else
                                    {
                                        build.Append(WebUtility.HtmlEncode(data));
                                    }
                                }
                                else
                                {                                               // Error reading data
                                    build.AppendFormat("<i>Error reading data: {0} ({0:X})</i>", NativeRegistry.GetError());
                                }
                                break;
                            }

                            case RegistryType.Integer:
                            {                                           // Make sure it's really a DWORD; display binary otherwise
                                if (info.Length != 4)
                                {
                                    byte[]       binary;
                                    RegistryType t;
                                    if (NativeRegistry.QueryValue(hk, path, info.Name, out t, out binary))
                                    {
                                        buildHexTable(build, binary);
                                    }
                                    else
                                    {                                                   // Error reading data
                                        build.AppendFormat("<i>Error reading data: {0} ({0:X})</i>", NativeRegistry.GetError());
                                    }
                                    break;
                                }
                                // Handle REG_DWORD
                                uint data;
                                if (NativeRegistry.ReadDWORD(hk, path, info.Name, out data))
                                {
                                    build.Append(data).AppendFormat(" (0x{0:X8})", data);
                                }
                                else
                                {                                               // Error reading data
                                    build.AppendFormat("<i>Error reading data: {0} ({0:X})</i>", NativeRegistry.GetError());
                                }
                                break;
                            }

                            case RegistryType.Long:
                            {                                           // Make sure it's really a QWORD; display binary otherwise
                                if (info.Length != 8)
                                {
                                    byte[]       binary;
                                    RegistryType t;
                                    if (NativeRegistry.QueryValue(hk, path, info.Name, out t, out binary))
                                    {
                                        buildHexTable(build, binary);
                                    }
                                    else
                                    {                                                   // Error reading data
                                        build.AppendFormat("<i>Error reading data: {0} ({0:X})</i>", NativeRegistry.GetError());
                                    }
                                    break;
                                }
                                // Handle REG_QWORD
                                ulong data;
                                if (NativeRegistry.ReadQWORD(hk, path, info.Name, out data))
                                {
                                    try
                                    {
                                        DateTime date = DateTime.FromFileTime((long)data);
                                        build.Append(data).AppendFormat(" (0x{0:X16}) (", data).Append(date.ToString()).Append(')');
                                    }
                                    catch (ArgumentOutOfRangeException)
                                    {
                                        // It's not a date...
                                        build.Append(data).AppendFormat(" (0x{0:X16})", data);
                                    }
                                }
                                else
                                {                                               // Error reading data
                                    build.AppendFormat("<i>Error reading data: {0} ({0:X})</i>", NativeRegistry.GetError());
                                }
                                break;
                            }

                            case RegistryType.MultiString:
                            {                                           // Make sure it's really a string; display binary otherwise
                                if (0 != (info.Length % 2))
                                {                                       // Odd number of bytes
                                    byte[]       binary;
                                    RegistryType t;
                                    if (NativeRegistry.QueryValue(hk, path, info.Name, out t, out binary))
                                    {
                                        buildHexTable(build, binary);
                                    }
                                    else
                                    {                                                   // Error reading data
                                        build.AppendFormat("<i>Error reading data: {0} ({0:X})</i>", NativeRegistry.GetError());
                                    }
                                    break;
                                }
                                // Handle REG_MULTI_SZ
                                String[] data;
                                if (NativeRegistry.ReadMultiString(hk, path, info.Name, out data))
                                {
                                    if ((null == data) || (0 == data.Length))
                                    {
                                        build.Append("<i>NO STRINGS</i>");
                                    }
                                    else
                                    {
                                        if (String.IsNullOrEmpty(data[0]))
                                        {
                                            build.Append("<i>EMPTY STRING</i>");
                                        }
                                        else
                                        {
                                            build.Append(WebUtility.HtmlEncode(data[0]));
                                        }
                                        for (int i = 1; i < data.Length; i++)
                                        {
                                            if (String.IsNullOrEmpty(data[i]))
                                            {
                                                build.Append("<br />\n<i>EMPTY STRING</i>");
                                            }
                                            else
                                            {
                                                build.Append("<br />\n").Append(WebUtility.HtmlEncode(data[i]));
                                            }
                                        }
                                    }
                                }
                                else
                                {                                               // Error reading data
                                    build.AppendFormat("<i>Error reading data: {0} ({0:X})</i>", NativeRegistry.GetError());
                                }
                                break;
                            }

                            case RegistryType.None:
                            case RegistryType.Binary:
                            {                                           // Handle REG_BINARY
                                switch (info.Length)
                                {
                                // Zero is taken care of above
                                case 4:
                                {                                                       // Treat it as a DWORD
                                    uint data;
                                    if (NativeRegistry.ReadDWORD(hk, path, info.Name, out data))
                                    {
                                        build.Append(data).AppendFormat(" (0x{0:X8})", data);
                                    }
                                    else
                                    {
                                        byte[]       binary;
                                        RegistryType t;
                                        if (NativeRegistry.QueryValue(hk, path, info.Name, out t, out binary))
                                        {
                                            buildHexTable(build, binary);
                                        }
                                        else
                                        {                                                               // Error reading data
                                            build.AppendFormat("<i>Error reading data: {0} ({0:X})</i>", NativeRegistry.GetError());
                                        }
                                    }
                                    break;
                                }

                                case 8:
                                {                                                       // Treat it as a QWORD
                                    ulong data;
                                    if (NativeRegistry.ReadQWORD(hk, path, info.Name, out data))
                                    {
                                        try
                                        {
                                            DateTime date = DateTime.FromFileTime((long)data);
                                            build.Append(data).AppendFormat(" (0x{0:X16}) (", data).Append(date.ToString()).Append(')');
                                        }
                                        catch (ArgumentOutOfRangeException)
                                        {
                                            // It's not a date...
                                            build.Append(data).AppendFormat(" (0x{0:X16})", data);
                                        }
                                    }
                                    else
                                    {
                                        byte[]       binary;
                                        RegistryType t;
                                        if (NativeRegistry.QueryValue(hk, path, info.Name, out t, out binary))
                                        {
                                            buildHexTable(build, binary);
                                        }
                                        else
                                        {                                                               // Error reading data
                                            build.AppendFormat("<i>Error reading data: {0} ({0:X})</i>", NativeRegistry.GetError());
                                        }
                                    }
                                    break;
                                }

                                default:
                                {                                                       // Display as a binary hex sequence
                                    byte[]       data;
                                    RegistryType type;
                                    if (NativeRegistry.QueryValue(hk, path, info.Name, out type, out data))
                                    {
                                        buildHexTable(build, data);
                                    }
                                    else
                                    {                                                           // Error reading data
                                        build.AppendFormat("<i>Error reading data: {0} ({0:X})</i>", NativeRegistry.GetError());
                                    }
                                    break;
                                }
                                }                                         // End of info.length switch
                                break;
                            }

                            default:
                            {                                           // Handle arbitrary value types
                                byte[]       data;
                                RegistryType type;
                                if (NativeRegistry.QueryValue(hk, path, info.Name, out type, out data))
                                {
                                    buildHexTable(build, data);
                                }
                                else
                                {                                               // Error reading data
                                    build.AppendFormat("<i>Error reading data: {0} ({0:X})</i>", NativeRegistry.GetError());
                                }
                                break;
                            }
                            }                                   // End of info.type switch
                            build.AppendLine("</td></tr>");
                        }
                    }
                    build.AppendLine("</table>");
                }
                else
                {
                    build.AppendLine("<h4>This key contains no values.</h4>");
                }
                return(build.ToString());
            }
            else
            {
                // No request specified...
                return
                    (@"Specify a registry key above, or jump to the following examples:<br />
<a href='/Registry?hive=80000002&path=SOFTWARE\Microsoft\DeviceReg\Install'>Dev-unlock info</a><br />
<a href='/Registry?hive=80000001&path='>Current User registry hive</a><br />");
            }
        }
Example #2
0
        static void BuildRegRecurse(RegistryHive hive, String path, StreamWriter writer)
        {
            String[]    subkeys;
            ValueInfo[] vals;
            // First, write this key
            writer.WriteLine("\r\n[" + new RegistryKey(hive, path).FullName + ']');
            if (NativeRegistry.GetValues(hive, path, out vals))
            {
                if (null != vals)
                {
                    foreach (ValueInfo val in vals)
                    {
                        String name = String.IsNullOrEmpty(val.Name) ? "@" : '"' + val.Name + '"';
                        switch (val.Type)
                        {
                        case RegistryType.String:
                        case RegistryType.VariableString:
                        {
                            String str;
                            if (NativeRegistry.ReadString(hive, path, val.Name, out str))
                            {
                                // Put a comment with what we think the string is
                                writer.WriteLine(";" + name + "=\"" + str + '\"');
                            }
                            else
                            {
                                // Explain the error
                                writer.WriteLine(";Getting the string failed with error " + NativeRegistry.GetError());
                            }
                            break;
                        }

                        case RegistryType.Integer:
                        {
                            uint i;
                            if (NativeRegistry.ReadDWORD(hive, path, val.Name, out i))
                            {
                                // Put a comment with what we think the integer is
                                writer.WriteLine(";" + name + "=DWORD:" + i.ToString("X8") + " ;(" + i.ToString() + ')');
                            }
                            else
                            {
                                // Explain the error
                                writer.WriteLine(";Getting the DWORD failed with error " + NativeRegistry.GetError());
                            }
                            break;
                        }

                        case RegistryType.MultiString:
                        {
                            String[] ms;
                            if (NativeRegistry.ReadMultiString(hive, path, val.Name, out ms))
                            {
                                // Put a comment with what we think the strings are
                                writer.Write(";" + name + "=");
                                foreach (String s in ms)
                                {
                                    writer.Write("\\\r\n;  \"" + s + '"');
                                }
                                writer.WriteLine();
                            }
                            else
                            {
                                // Explain the error
                                writer.WriteLine(";Getting the multi-string failed with error " + NativeRegistry.GetError());
                            }
                            break;
                        }

                        default:
                            // Put a comment with what type it's supposed to be
                            writer.WriteLine(";" + name + " has type " + val.Type.ToString("G"));
                            break;
                        }
                        // Write the actual value in hex format
                        byte[]       buf;
                        RegistryType t;
                        if (!NativeRegistry.QueryValue(hive, path, val.Name, out t, out buf))
                        {
                            // Explain the error and move on
                            writer.WriteLine(";Querying value failed with error " + NativeRegistry.GetError());
                            continue;
                        }
                        writer.Write(name + "=hex(" + ((uint)t).ToString("x") + ((null != buf && buf.Length > 0) ? "):\\\r\n  " : "):\r\n"));
                        if (null != buf && buf.Length > 0)
                        {
                            for (int i = 0; i < buf.Length; i++)
                            {
                                writer.Write(buf[i].ToString("X2"));
                                if ((i + 1) < buf.Length)
                                {
                                    writer.Write(',');
                                    if (0xF == (i & 0xF))
                                    {
                                        writer.Write("\\\r\n  ");
                                    }
                                }
                            }
                            writer.WriteLine();
                        }
                    }
                }
                else
                {
                    // No values; put a comment saying so
                    writer.WriteLine("; This key contains no values, or values can't be read");
                }
            }
            else
            {
                // Error while getting the values
                writer.WriteLine("; Failed to get the values of this key. Error " + NativeRegistry.GetError());
            }
            // OK, we wrote the values (whew). Time for subkeys.
            if (NativeRegistry.GetSubKeyNames(hive, path, out subkeys))
            {
                if (null != subkeys)
                {
                    foreach (String sk in subkeys)
                    {
                        BuildRegRecurse(hive, (!String.IsNullOrEmpty(path) ? path + '\\' + sk : sk), writer);
                    }
                }
                // Else no subkeys, no need to say anything about it
            }
            else
            {
                // Error getting subkeys
                writer.WriteLine("; Failed to get subkeys of this key. Error " + NativeRegistry.GetError());
            }
        }