Сейчас на форуме: tyns777, zds, JustLife, 2nd, morgot (+5 невидимых)

 eXeL@B —› Программирование —› Hardware breakpoints
Посл.ответ Сообщение

Ранг: 39.0 (посетитель)
Активность: 0.040
Статус: Участник

Создано: 07 июня 2009 19:15 · Поправил: SVIN95
· Личное сообщение · #1

Пишу отладчик, использующий Debug API. Сейчас прикручиваю HW BP.
Проверяю работу дебаггера на PETools.exe.

Тут проблема возникла. Ставлю HW бряк на 0x00424667, запускаю отлаживаемую прогу.
Ее выполнение прервалось по адресу 0x00424667, на который я ставил железный бряк.
Все правильно. Теперь удаляю эту точку останова (обнуляю Dr0 и Dr7). Требуется
продолжить выполнение программы. А вот не получается! Вечный EXCEPTION_SINGLE_STEP!
т.е невозможно продолжить выполнение программы с адреса останова.
Но я же обнулил Dr0 и Dr7... Почему бряк все еще действует?


P.S. Вычитал на васме

что разрешение на такое продолжение, без повторной генерации исключения, даёт флаг RF (бит 16) регистра EFLAGS

Делаю так:
Code:
  1. Context.EFlags |= 0x10000;
  2. SetThreadContext(ProcInfo.hThread, &Context);


Не помогает... Все-равно вечный EXCEPTION_SINGLE_STEP

Может кто подскажет?




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 07 июня 2009 20:22
· Личное сообщение · #2

Код в студию, во-первых.
Во-вторых, когда ставишь контекст с обнулёнными бряками, уверен, что флаг дебаг_регистров там стоит? Уверен, что ТФ не взведён? Уверен, что статус хандлед?



Ранг: 39.0 (посетитель)
Активность: 0.040
Статус: Участник

Создано: 07 июня 2009 21:25 · Поправил: SVIN95
· Личное сообщение · #3

Archer пишет:
Код в студию, во-первых.

Приведу отрывки.

Установка бряка:
Code:
  1. BOOL CDebugger::SetHWBP(DWORD Address)
  2. {
  3.     if (HWBPNum == 4)
  4.         return FALSE;
  5.  
  6.     GetThreadContext(ProcInfo.hThread, &Context);
  7.     Context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
  8.          
  9.     switch (HWBPNum)
  10.     {
  11.     case 0:
  12.         Context.Dr0 = Address;
  13.         break;
  14.  
  15.     case 1:
  16.         Context.Dr1 = Address;
  17.         break;
  18.  
  19.     case 2:
  20.         Context.Dr2 = Address;
  21.         break;
  22.  
  23.     case 3:
  24.         Context.Dr3 = Address;
  25.         break;
  26.     }
  27.          
  28.     Context.Dr7 = (Context.Dr7 & 0xFFF0FFFF) | 0x101;
  29.     SetThreadContext(ProcInfo.hThread, &Context);
  30.     HWBPTable[HWBPNum] = Address;
  31.     HWBPNum++;
  32.     return TRUE;
  33. }

Удаление бряка:
Code:
  1. BOOL CDebugger::DeleteHWBP(DWORD Address)
  2. {
  3.     Context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
  4.          
  5.     for (int i = 0; i < HWBPNum; i++)
  6.         if (HWBPTable<I> == Address)
  7.         {
  8.             switch (i)
  9.             {
  10.             case 0:
  11.                 Context.Dr0 = 0x0;
  12.                 break;
  13.  
  14.             case 1:
  15.                 Context.Dr1 = 0;
  16.                 break;
  17.  
  18.             case 2:
  19.                 Context.Dr2 = 0;
  20.                 break;
  21.  
  22.             case 3:
  23.                 Context.Dr3 = 0;
  24.                 break;
  25.             }
  26.             Context.Dr6 = 0;
  27.             Context.Dr7 = 0;
  28.             if (Context.Eip == Address)
  29.             {
  30.                 EXCEPTION_NOT_HANDLED = TRUE;
  31.                 Context.EFlags |= 0x10000;
  32.             }
  33.             SetThreadContext(ProcInfo.hThread, &Context);
  34.             StopDL  = FALSE;
  35.             Breaked = FALSE;
  36.             HWBPTable[i] = 0;
  37.             HWBPNum--;
  38.             return TRUE;
  39.         }
  40.     return FALSE;
  41. }

[i]Archer пишет:
Во-вторых, когда ставишь контекст с обнулёнными бряками, уверен, что флаг дебаг_регистров там
стоит
Code:
  1.     Context.ContextFlags = CONTEXT_DEBUG_REGISTERS;

