Int3

eXeL@B DVD

Материал из Справочник исследователя программ

Перейти к: навигация, поиск

В семействе процессоров x86 данная инструкция означает 3-е прерывание. Исполнение этой инструкции приводит к специальному отладочному исключению, которое реализуется обработчиком 3-ого прерывания. Код операции 0xCC был специально добавлен в систему команд для работы первых отладчиков, которые ставили точку останова, меняя на нее первый байт инструкции на которой требовался останов, обработчик первым делом естественно возвращал замененный байт обратно. Также есть и другая инструкция - Int 3 с кодом 0xCD 0x03.

Так как инструкция Int сохраняет в транзитном стеке адрес следующей за ней инструкции, то соответственно 3-й вектор(#BP) имеет тип Trap. В ядре NT ISR #DB выполняет декремент Eip для того, чтобы возвратить управление после отката ловушки на точку останова. Но так как не выполняется проверка типа инструкции, то для двубайтного Int 3 адрес останова и Eip будет указывать на середину инструкции:

;++
;
; Routine Description:
;
;    Handle INT 3 breakpoint.
;
;    The trap is caused by a single byte INT 3 instruction.  A
;    BREAKPOINT exception with additional parameter indicating
;    READ access is raised for this trap if previous mode is user.
;
; Arguments:
;
;    At entry, the saved CS:EIP point to the instruction immediately
;    following the INT 3 instruction.
;    No error code is provided with the error.
;
; Return value:
;
;    None
;
;--
        ASSUME  DS:NOTHING, SS:NOTHING, ES:NOTHING

        ENTER_DR_ASSIST kit3_a, kit3_t, NoAbiosAssist
align dword
        public  _KiTrap03
_KiTrap03       proc
        push    0                       ; push dummy error code
        ENTER_TRAP      kit3_a, kit3_t

        cmp     ds:_PoHiberInProgress, 0
        jnz     short kit03_01

   lock inc     ds:_KiHardwareTrigger   ; trip hardware analyzer

kit03_01:
        mov     eax, BREAKPOINT_BREAK

KiTrap03DebugService:
;
; If caller is user mode, we want interrupts back on.
;   . all relevant state has already been saved
;   . user mode code always runs with ints on
;
; If caller is kernel mode, we want them off!
;   . some state still in registers, must prevent races
;   . kernel mode code can run with ints off
;
;
; Arguments:
;     eax - ServiceClass - which call is to be performed
;     ecx - Arg1 - generic first argument
;     edx - Arg2 - generic second argument
;

.errnz (EFLAGS_V86_MASK AND 0FF00FFFFh)
        test    byte ptr [ebp]+TsEFlags+2,EFLAGS_V86_MASK/010000h
        jnz     kit03_30                ; fault occured in V86 mode => Usermode

.errnz (MODE_MASK AND 0FFFFFF00h)
        test    byte ptr [ebp]+TsSegCs,MODE_MASK
        jz      kit03_10

        cmp     word ptr [ebp]+TsSegCs,KGDT_R3_CODE OR RPL_MASK
        jne     kit03_30

kit03_05:
        sti
kit03_10:


;
; Set up exception record and arguments for raising breakpoint exception
;

        mov     esi, ecx                ; ExceptionInfo 2
        mov     edi, edx                ; ExceptionInfo 3
        mov     edx, eax                ; ExceptionInfo 1

        mov     ebx, [ebp]+TsEip
        dec     ebx                     ; (ebx)-> int3 instruction
        mov     ecx, 3
        mov     eax, STATUS_BREAKPOINT
        call    CommonDispatchException ; Never return

kit03_30:
; Check to see if this process is a vdm

        mov     ebx,PCR[PcPrcbData+PbCurrentThread]
        mov     ebx,[ebx]+ThApcState+AsProcess
        cmp     dword ptr [ebx]+PrVdmObjects,0 ; is this a vdm process?
        je      kit03_05

        stdCall _Ki386VdmReflectException_A, <03h>
        test    ax,0FFFFh
        jz      Kit03_10

        jmp     _KiExceptionExit

_KiTrap03       endp

Это также относится и к #OF - при срабатывании ловушки информация об исключении и контекст будет содержать адрес инструкции Into. Если использовать префиксы переопределения сегмента, то ссылка будет не на начало инструкции. Эта проблема была в младших версиях NT, где была не корректная обработка префиксов - например для инстуркции Ud2 проверялись префиксы за этой инструкцией и конструкция Ud2/Lock/* приводила к генерации STATUS_INVALID_LOCK_SEQUENCE.

См. также

Отладчик

Int1

IceBP

Источник — «https://exelab.ru/faq/Int3»