However, the memory patching approach is quite noisy from an attacker perspective because it can raise several alerts during memory integrity checks and also on modification itself. The memory region permissions usually need to be modified with read-write attributes by leveraging a memory protection function (VirtualProtect, NtProtectVirtualMemory
). This can be monitored and detected by security products.
To avoid these behaviors and evade detection, red team operators and malware authors started to skip these “active memory manipulation” techniques. Instead, they manipulate execution flow when specific functions are called by a process. There are several ways to “hook” these functions. A good example recently observed is programmatically placing hardware breakpoints on that function address and handling the execution on raised exceptions.
“Debug registers are privileged resources; a MOV instruction that accesses these registers can only be executed in real-address mode, in SMM or in protected mode at a CPL of 0.”
Hardware Breakpoints and Vectored Exception Handler
Hardware Breakpoints
On exception handling, a CONTEXT struct — of the thread that raised the exception — is passed to the VEH. An attacker can edit that struct in order to manipulate execution on that address by setting the RIP
(on x64) register, when resuming from that exception. Malware also uses this technique for anti-analysis, an issue we explored in a previous blog post about an advanced anti-analysis techniques discovered in GuLoader.
Our research and presentations focus on the challenge of these “silent” patchless AMSI attacks.
Note: Intel’s manual also specifies that the user space processes cannot access these resources:
Vectored Exception Handler
On Windows, as specified in MSDN documentation, it is possible to programmatically handle a specific exception by registering a VECTORED_EXCEPTION_HANDLER (VEH), which will manage the execution to handle that condition. In the case of a Debug Exception, the operating system will populate an EXCEPTION_POINTERS struct pointing to an EXCEPTION_RECORD with an ExceptionCode
of EXCEPTION_SINGLE_STEP
(0x80000004
)and ExceptionAddress
pointing to the hooked address.
According to Intel’s 64 and IA-32 Architectures Software Developer’s Manual, the DR0-DR3
debug registers contain the addresses of hardware (HW) breakpoints. When accessing a referenced location (in combination with the other DR registers), the CPU will raise a Debug Exception before executing the instruction specified at the address.