· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.ASSEMBLER —› Очередные глюки fasm'а(команда int 3) ?

Посл.отвђт Сообщенiе


Дата: Авг 15, 2004 20:25:43

Интересно как fasm кодирует int 3, вот:
CD 03          INT 3


т.е. db 0xCD,0x03 вместо 0xCC

почему так?


Дата: Авг 15, 2004 20:38:36 · Поправил: ProgramMan

Opcode Instruction Description
CC INT 3 Interrupt 3—trap to debugger.
CD ib INT imm8 Interrupt vector number specified by immediate byte.
CE INTO Interrupt 4—if overflow flag is 1.

Так что CCh это оптимизированный вариант CDh,03h и нет тут никакого глюка.

RTFM!


Дата: Авг 15, 2004 20:42:51

ProgramMan
Я и не сомневался в правильности опкода, я имел ввиду почему так не оптимально, два байта вместо одного..


Дата: Авг 15, 2004 20:46:42

FASM позволяет использовать оба варианта. 2й пишется так:
int3


Дата: Авг 15, 2004 22:20:07

S_T_A_S_
> FASM позволяет использовать оба варианта. 2й пишется так:
int3


Даже не мог такое предположить %)


Дата: Авг 16, 2004 02:04:17

Упс... Не надо юзать CD 03. Винда этого не понимает.

Почти год назад мы обсуждали в группе какой-то екзешник by DAEMON, который якобы детектил айс использую как раз этот вариант инт 3. Сам екзешник у мя не сохранился. Остались тока два моих поста. Из них, в принципе всё понятно.



Vladimir> Ну какой из голого int 3 антиотладочный прием? Да никакого!
Vladimir> Ведь что пнем по сове, что сову об пень - будет код возврата
Vladimir> STATUS_BREAKPOINT и усе!

Во-первых, предыдущую мою мессагу с кодом NtIceDetect читали?

Во-вторых, я еще маленько покопал Демоновский detect NTIce.EXE и ...
Я уже говорил, что он никакого айса не детектит и детектить не может -
он просто в любом случае показывает 'NTICE FOUND by ^DAEMON^!' и вот
почему...

SEH обработчиком у него является 00401005, который тупо прибавляет к
текущему eip в структуре CONTEXT 4 и возвращает
ExceptionContinueExecution.

Сначала он вбрасывает int3. Обратите внимание на опкод CD 03 !!!
:00401028 CD 03               int     3
:0040102A EB 12               jmp     short loc_40103E
:0040102C                   ; -----------------------------------------------------------
:0040102C EB 20               jmp     short loc_40104E
:0040102E                   ; -----------------------------------------------------------
:0040102E 6A 00               push    0
:00401030 68 00 20 40 00      push    offset aHello   ; "Hello!"
:00401035 68 40 20 40 00      push    offset aNticeFoundByDa ; "NTICE FOUND by ^DAEMON^!"
:0040103A 6A 00               push    0


Прикол в том, что в обработчике SEH в CONTEXT.regEip мы должны
получить 00401028 (и если бы опкод был 0CCh, то так и было бы, что
кстати тоже не верно, но об этом позже). Но мы получаем 00401029 !!!
Т.е. толи у камня, то ли у системы едет крыша, то ли я чего-то не
понимаю.

Демоновский SEH обработчик прибавляет 4 и получается 0040102D - это
середина команды jmp loc_40104E. Туда возвращается управление и мы
получаем новое исключение и опять попадаем в SEH-обработчик.
CONTEXT.regEip = 0040102D. Опять прибавляем 4 и получаем 00401031, а
это середина push offset aHello. Туда возвращается управление и мы
получаем новое исключение ;-) и опять попадаем в SEH-обработчик.
CONTEXT.regEip = 00401031 + 4 = 00401035. Наконец-то мы получили
валидный адрес и попадаем туда.

Пихаем в стек offset aNticeFoundByDa и 0 и вызываем MessageBoxA. Он
снимает со стека, как и полагается, 4 DWORD'а: наши 0 и offset
aNticeFoundByDa и, по счастливой случайности, следующим в стеке сидит
0012FFE0 - MessageBoxA считает, что это адрес строки заголовка (по
этому адресу некая последовательность байт превращающаяся в строку
'яяяя[aиw}йw', которую мы и видим в заголовке), и наконец в качестве
4 параметра MessageBoxA снимает со стека 00401005, интерпритирует 5
как MB_RETRYCANCEL - именно поэтому MessageBoxA появляется с двумя
кнопками ;-) - и показывает нам "NTICE FOUND by ^DAEMON^!". Причем
покажет он это в любом случае ;-) и никакой детекции айса тут нет.

А все потому, что вместо int3 надо влепить int1 (CD 01). Поменяйте 03
на 01 и увидите, что все заработало как надо.

