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

 WASM Phorum —› WASM.WIN32 —› 3 глупых вопроса про Win32 Dbg API

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


Дата: Апр 2, 2004 15:05:13 · Поправил: MarsRover

1) Как в 95/98/ME брякнуться (bpx) на т.н. shared virtual address space (0x80000000-0xBFFFFFFF)?
2) Является ли установка DRx общей для отлаживаемого процесса или только для того потока, в чьем контексте она производится.
3) (Совсем глюпий). В winnt.h есть такой код для ContinueDebugEvent():
#define DBG_EXCEPTION_HANDLED 0x00010001.
Что бы это значило? И чем отличается от DBG_CONTINUE 0x00010002? сразу говорю: гуглил, MSDN-ил, нет этого DBG_EXCEPTION_HANDLED нигде.


Дата: Апр 2, 2004 17:30:00

1) Это только из Ring0 возможно, или если открыть доступ, в статье про перехват API написано как.

2) Только для потока, т.к. для каждого потока своя структура CONTEXT.


Дата: Апр 2, 2004 19:23:25

Только для потока, т.к. для каждого потока своя структура CONTEXT

Ну и что?

Поглядим подробнее:

Итак, утверждение первое - в WinNT нет TSS (т.е. TSS'ы-то есть, но лишь для обработки некоторых исключительных ситуаций). Переключение в контекст процесса осуществляется программно - функция SwapContext.

Теперь смотрим интеловский бук о флажках в DR-регистре:

L0 through L3 (local breakpoint enable) flags (bits 0, 2, 4, and 6)
Enable (when set) the breakpoint condition for the associated breakpoint for
the current task. When a breakpoint condition is detected and its associated Ln
flag is set, a debug exception is generated. The processor automatically clears
these flags on every task switch to avoid unwanted breakpoint conditions in the
new task.


G0 through G3 (global breakpoint enable) flags (bits 1, 3, 5, and 7)
Enable (when set) the breakpoint condition for the associated breakpoint for all
tasks. When a breakpoint condition is detected and its associated Gn flag is set,
a debug exception is generated. The processor does not clear these flags on a
task switch, allowing a breakpoint to be enabled for all tasks.


Ну, ОК. Я поставил битики G0-G3, а в DR0-DR3 прописал адресочки и теперь с полным основанием жду, а когда же произойдет трап при встрече нужного VA. А TSS-то ведь один! Так это что, значит если я поставил G0-G3 бит, то теперь как только нужный VA встретится в ЛЮБОМ из процессов системы, произойдет трап? Так ведь это беспредел! Но ведь этого не происходит! Почему? Поглядим на цепочки:

ring-3:
SetThreadContext or SEH -> CONTEXT.DRx = VA, CONTEXT.DR7 = mask;

ring-0:
NtConinue->KiContinue->KeContextToKframes

В кольце-0 Windows перекладывает содержимое CONTEXT в структуру KTRAP_FRAME.
typedef struct _KTRAP_FRAME {


//
//  Following 4 values are only used and defined for DBG systems,
//  but are always allocated to make switching from DBG to non-DBG
//  and back quicker.  They are not DEVL because they have a non-0
//  performance impact.
//

    ULONG   DbgEbp;         // Copy of User EBP set up so KB will work.
    ULONG   DbgEip;         // EIP of caller to system call, again, for KB.
    ULONG   DbgArgMark;     // Marker to show no args here.
    ULONG   DbgArgPointer;  // Pointer to the actual args

//
//  Temporary values used when frames are edited.
//
//
//  NOTE:   Any code that want's ESP must materialize it, since it
//          is not stored in the frame for kernel mode callers.
//
//          And code that sets ESP in a KERNEL mode frame, must put
//          the new value in TempEsp, make sure that TempSegCs holds
//          the real SegCs value, and put a special marker value into SegCs.
//

    ULONG   TempSegCs;
    ULONG   TempEsp;

//
//  Debug registers.
//

    ULONG   Dr0;
    ULONG   Dr1;
    ULONG   Dr2;
    ULONG   Dr3;
    ULONG   Dr6;
    ULONG   Dr7;

//
//  Segment registers
//

    ULONG   SegGs;
    ULONG   SegEs;
    ULONG   SegDs;

//
//  Volatile registers
//

    ULONG   Edx;
    ULONG   Ecx;
    ULONG   Eax;

//
//  Nesting state, not part of context record
//

    ULONG   PreviousPreviousMode;

    PEXCEPTION_REGISTRATION_RECORD ExceptionList;
                                            // Trash if caller was user mode.
                                            // Saved exception list if caller
                                            // was kernel mode or we're in
                                            // an interrupt.

//
//  FS is TIB/PCR pointer, is here to make save sequence easy
//

    ULONG   SegFs;

//
//  Non-volatile registers
//

    ULONG   Edi;
    ULONG   Esi;
    ULONG   Ebx;
    ULONG   Ebp;

//
//  Control registers
//

    ULONG   ErrCode;
    ULONG   Eip;
    ULONG   SegCs;
    ULONG   EFlags;

    ULONG   HardwareEsp;    // WARNING - segSS:esp are only here for stacks
    ULONG   HardwareSegSs;  // that involve a ring transition.

    ULONG   V86Es;          // these will be present for all transitions from
    ULONG   V86Ds;          // V86 mode
    ULONG   V86Fs;
    ULONG   V86Gs;
} KTRAP_FRAME;


Само перекладывание тривиально и описано в упаковщиках, вторая часть. А вот проверки, которые при этом делаются уже более любопытны:
.text:00430777 mov ecx, [esi+CONTEXT.Dr1] 
.text:0043077A cmp MmHighestUserAddress, ecx 
.text:00430780 sbb eax, eax 
.text:00430782 not eax 
.text:00430784 and eax, ecx 
.text:00430786 jmp back1 


Здесь на 7FFFFFFF проверка.
.text:0043059C mov [ebx+KTRAP_FRAME.Dr3], eax 
.text:0043059F mov eax, [esi+CONTEXT.Dr6] 
.text:004305A2 and eax, 0E00Fh 
.text:004305A7 mov [ebx+KTRAP_FRAME.Dr6], eax 
.text:004305AA mov eax, [esi+CONTEXT.Dr7] 
.text:004305AD and ax, 155h 
.text:004305B1 test dl, dl 
.text:004305B3 mov [ebx+KTRAP_FRAME.Dr7], eax 
.text:004305B6 jz short loc_4305D9 


Т.о. видим, что G0-G3 принудительно обнуляются, аппаратный бряк из кольца-3 нельзя поставить выше 7FFFFFFF. А вот если из кольца-0 поставить G0-G3 биты... Короче, тут есть над чем подумать!


Дата: Апр 2, 2004 19:34:59

И даже более того, L0-L3 получаются эквивалентны G0-G3 в присутствии одного общего TSS...


Дата: Апр 3, 2004 02:43:48

:-0 ! А говорил, что винды не знает... :)


