SetLastError to set the current error code to an arbitrary value. If OutputDebugString is called and there is no debugger attached, GetLastError should no longer contain our arbitrary value, because an error code will be set by the OutputDebugString function if it fails. If OutputDebugString is called and there is a debugger attached, the call to OutputDebugString should succeed, and the value in GetLastError should not be changed.BeingDebugged flag. Finally, EBX is checked to see if it is zero. If so, a debugger is not attached, and the jump will be taken.Another example is shown on the right side of . The location of the PEB is moved into EDX using a push/pop combination of instructions, and then the BeingDebugged flag at offset 2 is directly compared to 1.
This check can take many forms, and, ultimately, the conditional jump determines the code path. You can take one of the following approaches to surmount this problem:
Force the jump to be taken (or not) by manually modifying the zero flag immediately before the jump instruction is executed. This is the easiest approach.
Manually change the BeingDebugged flag to zero.
Both options are generally effective against all of the techniques described in this section.
ProcessHeap, is set to the location of a process’s first heap allocated by the loader. ProcessHeap is located at 0x18 in the PEB structure. This first heap contains a header with fields used to tell the kernel whether the heap was created within a debugger. These are known as the ForceFlags and Flags fields.Offset 0x10 in the heap header is the ForceFlags field on Windows XP, but for Windows 7, it is at offset 0x44 for 32-bit applications. Malware may also look at offset 0x0C on Windows XP or offset 0x40 on Windows 7 for the Flags field. This field is almost always equal to the ForceFlags field, but is usually ORed with the value 2.
shows the assembly code for this technique. (Note that two separate dereferences must occur.)