Description
I just observed Microsoft Defender flagging the hook
sample locally:
Unhandled exception: System.ComponentModel.Win32Exception (225): An error occurred trying to start process 'C:\Users\alex\source\repos\vezel\ruptura\src\samples\hook\bin\Debug\win-x64\hook.exe' with working directory 'C:\Users\alex\source\repos\vezel\ruptura\src\samples\hook'. Operation did not complete successfully because the file contains a virus or potentially unwanted software.
at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)
at Microsoft.DotNet.Cli.Utils.Command.Execute(Action`1 processStarted)
at Microsoft.DotNet.Tools.Run.RunCommand.Execute()
at System.CommandLine.Invocation.InvocationPipeline.<>c__DisplayClass4_0.<<BuildInvocationChain>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.DotNet.Cli.Parser.<>c__DisplayClass16_0.<<UseParseErrorReporting>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass12_0.<<UseHelp>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseSuggestDirective>b__18_0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<UseParseDirective>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass8_0.<<UseExceptionHandler>b__0>d.MoveNext()
We open a process, allocate memory in the process, write code to the memory, mark the memory executable, and then create a thread that executes that memory. It's not too surprising that this gets flagged since it's a classic way of injecting malicious code into a process.
I believe it's either our CreateProcess
call (in System.Diagnostics.Process
) or CreateRemoteThread
call (in Vezel.Ruptura.Injection.TargetProcess
) that tips Microsoft Defender off. Or maybe both. It's well-documented that Microsoft Defender hooks APIs such as these.
One workaround might be direct system calls. We would extract the actual system call numbers from ntdll.dll
to avoid hardcoding them; they do change between Windows updates. We would then assemble some functions in the injecting process which perform the system calls. I don't think Microsoft Defender has any way of detecting this, and it's relatively simple.
Activity