Archer пишет:
Уверен, что ТФ не взведён?

Трассировку пока не реализовывал, TF мне пока не нужен.




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 07 июня 2009 21:57
· Личное сообщение · #4

Да весь код смотреть надо, костылей много.

GetThreadContext(ProcInfo.hThread, &Context);
Context.ContextFlags = CONTEXT_DEBUG_REGISTERS;

Накой так? Сначала флаг надо, потом читать.

Почему EXCEPTION_NOT_HANDLED = TRUE; и вообще, что это такое?
Context.Dr7 = 0; неправильно, ибо зануляешь все сразу.
Ставить контекст у неспящего потока тоже зло, тут непонятно, как оно.

Короче, взял бы погуглил. И не говори, что нет нигде такого кода.




Ранг: 990.2 (! ! !), 380thx
Активность: 0.680
Статус: Модератор
Author of DiE

Создано: 07 июня 2009 22:11
· Личное сообщение · #5

приведу куски из своего старого проекта:
Code:
  1. function TDebugger.SetHardwareBreak(const iNumber:integer;dwAddress:DWORD):Integer;
  2. var
  3.   pr : Boolean;
  4.   i  : integer;
  5. begin
  6.   result := 0;
  7.   For i:=0 to 3 do
  8.     If BPH[i].addr = dwAddress then EXIT;
  9.   Cont.ContextFlags := CONTEXT_DEBUG_REGISTERS;
  10.   pr := GetThreadContext(pi.hThread,cont);
  11.   If (pr) and (iNumber >= 0) and (iNumber <= 3) and (dwAddress>0) then
  12.   begin
  13.     CASE (iNumber) of
  14.       0:  begin
  15.             cont.Dr0:= dwAddress;
  16.             Cont.Dr7:= Cont.Dr7 or BPM_LOCAL_EXACT or BPM0_ENABLED
  17.           end;
  18.       1:  begin
  19.             cont.Dr1:= dwAddress;
  20.             Cont.Dr7:= Cont.Dr7 or BPM_LOCAL_EXACT or BPM1_ENABLED
  21.           end;
  22.       2:  begin
  23.             cont.Dr2:= dwAddress;
  24.             Cont.Dr7:= Cont.Dr7 or BPM_LOCAL_EXACT or BPM2_ENABLED
  25.           end;
  26.       3:  begin
  27.             cont.Dr3:= dwAddress;
  28.             Cont.Dr7:= Cont.Dr7 or BPM_LOCAL_EXACT or BPM3_ENABLED
  29.           end;
  30.     end;
  31.     BPH[iNumber].addr := dwAddress;
  32.     cont.Dr6 := 0;
  33.     pr := setThreadContext(pi.hThread,cont);
  34.     If (pr) then result:=1;
  35.   end;
  36. end;
  37. ...
  38. function TDebugger.DelHardwareBreak(const iNumber:integer):Integer;
  39. var
  40.   pr : Boolean;
  41. begin     
  42.   result := 0;
  43.   Cont.ContextFlags := CONTEXT_DEBUG_REGISTERS;
  44.   pr := GetThreadContext(pi.hThread,cont);
  45.   If (pr) and (iNumber >= 0) and (iNumber <= 3) then
  46.   begin
  47.     case (iNumber) of
  48.       0:  begin
  49.             cont.Dr0:=0;
  50.             Cont.Dr7:= Cont.Dr7 xor BPM0_ENABLED;
  51.           end;
  52.       1:  begin
  53.             cont.Dr1:=0;
  54.             Cont.Dr7:= Cont.Dr7 xor BPM1_ENABLED;
  55.           end;
  56.       2:  begin
  57.             cont.Dr2:=0;
  58.             Cont.Dr7:= Cont.Dr7 xor BPM2_ENABLED;;
  59.           end;
  60.       3:  begin
  61.             cont.Dr3:=0;
  62.             Cont.Dr7:= Cont.Dr7 xor BPM3_ENABLED;
  63.           end;
  64.     end;
  65.     BPH[iNumber].addr:=0;
  66.     cont.Dr6:=0;
  67.     pr:=setThreadContext(pi.hThread,cont);
  68.     If pr then result:=1;
  69.   end;
  70. end;
  71. ... 
  72. procedure TDebugger.ExceptionSingleStep(const ERec : _EXCEPTION_RECORD);
  73. var
  74.   address:DWORD;
  75.   temp:DWORD;
  76.   n:Integer;
  77. begin
  78.   DbgControl := DBG_EXCEPTION_NOT_HANDLED;
  79.   address    := DWORD(ERec.ExceptionAddress);
  80.   n          := MyBPH(address);
  81.   If (>= 0) then
  82.   begin
  83.     DbgControl := DBG_CONTINUE;
  84.     DelHardwareBreak(n);
  85.     FDebugLog := '> HardwareBreakpoint ['+IntToStr(n)+']: '+IntToHex(address,8);
  86.     exit;
  87.   end;
  88. ...


