INT3 Instruction Scanning

Created the Monday 18 March 2019. Updated 3 years, 6 months ago.

Instruction INT3 is an interruption which is used as Software breakpoints. These breakpoints are set by modifying the code at the target address, replacing it with a byte value 0xCC (INT3 / Breakpoint Interrupt).

The exception EXCEPTION_BREAKPOINT (0x80000003) is generated, and an exception handler will be raised. Malware identify software breakpoints by scanning for the byte 0xCC in the protector code and/or an API code.


Technique Identifier

U0105

Technique Tag

int3


Code Snippets

BOOL IsDebuggerPresent_Int3()
{
      __try
         { 
             __asm int 3 
         }
      __except(1) 
         { 
             return FALSE; 
         }
     return TRUE;

}
#include "pch.h"

#include "SoftwareBreakpoints.h"


/*
Software breakpoints aka INT 3 represented in the IA-32 instruction set with the opcode CC (0xCC).
Given a memory addresse and size, it is relatively simple to scan for the byte 0xCC -> if(pTmp[i] == 0xCC)
An obfuscated method would be to check if our memory byte xored with 0x55 is equal 0x99 for example ... 
*/

VOID My_Critical_Function()
{
	int a = 1;
	int b = 2;
	int c = a + b;
	_tprintf(_T("I am critical function, you should protect against int3 bps %d"), c);
}


VOID Myfunction_Adresss_Next()
{
	My_Critical_Function();
	/*
	There is no guaranteed way of determining the size of a function at run time(and little reason to do so)
	however if you assume that the linker located functions that are adjacent in the source code sequentially in memory,
	then the following may give an indication of the size of a function Critical_Function by using :
	int Critical_Function_length = (int)Myfunction_Adresss_Next - (int)Critical_Function
	Works only if you compile the file in Release mode.
	*/
};

BOOL SoftwareBreakpoints()
{
	//NOTE this check might not work on x64 because of alignment 0xCC bytes
	size_t sSizeToCheck = (size_t)(Myfunction_Adresss_Next)-(size_t)(My_Critical_Function);
	PUCHAR Critical_Function = (PUCHAR)My_Critical_Function;

	for (size_t i = 0; i < sSizeToCheck; i++) {
		if (Critical_Function[i] == 0xCC) // Adding another level of indirection : 0xCC xor 0x55 = 0x99
			return TRUE;
	}
	return FALSE;
}

Detection Rules

rule Detect_Interrupt: AntiDebug {
    meta: 
        description = "Detect Interrupt instruction"
        author = "Unprotect"
        comment = "Experimental rule / the rule can be slow to use"
    strings:
        $int3 = { CC }
        $intCD = { CD }
        $int03 = { 03 }
        $int2D = { 2D }
        $ICE = { F1 }
    condition:   
       uint16(0) == 0x5A4D and filesize < 1000KB and any of them
}
rule:
  meta:
    name: check for software breakpoints
    namespace: anti-analysis/anti-debugging/debugger-detection
    authors:
      - michael.hunhoff@mandiant.com
    scope: function
    mbc:
      - Anti-Behavioral Analysis::Debugger Detection::Software Breakpoints [B0001.025]
    references:
      - https://github.com/LordNoteworthy/al-khaser/blob/master/al-khaser/AntiDebug/SoftwareBreakpoints.cpp
    examples:
      - al-khaser_x86.exe_:0x431020
  features:
    - and:
      - basic block:
        - and:
          - mnemonic: cmp
          - or:
            - number: 0xCC
            - and:
              - number: 0xCD
              - number: 0x3
      - match: contain loop

Additional Resources

External Links

Subscribe to our Newsletter


The information entered into this form is mandatory. It will be subjected to computer processing. It is processed by computer in order to support our users and readers. The recipients of the data will be : contact@unprotect.it.

According to the Data Protection Act of January 6th, 1978, you have at any time, a right of access to and rectification of all of your personal data. If you wish to exercise this right and gain access to your personal data, please write to Thomas Roccia at contact@unprotect.it.

You may also oppose, for legitimate reasons, the processing of your personal data.