А теперь два вопроса!
1. Почему наткнувшись на CD 03 система передает в SEH адрес 00401029,
указывающий в середину инструкции?
2. Даже если вместо CD 03 влепить СС система передаст в SEH адрес
самого int3. Но ведь int3 это не fault, а trap и адрес должен указывать на
следующую инструкцию. Какого ж хрена он кажет на саму int3, как будто
это трап?


В аттаче еще маленько упрощенный пример детекции на int1.

-----------------------
Four-F





Four-F> А теперь два вопроса!
Four-F> 1. Почему наткнувшись на CD 03 система передает в SEH адрес 00401029,
Four-F> указывающий в середину инструкции?
Four-F> 2. Даже если вместо CD 03 влепить СС система передаст в SEH адрес
Four-F> самого int3. Но ведь int3 это не fault, а trap и адрес должен указывать на
Four-F> следующую инструкцию. Какого ж хрена он кажет на саму int3, как будто
Four-F> это трап?

Чтобы дальнейшие объяснения были более понятны, выпомните, что когда
процессор натыкается на int3 генерится исключение типа Trap (ловушка).
А если ловушка, то камень передаст обработчику этого исключения адрес
инструкции следующей сразу за int3.

Int3 существует в двух вариантах: с опкодом СС, к которому мы все
привыкли и с опкодом CD03. Обратите внимание, один байт и два байта.
При натыкании на любой из этих опкодов, камень генерит исключение, и
передает обработчику: в случае CC адрес на один больший чем адрес CC,
в случае CD03 адрес на два больший чем адрес CD03. Здесь все четко.
Камень свои опкоды знает и ошибиться не может.


Теперь сам спросил, сам отвечу.

Ответ 1: Потому, что обработчик _KiTrap03 никак не ожидает int3 с
опкодом CD03. Он считает что int3 имеет только только опкод CC.

Ответ 2: Потому, что обработчик _KiTrap03 уменьшает адрес переданный
камнем на 1. Причем делает он это в любом случае. Для СС это будет
указатель на него самого, как будто это не Trap, а Fault. Для CD03
будет большая лажа ;-) Адрес переданный камнем будет уменьшен на 1 и
будет указывать в середину int3 с опкодом CD03.


Во втором мануале от интела "Instruction Set Reference" находим такую
фразу:

"Note that the “normal” 2-byte opcode for INT 3 (CD03) does not have
these special features. Intel and Microsoft assemblers will not
generate the CD03 opcode from any mnemonic, but this opcode can be
created by direct numeric code definition or by self-modifying code."

Т.е. M$ вообще не предполагает обработку int3 с опкодом CD03, а только
с опкодом CC! Демоновский код был скомпилен не masm, поэтому в
обработчике SEH мы имеем eip указывающий в середину инструкции int3 с
опкодом CD03.


Вот куски из ntoskrnl.exe от w2k+sp2 (от ХР я тоже глянул - там все то
же самое).
:00465D6E _KiTrap03:
. . .
:00465DEC loc_465DEC:
:00465DEC       mov esi, ecx
:00465DEE       mov edi, edx
:00465DF0       mov edx, eax
:00465DF2       mov ebx, [ebp+KTRAP_FRAME.Eip]
:00465DF5       dec ebx                          ; <- !!! eip = eip-1
:00465DF6       mov ecx, 3
:00465DFB       mov eax, STATUS_BREAKPOINT
:00465E00       call CommonDispatchException


:004301B0 _KiDispatchException@20 proc near
. . .
:00430216 loc_430216:
:00430216       lea eax, [ebp+var_38C]
:0043021C       push eax
:0043021D       push [ebp+arg_4]
:00430220       mov esi, [ebp+TrapFrame]             ; PKTRAP_FRAME
:00430223       push esi
:00430224       call _KeContextFromKframes@12
:00430229       mov edi, [ebp+exr]                   ; PEXCEPTION_RECORD
:0043022C       cmp [edi+EXCEPTION_RECORD.ExceptionCode], STATUS_BREAKPOINT
:00430232       jnz short loc_43023A
:00430234       dec [ebp+Eip]                        ; <- !!! eip = eip-1


Если EXCEPTION_RECORD.ExceptionCode == STATUS_BREAKPOINT, то просто
[ebp+Eip] - это CONTEXT.Eip - уменьшается на 1 (В строке 00430234).

Гы-гы-гы.

-----------------------
Four-F


Дата: Авг 16, 2004 09:11:13

Four-F
Уменя Win2K+SP2+ SoftICE нормально обрабатывает инструкцию CD 03
Asterix Извени, видимо я не понял тебя.


Дата: Авг 16, 2004 15:44:24

ProgramMan, тебе, похоже, попался какой-то custom build винды ;) См. аттач.


_916680702__CD03Trouble.rar


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.083