Inclusion of an INT 2D instruction appears to be a fairly common anti-debugging tactic used by Windows malware authors. From what I understand, it causes a process to act differently when a debugger is attached from when it is not attached.I have read that this is due in part to an asynchronous (not part of normal program flow) increment to the instruction pointer. This increment can be made to lead to instruction scission.Could someone explain this anti-debugging tactic, specifically why this increment to the instruction pointer occurs, and what happens when a debugger is and is not attached.
INT 2D Anti-Forensic Method
windows;static analysis;malware;anti debugging
From my Ultimate Anti-Debugging reference (see pferrie.host22.com):The interrupt 0x2D is a special case.  When it is executed, Windows uses the current EIP register value as the exception address, and then it increments by one the EIP register value.  However, Windows also examines the value in the EAX register to determine how to adjust the exception address.  If the EAX register has the value of 1, 3, or 4 on all versions of Windows, or the value 5 on Windows Vista and later, then Windows will increase by one the exception address.  Finally, it issues an EXCEPTION_BREAKPOINT (0x80000003) exception if a debugger is present.  The interrupt 0x2D behaviour can cause trouble for debuggers.  The problem is that some debuggers might use the EIP register value as the address from which to resume, while other debuggers might use the exception address as the address from which to resume.  This can result in a single-byte instruction being skipped, or the execution of a completely different instruction because the first byte is missing.  These behaviours can be used to infer the presence of the debugger.  The check can be made using this code (identical for 32-bit and 64-bit) to examine either the 32-bit or 64-bit Windows environment:xor  eax, eax ;set Z flagint  2dhinc  eax ;debugger might skipje   being_debugged[end]So you can see that there's nothing asynchronous happening here.  The change occurs immediately when the exception occurs.As far as why it occurs, the skipped byte is intended to be used to pass one byte of additional information at the time of the exception.