diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f8431e..8d7eeba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,15 @@ # Changelog +# 1.2.20.0 +## 10/04/2015 + +* Added more information under Autoruns about almost everything that loads with the system +* Added autorunsc.exe from Sysinternals into projected [Embedded] +* Changed reports are now generated with parallel threads, 100% boost over single thread on most cases - More cores more benefits + + # 1.2.0.0 +## 09/04/2015 * Added a new report about system info * Changed old system info report to hardware @@ -8,12 +17,14 @@ # 1.1.10.0 +## 08/04/2015 * Added a timer on GUI to inform the elapsed time in seconds * Changed the whole reports system [Internal] # 1.1.0.0 +## 07/04/2015 * Added PnP devices * Added Network devices @@ -22,6 +33,8 @@ * Improved template responsive styles * Internal improvements + # 1.0.0.0 +## 06/04/2015 * First Release \ No newline at end of file diff --git a/README.md b/README.md index 4f133c6..9b22d3e 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ You can share the generated report with your friend or someone of your trust to 4. PnP Devices 5. Processes 6. Services -7. Startup Applications +7. Autoruns 8. Installed programs # GUI Screenshot diff --git a/SystemInfoSnapshot/Autoruns.cs b/SystemInfoSnapshot/Autoruns.cs new file mode 100644 index 0000000..231c949 --- /dev/null +++ b/SystemInfoSnapshot/Autoruns.cs @@ -0,0 +1,211 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Diagnostics; +using System.IO; + +namespace SystemInfoSnapshot +{ + /// + /// Sysinternals Autoruns v13.2 - Autostart program viewer + /// Copyright (C) 2002-2015 Mark Russinovich + /// Sysinternals - www.sysinternals.com + /// Autorunsc shows programs configured to autostart during boot. + /// Usage: autorunsc [-a <*|bdeghiklmoprsw>] [-c|-ct] [-h] [-m] [-s] [-u] [-vt] [[-z ] | [user]]] + /// -a Autostart entry selection: + /// * All. + /// b Boot execute. + /// d Appinit DLLs. + /// e Explorer addons. + /// g Sidebar gadgets (Vista and higher) + /// h Image hijacks. + /// i Internet Explorer addons. + /// k Known DLLs. + /// l Logon startups (this is the default). + /// m WMI entries. + /// n Winsock protocol and network providers. + /// o Codecs. + /// p Printer monitor DLLs. + /// r LSA security providers. + /// s Autostart services and non-disabled drivers. + /// t Scheduled tasks. + /// w Winlogon entries. + /// -c Print output as CSV. + /// -ct Print output as tab-delimited values. + /// -h Show file hashes. + /// -m Hide Microsoft entries (signed entries if used with -v). + /// -s Verify digital signatures. + /// -t Show timestamps in normalized UTC (YYYYMMDD-hhmmss). + /// -u If VirusTotal check is enabled, show files that are unknown by VirusTotal or have non-zero detection, otherwise show only unsigned files. + /// -x Print output as XML. + /// -v[rs] Query VirusTotal (www.virustotal.com) for malware based on file hash. + /// Add 'r' to open reports for files with non-zero detection. Files + /// reported as not previously scanned will be uploaded to VirusTotal + /// if the 's' option is specified. Note scan results may not be + /// available for five or more minutes. + /// -vt Before using VirusTotal features, you must accept VirusTotal terms of service. See: + /// https://www.virustotal.com/en/about/terms-of-service/ + /// + /// If you haven't accepted the terms and you omit this option, you will be interactively prompted. + /// -z Specifies the offline Windows system to scan. + /// user Specifies the name of the user account for which autorun items will be shown. Specify '*' to scan all user profiles. + /// + public sealed class Autoruns : IDisposable + { + public sealed class AutorunEntry + { + //Time,Entry Location,Entry,Enabled,Category,Profile,Description,Publisher,Image Path,Version,Launch String + + public DateTime Time { get; set; } + public string EntryLocation { get; set; } + public string Entry { get; set; } + public bool Enabled { get; set; } + public string Category { get; set; } + public string Profile { get; set; } + public string Description { get; set; } + public string Publisher { get; set; } + public string ImagePath { get; set; } + public string Version { get; set; } + public string LunchString { get; set; } + + public bool IsValidFile { get; set; } + + public AutorunEntry() + { + } + } + public string ExecutableFile { get; private set; } + public List AutorunEntries { get; private set; } + public Autoruns() + { + AutorunEntries = new List(); + } + + public void BuildEntries() + { + try + { + if (string.IsNullOrEmpty(ExecutableFile)) + { + ExecutableFile = Path.Combine(Path.GetTempPath(), "autorunsc.exe"); + File.WriteAllBytes(ExecutableFile, Properties.Resources.autorunsc); + } + using (var proc = new Process()) + { + proc.StartInfo.FileName = ExecutableFile; + proc.StartInfo.Arguments = "-a * -m -c"; + proc.StartInfo.CreateNoWindow = true; + proc.StartInfo.UseShellExecute = false; + proc.StartInfo.RedirectStandardOutput = true; + proc.Start(); + int i = 0; + while (!proc.StandardOutput.EndOfStream) + { + i++; + string line = proc.StandardOutput.ReadLine(); + if (i == 1 || string.IsNullOrEmpty(line)) + continue; + + var args = line.Split(','); + if (args.Length != 11) + continue; + for (var index = 0; index < args.Length; index++) + { + args[index] = args[index].Replace("\"", string.Empty); + } + + byte argc = 0; + AutorunEntry entry = new AutorunEntry(); + if (!string.IsNullOrEmpty(args[argc])) + { + DateTime result; + DateTime.TryParse(args[argc], out result); + entry.Time = result; + } + + argc++; + entry.EntryLocation = args[argc]; + + argc++; + entry.Entry = args[argc]; + + argc++; + entry.Enabled = args[argc].Equals("enabled"); + + argc++; + entry.Category = args[argc]; + + argc++; + entry.Profile = args[argc]; + + argc++; + entry.Description = args[argc]; + + argc++; + entry.Publisher = args[argc]; + + argc++; + entry.ImagePath = args[argc]; + + argc++; + entry.Version = args[argc]; + + argc++; + entry.LunchString = args[argc]; + + if (!entry.ImagePath.StartsWith("File not found:")) + { + entry.IsValidFile = true; + } + + AutorunEntries.Add(entry); + } + + proc.Close(); + } + } + catch (Exception) + { + // ignored + } + } + + public Dictionary> GetAsDictionary() + { + if(AutorunEntries.Count == 0) + BuildEntries(); + + var dict = new Dictionary>(); + foreach (var autorunEntry in AutorunEntries) + { + if (!dict.ContainsKey(autorunEntry.Category)) + { + dict.Add(autorunEntry.Category, new List()); + } + + dict[autorunEntry.Category].Add(autorunEntry); + } + return dict; + } + + public void Clear() + { + if (!string.IsNullOrEmpty(ExecutableFile)) return; + + try + { + File.Delete(ExecutableFile); + ExecutableFile = null; + } + catch (Exception) + { + // ignored + } + } + + public void Dispose() + { + Clear(); + } + } +} diff --git a/SystemInfoSnapshot/Properties/AssemblyInfo.cs b/SystemInfoSnapshot/Properties/AssemblyInfo.cs index aa90ce2..a029dc6 100644 --- a/SystemInfoSnapshot/Properties/AssemblyInfo.cs +++ b/SystemInfoSnapshot/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.2.0.0")] -[assembly: AssemblyFileVersion("1.2.0.0")] +[assembly: AssemblyVersion("1.2.20.0")] +[assembly: AssemblyFileVersion("1.2.20.0")] diff --git a/SystemInfoSnapshot/Properties/Resources.Designer.cs b/SystemInfoSnapshot/Properties/Resources.Designer.cs index 3ff720b..89d7255 100644 --- a/SystemInfoSnapshot/Properties/Resources.Designer.cs +++ b/SystemInfoSnapshot/Properties/Resources.Designer.cs @@ -60,6 +60,16 @@ internal Resources() { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] autorunsc { + get { + object obj = ResourceManager.GetObject("autorunsc", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/SystemInfoSnapshot/Properties/Resources.resx b/SystemInfoSnapshot/Properties/Resources.resx index bed6a44..9ca1459 100644 --- a/SystemInfoSnapshot/Properties/Resources.resx +++ b/SystemInfoSnapshot/Properties/Resources.resx @@ -136,4 +136,7 @@ ..\Resources\images\web.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\executables\autorunsc.exe;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + \ No newline at end of file diff --git a/SystemInfoSnapshot/Reports/Report.cs b/SystemInfoSnapshot/Reports/Report.cs index d67a656..0f13858 100644 --- a/SystemInfoSnapshot/Reports/Report.cs +++ b/SystemInfoSnapshot/Reports/Report.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Reflection; +using System.Threading.Tasks; namespace SystemInfoSnapshot.Reports { @@ -29,7 +30,16 @@ public enum ReportStatus : byte /// Html string /// public string Html { get; protected set; } + + /// + /// Gets the report status + /// public ReportStatus Status { get; private set; } + + /// + /// Gets if this report worth from async + /// + public bool CanAsync { get; protected set; } #endregion #region Constructor @@ -40,6 +50,7 @@ protected Report() { Html = string.Empty; Status = ReportStatus.None; + CanAsync = true; } #endregion @@ -129,20 +140,31 @@ public static Report[] GetReports() public static HtmlTemplate GenerateReports(Report[] reports, bool saveReport = true) { var htmlTemplate = new HtmlTemplate(); - /*Parallel.ForEach(reports, report => + /*List asyncReports = new List(); + foreach (var report in reports) { - Debug.WriteLine(report.GetTemplateVar()); + if (report.CanAsync) + { + Debug.WriteLine(report.CanAsync); + asyncReports.Add(report); + continue; + } report.Generate(); - //if (ReferenceEquals(htmlTemplate, null)) continue; htmlTemplate.WriteFromVar(report.GetTemplateVar(), report.Html); - });*/ - foreach (var report in reports) + }*/ + + Parallel.ForEach(reports, report => { + //Debug.WriteLine(report.GetTemplateVar()); report.Generate(); - //if (ReferenceEquals(htmlTemplate, null)) continue; - htmlTemplate.WriteFromVar(report.GetTemplateVar(), report.Html); - } + + lock (htmlTemplate.TemplateHTML) + { + htmlTemplate.WriteFromVar(report.GetTemplateVar(), report.Html); + } + }); + if (/*!ReferenceEquals(htmlTemplate, null) && */saveReport) { diff --git a/SystemInfoSnapshot/Reports/Startup.cs b/SystemInfoSnapshot/Reports/Startup.cs index 1dbcee0..a27a3cc 100644 --- a/SystemInfoSnapshot/Reports/Startup.cs +++ b/SystemInfoSnapshot/Reports/Startup.cs @@ -1,18 +1,21 @@ using System; +using System.Collections.Generic; using System.Globalization; namespace SystemInfoSnapshot.Reports { public sealed class Startup : Report { - public const string TemplateVar = ""; + public const string TemplateVar = ""; + public override string GetTemplateVar() { return TemplateVar; } - protected override void Build() + // OLD BUILD + /*protected override void Build() { var result = "" + "" + @@ -39,6 +42,88 @@ protected override void Build() result += "
"; + Html = result; + }*/ + + protected override void Build() + { + var icons = new Dictionary + { + {"Logon", "fa fa-sign-in"}, + {"Explorer", "fa fa-folder"}, + {"Internet Explorer", "fa fa-globe"}, + {"Tasks", "fa fa-clock-o"}, + {"Services", "fa fa-cogs"}, + {"Drivers", "fa fa-desktop"}, + {"Codecs", "fa fa-play-circle"}, + {"Boot Execute", ""}, + {"Hijacks", ""}, + {"Known DLLs", "fa fa-file-o"}, + {"Winlogon", ""}, + {"Print Monitors", "fa fa-print"}, + {"LSA Providers", "fa fa-shield"}, + {"Network Providers", "fa fa-wifi"}, + {"WDM", ""}, + {"Sidebar Gadgets", ""}, + }; + var autoruns = new Autoruns(); + autoruns.BuildEntries(); + var autorunsDict = autoruns.GetAsDictionary(); + + var result = "
    "; + foreach (var autorunDict in autorunsDict) + { + result += string.Format("
  • {1} ({3})
  • ", (autorunDict.Key.Equals("Logon") ? "active" : string.Empty), autorunDict.Key, autorunDict.Key.Replace(" ", ""), autorunDict.Value.Count, icons[autorunDict.Key]); + } + result += "
