Привет, форумчане! Прохожу урок 37 Нарваховский, но похоже не получается telock так как он пишет в своей статье, а именно в этом месте: ссылка на урок: http://wasm.ru/article.php?article=ollydbg37 программа здесь: http://wasm.ru/pub/23/files/ollydbg36.zip Удручает, то что этот брейк не работает в telock(пример). Telock упорно сопротивляется установке бряков, даже тех, которые должны якобы должны работать. Зараза telock, проверяет, чтобы в коде не было бряков. Вопрос: Как же так получается, я устанавливаю бряк на чтение мемори в Ольке, телок, чтобы определить это дело, должен по идее прочитать эту часть кода, где установлен мой бряк, для сравнения на изменения и тут то мой бряк по идее должен всплыть, но он зараза не всплывает. Как может быть так? Каков здесь механизм, как лучше посмотреть на него?
И все же вопрос актуален: Как код может контролировать свой код, например если у меня установлен бряк в коде на чтение или аccess, ведь для того чтобы проверить этот код его необходимо механизму защиты прочитать и тут то Олька должна его схватить по-идее за жабры. Или нет?
neutronion Вы путаете int3, hardware breakpoint и memory breakpoint. 1) С изменением кода связан только int3 (первый байт инструкции заменяется на 0CCh). Обнаружение возможно с помощью чтения области памяти с брэйкпоинтом. 2) Hardware breakpoint устанавливается с помощью отладочных регистров CPU. Таких брейкпоинтов может быть не более четырёх, и они в отличие от других видов брейкпоинтов локальны для потока, в котором установлены. Обнаружение возможно чтением отладочного регистра. 3) Memory breakpoint помечает страницу недоступной. Соответственно он так же, как и int3, глобален для процесса. Минус этого брейкпоинта в его быстродействии, т.к. он срабатывает каждый раз, когда возникает попытка доступа к странице. После чего отладчик проверяет, относится ли попытка доступа к той части страницы, на которую фактически был поставлен брэйкпоинт. Обнаружение возможно чтением атрибутов страницы. Как видно, на доступ к памяти (которым в частности является и исполнение кода) можно поставить только 2-й и 3-й типы. При этом такие брэйкпоинты не обнаружимы сравнением содержимого памяти с оригинальным, т.к. оно не меняется. int3 срабатывает, как точка останова, только если он исполняется как код, но не при попытке чтения. При попытке чтения программа, разумеется, не будет поймана отладчиком.
Тогда защитному коду достаточно узнать, что страница стала недоступна по 3 варианту, и таким образом защита будет знать, что что-то пошло не так и завершить программу. Я правильно понимаю?
Memory breakpoint на telock'е срабатывать должен. Hardware breakpoint уже нет, так как в этом упаковщике юзается самотрассировка, примерно так это выглядит: Устанавливается хендлер для обработки исключений, затем пробегается следующий код: Код (Text): int 3 ; попадаем в ранее установленный обработчик nop mov eax, eax addr3 stc ; из обработчика сюда ставится hardware breakpoinе 3 (через DR3 регистр) nop lea eax, ds:1234h[ebx*2] addr2 clc ; из обработчика сюда ставится hardware breakpoinе 2 (через DR2 регистр) nop shr ebx, 5 addr1 cld ; из обработчика сюда ставится hardware breakpoinе 1 (через DR1 регистр) nop rol eax, 7 addr0 nop ; из обработчика сюда ставится hardware breakpoinе 0 (через DR0 регистр) nop xor ebx, ebx div ebx ; EXCEPTION_INT_DIVIDE_BY_ZERO Обработчик выглядит так: Код (Text): EXCEPTION_DISPOSITION __cdecl _except_handler( struct _EXCEPTION_RECORD *ExceptionRecord, void *EstablisherFrame, struct _CONTEXT *ContextRecord, void *DispatcherContext ) { // skip problem instruction ContextRecord->Eip++; switch ( ExceptionRecord->ExceptionCode ) { case EXCEPTION_INT_DIVIDE_BY_ZERO: { ContextRecord->Eip++; // размер div reg равен 2м байтам, так что нужно пропустить еще 1 байт ContextRecord->Dr0 = 0; ContextRecord->Dr1 = 0; ContextRecord->Dr2 = 0; ContextRecord->Dr3 = 0; ContextRecord->Dr6 = 0x0FFFF0FF0; // обнуляем все поля кроме зарезервированных ContextRecord->Dr7 = 0xDC00; // 1101110000000000 - обнуляем все поля кроме зарезервированных return ExceptionContinueExecution; } break; case EXCEPTION_SINGLE_STEP: { call skip_next_byte db 0 // счетчик выполненных DR бряков. Если не равен 4, то нас отлаживают через DR регистры skip_next_byte: ... pop eax inc byte ptr [eax] // инкремент счетчика DR бряков return ExceptionContinueExecution; } break; case EXCEPTION_BREAKPOINT: { ContextRecord->Dr0 = addr0; ContextRecord->Dr1 = addr1; ContextRecord->Dr2 = addr2; ContextRecord->Dr3 = addr3; ContextRecord->Dr6 = 0x0FFFF0FF0; // обнуляем все поля кроме зарезервированных ContextRecord->Dr7 = 0x155; // 101010101 - включили 4 локальных точки останова + установили флаг LocalEnable return ExceptionContinueExecution; } break; default: break; } } Если стоит цель разобраться с механизмом отладки, то telock с выше приведенным разжеванным материалом может этому поспособствовать =]
уверяю вас, мемори он write не работает. попробуйте сами, адрес где записывается адрес функции GetVersion 406adc - и попробуйте запустить, ничего не получается.