diff --git a/DefenderCheck/DefenderCheck/DefenderCheck.csproj b/DefenderCheck/DefenderCheck/DefenderCheck.csproj index beaa935..32a9b6c 100644 --- a/DefenderCheck/DefenderCheck/DefenderCheck.csproj +++ b/DefenderCheck/DefenderCheck/DefenderCheck.csproj @@ -14,7 +14,7 @@ true - AnyCPU + x64 true full false @@ -22,6 +22,7 @@ DEBUG;TRACE prompt 4 + false AnyCPU @@ -32,6 +33,9 @@ prompt 4 + + true + diff --git a/DefenderCheck/DefenderCheck/Program.cs b/DefenderCheck/DefenderCheck/Program.cs index 6e775de..0b8fb55 100755 --- a/DefenderCheck/DefenderCheck/Program.cs +++ b/DefenderCheck/DefenderCheck/Program.cs @@ -9,139 +9,87 @@ namespace DefenderCheck { class Program { + private static string DefenderPath = Path.Combine(Environment.GetEnvironmentVariable("ProgramFiles"), "Windows Defender", "MpCmdRun.exe"); + static void Main(string[] args) { - //Setup(); - bool debug = false; - if (args.Length == 2 && args[1].Contains("debug")) - { - debug = true; - } - string targetfile = args[0]; if (!File.Exists(targetfile)) { Console.WriteLine("[-] Can't access the target file"); return; } - - string originalFileDetectionStatus = Scan(targetfile).ToString(); - if (originalFileDetectionStatus.Equals("NoThreatFound")) - { - if (debug) { Console.WriteLine("Scanning the whole file first"); } - Console.WriteLine("[+] No threat found in submitted file!"); - return; - } - - if (!Directory.Exists(@"C:\Temp")) - { - Console.WriteLine(@"[-] C:\Temp doesn't exist. Creating it..."); - Directory.CreateDirectory(@"C:\Temp"); - } - - string testfilepath = @"C:\Temp\testfile.exe"; + byte[] originalfilecontents = File.ReadAllBytes(targetfile); - int originalfilesize = originalfilecontents.Length; - Console.WriteLine("Target file size: {0} bytes", originalfilecontents.Length); - Console.WriteLine("Analyzing...\n"); + int left = 0; + int mid = originalfilecontents.Length - 1; + int right = mid; - byte[] splitarray1 = new byte[originalfilesize/2]; - Buffer.BlockCopy(originalfilecontents, 0, splitarray1, 0, originalfilecontents.Length / 2); - int lastgood = 0; + bool threatFound = false; while (true) { - if (debug) { Console.WriteLine("Testing {0} bytes", splitarray1.Length); } - File.WriteAllBytes(testfilepath, splitarray1); - string detectionStatus = Scan(testfilepath).ToString(); - if (detectionStatus.Equals("ThreatFound")) - { - if (debug) { Console.WriteLine("Threat found. Halfsplitting again..."); } - byte[] temparray = HalfSplitter(splitarray1, lastgood); - Array.Resize(ref splitarray1, temparray.Length); - Array.Copy(temparray, splitarray1, temparray.Length); - } - else if (detectionStatus.Equals("NoThreatFound")) - { - if (debug) { Console.WriteLine("No threat found. Going up 50% of current size."); }; - lastgood = splitarray1.Length; - byte[] temparray = Overshot(originalfilecontents, splitarray1.Length); //Create temp array with 1.5x more bytes - Array.Resize(ref splitarray1, temparray.Length); - Buffer.BlockCopy(temparray, 0, splitarray1, 0, temparray.Length); - } - } - } - - //public static void Setup() - //{ - // RegistryKey defenderService = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Policies\Microsoft\Windows Defender"); - // object defenderServiceValue = defenderService.GetValue("DisableAntiSpyware"); - // if (!defenderServiceValue.Equals(0)) //This is the case in situations like Commando - // { - // Console.WriteLine("[-] The defender antispyware service is not enabled, so MpCmdRun will fail. Exiting..."); - // Environment.Exit(1); - // } - // defenderService.Close(); - - // if (!Directory.Exists(@"C:\temp")) - // { - // Console.WriteLine(@"[-] C:\Temp\ doesn't exist. Creating it."); - // Directory.CreateDirectory(@"C:\Temp"); - // } + // Scan the file + ScanResult r = Scan(originalfilecontents, mid); - //} + if (r == ScanResult.ThreatFound) + { + threatFound = true; - public static byte[] HalfSplitter(byte[] originalarray, int lastgood) //Will round down to nearest int - { - byte[] splitarray = new byte[(originalarray.Length - lastgood)/2+lastgood]; - if (originalarray.Length == splitarray.Length +1) - { - Console.WriteLine("[!] Identified end of bad bytes at offset 0x{0:X} in the original file", originalarray.Length); - Scan(@"C:\Temp\testfile.exe", true); - byte[] offendingBytes = new byte[256]; + // If it's stil a threat, search a smaller segment: + right = mid; + mid = left + ((mid - left) / 2); - if (originalarray.Length < 256) + if (right == mid) + { + // No change, we're done. + break; + } + } + else if (r == ScanResult.NoThreatFound) { - Array.Resize(ref offendingBytes, originalarray.Length); - Buffer.BlockCopy(originalarray, originalarray.Length, offendingBytes, 0, originalarray.Length); + // We skipped the bad part, expand! + left = mid; + mid = mid + ((right - mid) / 2); + + if (left == mid) + { + // No change, we're done. + break; + } } else { - Buffer.BlockCopy(originalarray, originalarray.Length - 256, offendingBytes, 0, 256); + Console.WriteLine("Unexpected scan result: {0}. Aborting.", r); + break; } - HexDump(offendingBytes, 16); - File.Delete(@"C:\Temp\testfile.exe"); - Environment.Exit(0); } - Array.Copy(originalarray, splitarray, splitarray.Length); - return splitarray; - } - public static byte[] Overshot(byte[] originalarray, int splitarraysize) - { - int newsize = (originalarray.Length - splitarraysize) / 2 + splitarraysize; - if (newsize.Equals(originalarray.Length-1)) + if (threatFound) + { + Console.WriteLine("Threat found at byte 0x{0:X}:", mid); + int max = mid < 256 ? mid : 256; + byte[] tmp = new byte[max]; + Buffer.BlockCopy(originalfilecontents, mid - max, tmp, 0, max); + HexDump(tmp); + } else { - Console.WriteLine("Exhausted the search. The binary looks good to go!"); - Environment.Exit(0); + Console.WriteLine("No threats found!"); } - byte[] newarray = new byte[newsize]; - Buffer.BlockCopy(originalarray, 0, newarray, 0, newarray.Length); - return newarray; } - //Adapted from https://github.com/yolofy/AvScan/blob/master/src/AvScan.WindowsDefender/WindowsDefenderScanner.cs - public static ScanResult Scan(string file, bool getsig = false) + public static ScanResult Scan(byte[] fileBytes, int length, bool getsig = false) { - if (!File.Exists(file)) + string tmpFile = Path.GetTempFileName(); + using (FileStream fs = File.OpenWrite(tmpFile)) { - return ScanResult.FileNotFound; + fs.Write(fileBytes, 0, length); } var process = new Process(); - var mpcmdrun = new ProcessStartInfo(@"C:\Program Files\Windows Defender\MpCmdRun.exe") + var mpcmdrun = new ProcessStartInfo(DefenderPath) { - Arguments = $"-Scan -ScanType 3 -File \"{file}\" -DisableRemediation -Trace -Level 0x10", + Arguments = $"-Scan -ScanType 3 -File \"{tmpFile}\" -DisableRemediation -Trace -Level 0x10", CreateNoWindow = true, ErrorDialog = false, UseShellExecute = false, @@ -151,7 +99,7 @@ public static ScanResult Scan(string file, bool getsig = false) process.StartInfo = mpcmdrun; process.Start(); - process.WaitForExit(30000); //Wait 30s + process.WaitForExit(30000); //Wait up to 30s if (!process.HasExited) { @@ -174,7 +122,9 @@ public static ScanResult Scan(string file, bool getsig = false) } } } - + + File.Delete(tmpFile); + switch (process.ExitCode) { case 0: @@ -184,9 +134,10 @@ public static ScanResult Scan(string file, bool getsig = false) default: return ScanResult.Error; } - + } + public enum ScanResult { [Description("No threat found")]