"; + + + + var i = 0; + result += "
"; + foreach (var autorunDict in autorunsDict) + { + result += string.Format("
", (autorunDict.Key.Equals("Logon") ? " active" : string.Empty), autorunDict.Key.Replace(" ", "")); + if (autorunDict.Value.Count == 0) + { + result += "

No autorun entries under this category

"; + continue; + } + result += "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + ""; + i = 0; + foreach (var autorunEntry in autorunDict.Value) + { + i++; + var extraClass = string.Empty; + if (!autorunEntry.IsValidFile) + { + extraClass = "warning"; + } + result += "" + + "" + + "" + + "" + + "" + + "" + + "" + + ""; + } + result += "
#EnabledEntryDescriptionPublisherImage Path
" + i + "" + (autorunEntry.Enabled ? "" : "") + "" + autorunEntry.Entry + "" + autorunEntry.Description + "" + autorunEntry.Publisher + "" + autorunEntry.ImagePath + "
"; + result += "
"; + } + result += "
"; + Html = result; } } diff --git a/SystemInfoSnapshot/Reports/SystemInfo.cs b/SystemInfoSnapshot/Reports/SystemInfo.cs index fd46a5b..02c338d 100644 --- a/SystemInfoSnapshot/Reports/SystemInfo.cs +++ b/SystemInfoSnapshot/Reports/SystemInfo.cs @@ -8,6 +8,11 @@ public sealed class SystemInfo : Report { public const string TemplateVar = ""; + public SystemInfo() + { + CanAsync = false; + } + public override string GetTemplateVar() { return TemplateVar; diff --git a/SystemInfoSnapshot/Reports/Title.cs b/SystemInfoSnapshot/Reports/Title.cs index b7f85ff..25bffef 100644 --- a/SystemInfoSnapshot/Reports/Title.cs +++ b/SystemInfoSnapshot/Reports/Title.cs @@ -7,6 +7,11 @@ public sealed class Title : Report { public const string TemplateVar = ""; + public Title() + { + CanAsync = false; + } + public override string GetTemplateVar() { return TemplateVar; diff --git a/SystemInfoSnapshot/Reports/Version.cs b/SystemInfoSnapshot/Reports/Version.cs index 6c94816..bd791c1 100644 --- a/SystemInfoSnapshot/Reports/Version.cs +++ b/SystemInfoSnapshot/Reports/Version.cs @@ -4,6 +4,11 @@ public sealed class Version : Report { public const string TemplateVar = ""; + public Version() + { + CanAsync = false; + } + public override string GetTemplateVar() { return TemplateVar; diff --git a/SystemInfoSnapshot/Resources/executables/autorunsc.exe b/SystemInfoSnapshot/Resources/executables/autorunsc.exe new file mode 100644 index 0000000..e2fdfe1 Binary files /dev/null and b/SystemInfoSnapshot/Resources/executables/autorunsc.exe differ diff --git a/SystemInfoSnapshot/Resources/template.html b/SystemInfoSnapshot/Resources/template.html index b4c24c4..63166ed 100644 --- a/SystemInfoSnapshot/Resources/template.html +++ b/SystemInfoSnapshot/Resources/template.html @@ -140,7 +140,7 @@
  • PnP Devices
  • Processes
  • Services
  • -
  • Startup
  • +
  • Autoruns
  • Programs
  • @@ -202,10 +202,10 @@

    -
    -

    Startup Applications

    +
    +

    Autoruns

    - +
    @@ -261,11 +261,11 @@

    + @@ -160,6 +161,7 @@ +