Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion DefenderCheck/DefenderCheck/DefenderCheck.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<PlatformTarget>x64</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
Expand All @@ -32,6 +33,9 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<NoWin32Manifest>true</NoWin32Manifest>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
Expand Down
157 changes: 54 additions & 103 deletions DefenderCheck/DefenderCheck/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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)
{
Expand All @@ -174,7 +122,9 @@ public static ScanResult Scan(string file, bool getsig = false)
}
}
}


File.Delete(tmpFile);

switch (process.ExitCode)
{
case 0:
Expand All @@ -184,9 +134,10 @@ public static ScanResult Scan(string file, bool getsig = false)
default:
return ScanResult.Error;
}

}


public enum ScanResult
{
[Description("No threat found")]
Expand Down