Дата: Апр 3, 2004 05:12:47

А ты поверил :)


Дата: Апр 4, 2004 02:18:05 · Поправил: Toxic

По крайней мере я такого не знаю(никогда не было необходимости, я ведь в основном работаю с UI и прикладными задачами)


Дата: Апр 5, 2004 16:25:21

MarsRover
читай мануалы по айсу, и там были ответы на первые твои два вопроса, что касается третьего вопроса, то я ужё давно забыл про отладчики третьего кольца и отладку кода в оном.


Дата: Апр 6, 2004 01:06:59

1) Как в 95/98/ME брякнуться (bpx) на ..
кладёшь бряк тудыть и брякаешься. если ROnly, пробуй VirtualProtect или R0

2) Является ли установка DRx общей для отлаживаемого процесса или только для того потока,
в чьем контексте она производится.

Под W9x DRx общий для всех процессов == опасный!


Дата: Апр 6, 2004 14:12:38

Всем спасибо!
Извините что так долго нен писал - занят был.
про 1) Хотелось бы чтобы срабатывало только в контексте конкретного процесса, похоже без system wide извращений не обойтись.
про 2) Я спрашивал не про 95-98, в них похоже DRx не установить через SetThreadContext(). В NT придется опытным путем, пока руки не доходят.
про 3) Я думаю (тоже проверить пока времени нет), что DBG_EXCEPTION_HANDLED эквивалентно DBG_CONTINUE в случае если обрабатывается EXCEPTION_DEBUG_EVENT. Скорее всего наследие далеких времен, когда только проэктировали Dbg API. Потом решили, что и DBG_CONTINUE хватит.


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