Debugger Evasion

May 1, 2024 · View on GitHub

ID B0002
Objective(s) Anti-Behavioral Analysis
Related ATT&CK Techniques Debugger Evasion (T1622)
Anti-Analysis Type Evasion
Version 2.3
Created 1 August 2019
Last Modified 27 April 2024

Debugger Evasion

Debugger evasion is employed by malware to foil a debugger and avoid analysis. For example, to hinder the malware analyst and debugger, malware may use exception handling to execute non-obvious execution paths (exception misdirection method) or may use several parallel threads (parallel threads method). Additional debugger evasion methods are described below.

A thorough reference for anti-debugging, both detection and evasion, is given in [1].

The related Debugger Evasion (T1622) ATT&CK technique was defined subsequent to this MBC behavior.

Methods

NameIDDescription
Block InterruptsB0002.001Block interrupt (via hooking) 1 and/or 3 to prevent debuggers from working.
Break Point ClearingB0002.002Intentionally clearing software or hardware breakpoints.
Byte StealingB0002.003Move or copy the first bytes / instructions of the original code elsewhere. AKA stolen bytes or code splicing. For example, a packer may incorporate the first few instructions of the original EntryPoint (EP) into its unpacking stub before the tail transition in order to confuse automated unpackers and novice analysts. This can make it harder for rebuilding and may bypass breakpoints if set prematurely.
Change SizeOfImageB0002.004Changing this value during run time can prevent some debuggers from attaching and also confuses some unpackers and dumpers.
Code Integrity CheckB0002.005Check that the unpacking code is unmodified. Variation exists where unpacking code is part of the "key" used to unpack, therefore any Software Breakpoints during debugging causes unpacking to completely fail or result in malformed unpacked code.
Exception MisdirectionB0002.006Using exception handling (SEH) to cause flow of program to non-obvious paths.
Get Base IndirectlyB0002.007CALL to a POP; finds base of code or data, often the packed version of the code; also used often in obfuscated/packed shellcode.
Guard PagesB0002.008Encrypt blocks of code individually and decrypt temporarily only upon execution. This method is related to Unprotect technique U0102.
Hook InterruptB0002.009Modification of interrupt vector or descriptor tables.
Import ObfuscationB0002.010Add obfuscation between imports calls and APIs.
InliningB0002.011Variation of static linking where full API code inserted everywhere it would have been called.
Loop EscapesB0002.012Use SEH or other methods to break out of a loop instead of a conditional jump.
Malloc UseB0002.013Instead of unpacking into a pre-defined section/segment (ex: .text) of the binary, use malloc() / VirtualAlloc() to create a new segment. This makes keeping track of memory locations across different runs more difficult, as there is no guarantee that malloc/VirtualAlloc will assign the same address range each time.
Modify PE HeaderB0002.014Any part of the header is changed or erased.
NanomitesB0002.015int3 with code replacement table; debugs itself.
Obfuscate Library UseB0002.016LoadLibrary API calls or direct access of kernel32 via PEB (fs[0]) pointers, used to rebuild IAT or just obfuscate library use.
Parallel ThreadsB0002.017Use several parallel threads to make analysis harder.
Pipeline MisdirectionB0002.018Take advantage of pipelining in modern processors to misdirect debugging, emulation, or static analysis tools. An unpacker can assume a certain number of opcodes will be cached and then proceed to overwrite them in memory, causing a debugger/emulator/analyzer to follow different code than is normally executed.
Pre-DebugB0002.019Prevents debugger from attaching to process or to break until after the code of interest has been executed.
Relocate API CodeB0002.020Relocate API code in separate buffer (calls don’t lead to imported DLLs).
Return ObfuscationB0002.021Overwrite the RET address on the stack or the code at the RET address. Variation seen that writes to the start-up code or main module that called the malware's WinMain or DllMain.
RtlAdjustPrivilegeB0002.022Calling RtlAdjustPrivilege to either prevent a debugger from attaching or to detect if a debugger is attached.
Section MisalignmentB0002.023Some analysis tools cannot handle binaries with misaligned sections.
Self-DebuggingB0002.024Debug itself to prevent another debugger to be attached.
Self-UnmappingB0002.025UnmapViewOfFile() on itself.
Static LinkingB0002.026Copy locally the whole content of API code.
Stolen API CodeB0002.027A variation of "byte stealing" where the first few instructions or bytes of an API are executed in user code, allowing the IAT to point into the middle of an API function. This confuses IAT rebuilders such as ImpRec and Scylla and may bypass breakpoints.
TamperingB0002.028Erase or corrupt specific file parts to prevent rebuilding (header, packer stub, etc.).
Thread TimeoutB0002.029Setting dwMilliseconds in WaitForSingleObject to a small number will timeout the thread before the analyst can step through and analyze the code executing in the thread. Modifying this via patch, register, or stack to the value 0xFFFFFFFF, the INFINITE constant circumvents this anti-debugging technique.
Use InterruptsB0002.030The unpacking code relies on use of int 1 or int 3, or it uses the interrupt vector table as part of the decryption "key".

Use in Malware

NameDateMethodDescription
Fake Adobe Flash Update OS X2016--Malware contains code that manually detects a debugger. [2]
Dridex2015--[3]
Redhip2011--Redhip uses general approaches to detecting user level debuggers (e.g., Process Environment Block 'Being Debugged' field), as well as specific checks for kernel level debuggers like SOFTICE. [3]
Vobfus2016--Vobfus uses GetModuleHandle API to check for the presence of a debugger. [4]

Detection

Tool: capaMappingAPIs
hide thread from debuggerDebugger Evasion (B0002)NtSetInformationThread, ZwSetInformationThread, GetCurrentThread
switch active desktopDebugger Evasion (B0002)user32.CreateDesktop, user32.SwitchDesktop
Tool: CAPEMappingAPIs
antidebug_guardpagesDebugger Evasion (B0002)VirtualProtectEx, NtAllocateVirtualMemory, NtProtectVirtualMemory
antidebug_guardpagesDebugger Evasion::Guard Pages (B0002.008)VirtualProtectEx, NtAllocateVirtualMemory, NtProtectVirtualMemory
antidebug_ntcreatethreadexDebugger Evasion (B0002)NtCreateThreadEx
debugs_selfDebugger Evasion (B0002)CreateProcessInternalW
debugs_selfDebugger Evasion::Self-Debugging (B0002.024)CreateProcessInternalW

References

[1] https://anti-reversing.com/Downloads/Anti-Reversing/The_Ultimate_Anti-Reversing_Reference.pdf

[2] https://web.archive.org/web/20210225195315/https://www.synack.com/blog/analyzing-the-anti-analysis-logic-of-an-adware-installer/

[3] https://web.archive.org/web/20200815134441/https://www.fireeye.com/blog/threat-research/2011/01/the-dead-giveaways-of-vm-aware-malware.html

[4] https://securitynews.sonicwall.com/xmlpost/revisiting-vobfus-worm-mar-8-2013/