-----
[nice coder and reverser]




Ранг: 39.0 (посетитель)
Активность: 0.040
Статус: Участник

Создано: 07 июня 2009 22:24
· Личное сообщение · #6

Archer пишет:
GetThreadContext(ProcInfo.hThread, &Context);Context.ContextFlags = CONTEXT_DEBUG_REGISTERS;Накой так? Сначала флаг надо, потом читать.

Накосячил, поправил.

Archer пишет:
Почему EXCEPTION_NOT_HANDLED = TRUE; и вообще, что это такое?

Если TRUE, продолжение выполнения проги начнется с ContinueDebugEvent(ProcInfo.dwProcessId, ProcInfo.dwThreadId, DBG_EXCEPTION_NOT_HANDLED). Если после удаления железного бряка продолжить выполнение проги с WaitForDebugEvent, будет вечно висеть.

Archer пишет:
Context.Dr7 = 0; неправильно, ибо зануляешь все сразу.

Поправлю.

Archer пишет:
Ставить контекст у неспящего потока тоже зло, тут непонятно, как оно.

Зачем усыплять поток, если прога находится под отладкой? Или не важно?

Archer пишет:
Короче, взял бы погуглил

Уже гуглил - только 2 статьи. Одна на хакере - только описание отладочных регистров.
Другая на васме - EXCEPTION_SINGLE_STEP (#DB exception) обрабатывается с помощью
VectoredExceptionHandler, а не с помощью отладчика.

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



Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 07 июня 2009 23:07
· Личное сообщение · #7

> обрабатывается с помощью VectoredExceptionHandler, а не с помощью отладчика.
Какие есчо векторы, перед возвратом потока на диспетчер исключений на отладочный порт посылается сообщение, при любом исключении.




Ранг: 681.5 (! !), 405thx
Активность: 0.420.21
Статус: Участник
ALIEN Hack Team

Создано: 08 июня 2009 15:10
· Личное сообщение · #8

Да вон рядом тема есть - Anti-Anpackers tricks, там рассказывается, как использовать отладочные регистры, а более подробно, можно прочитать "Об упаковщиках в последний раз" - там описывается, как Telock использует отладочные регистры, чтоб выполнять самотрассировку.

-----
Stuck to the plan, always think that we would stand up, never ran.




Ранг: 39.0 (посетитель)
Активность: 0.040
Статус: Участник

Создано: 08 июня 2009 15:48 · Поправил: SVIN95
· Личное сообщение · #9

Заработало. Надо было при получении EXCEPTION_SINGLE_STEP (первый раз) поставить
ContinueDebugEvent с флагом DBG_CONTINUE. Спасибо Hellspawn'у за куски кода,
кое-что у себя поправил. Тему прошу пока не закрывать, могут еще возникнуть вопросы.




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 08 июня 2009 18:31
· Личное сообщение · #10

А выше ты читал? Уверен, что статус хандлед?
Оказалось, что ни разу не так.

Добавлю ещё, что не уверен, что RF флаг выставится правильно. Если почитать ман интела, скажем, он глаголит, что команда popfd этот флаг не ставит. Походу, только через iretd его можно выставить. Как его винда ставит-хз, поэтому может и не работать.

Да и установка бряка косяк тоже, биты в ДР7 надо тыкать не всегда как 0х101, а соответственно номеру регистра и типу бряка. Читай ман интела, в общем.



Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 09 июня 2009 00:27
· Личное сообщение · #11

В чем проблема собственно заключается не могу понять ?




Ранг: 681.5 (! !), 405thx
Активность: 0.420.21
Статус: Участник
ALIEN Hack Team

Создано: 09 июня 2009 14:00 · Поправил: ARCHANGEL
· Личное сообщение · #12

Clerk
Насколько я понял - проблема заключалась в том, что у SVIN95 не получалось продолжить выполнение программы после срабатывания аппаратников.

-----
Stuck to the plan, always think that we would stand up, never ran.




Ранг: 39.0 (посетитель)
Активность: 0.040
Статус: Участник

Создано: 09 июня 2009 14:59
· Личное сообщение · #13

Clerk
Проблема решена уже.

ARCHANGEL
Именно так.


 eXeL@B —› Программирование —› Hardware breakpoints
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати