INT3
В семействе процессоров 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.