Вызывает ли чтение регистра отладки исключение, если установлен флаг GD?

Недавно я провел некоторое исследование регистров отладки и того, как некоторые вредоносные программы могут манипулировать ими в качестве тактики против отладки. Одна из вещей, которые я прочитал несколько раз, заключается в том, что это можно предотвратить, используя флаг General Detect в DR7, который вызывает исключение отладки, если инструкция MOV используется для доступа к любому из DR0-DR7.

Однако мне не ясно, что именно означает доступ - если, например, инструкция mov используется только для помещения адреса DR0-DR3 в регистр общего назначения, чтобы его можно было прочитать, вызовет ли это отладку? исключение, которое будет вызвано, когда установлен флаг GD? Или это происходит только в том случае, если инструкция MOV используется для фактического изменения содержимого регистра? То, что я читал до сих пор, было немного двусмысленным по этому поводу.

Я столкнулся с приведенной ниже сборкой в ​​тексте, который показывает манипулирование регистрами отладки, но в этом случае mov используется только для получения адреса регистров отладки, а фактическая модификация выполняется с помощью инструкции или, поэтому я не уверен, что это код вызовет исключение, если установлен GD.

    xor eax, eax
    push offset except_callback
    push d fs:[eax]
    mov fs:[eax], esp
    int 3 ;force an exception to occur
    ...        

    except_callback:
     mov eax, [esp+0ch] ;get ContextRecord
     mov ecx, [eax+4] ;Dr0
     or ecx, [eax+8] ;Dr1
     or ecx, [eax+0ch] ;Dr2
     or ecx, [eax+10h] ;Dr3
     jne <Debugger_detected>

Действительно, в руководствах Intel иногда говорится «доступ», а иногда — «изменение», например. в Таблице 17-2, Исключительные условия отладки.

Nate Eldredge 14.12.2020 06:10

Ваш пример вообще не обращается к регистрам отладки. «ContextRecord» не присущ ЦП и не подвергается какой-либо специальной обработке (помимо обычной сегментации памяти и подкачки).

ecm 14.12.2020 09:07

@ecm Я добавил недостающий код для большего контекста (без каламбура), если теперь это имеет смысл. Исходные инструкции являются частью обработчика исключений, который помещается в стек и вызывается позже, откуда смещение используется для доступа к записи контекста.

Rahl2500 14.12.2020 16:54

@ Rahl2500: добавленный код также не имеет прямого доступа ни к одному из регистров отладки. Только инструкции формы mov XXX, drX (xxx = регистр, x = число) имеют прямой доступ к ним.

ecm 14.12.2020 18:25
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
1
4
361
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Intel довольно четко об этом говорит:

Попытка чтения или записи регистров отладки с любого другого уровня привилегий генерирует исключение общей защиты (#GP).

Таким образом, чтение или запись регистра отладки, когда он не работает на CPL 0, вызовет исключение независимо от флага GD.

На самом деле, я проанализировал довольно много вредоносных программ, и ни одна из них не имеет прямого доступа к регистрам отладки. Они получают текущий контекст потока (GetThreadContext или NtGetContextThread или аналогичные варианты WOW64) и оттуда проверяют значения регистров отладки, обратите внимание, что в этом случае регистр отладки считывает ядро ​​Windows. Этот антиотладочный трюк можно обойти вручную (с помощью точки останова в API, извлекающей контекст) или с помощью подключаемого модуля отладчика. Вредоносные программы, работающие на CPL 0, могут использовать флаг GD, но я пока не нашел ни одного.

Отвечая на ваш вопрос в заголовке, любой доступ для чтения или записи (при CPL 0) к регистру отладки вызовет #GP, если установлен GD. Я не тестировал его, но, учитывая его предполагаемое использование (для поддержки эмулятора аппаратного отладчика), идея состоит в том, чтобы «виртуализировать» регистры отладки. Аппаратный отладчик, эмулированный в программном обеспечении, может затем использовать регистр отладки, даже если отлаживаемая ОС уже использует их. Это делается путем сбоя при каждом доступе и правильной замены значений ОС и эмулятора.

Если бы ошибались только записи, эмулятор не мог бы помешать отлаживаемой ОС прочитать неправильное значение (помещенное туда эмулятором) из регистра отладки.

Включает (если установлено) защиту отладочного регистра, которая вызывает исключение отладки, которое будет сгенерировано перед любой инструкцией MOV, которая обращается к регистру отладки. Когда такой условие обнаружено, флаг BD в регистре состояния отладки DR6 устанавливается перед созданием исключения. Этот предусмотрено условие для поддержки внутрисхемных эмуляторов. Когда эмулятору необходимо получить доступ к регистрам отладки, программное обеспечение эмулятора может установить флаг GD, чтобы предотвратить помехи от программы, которая в данный момент выполняется на процессоре.
Процессор очищает флаг GD при входе в обработчик исключений отладки, чтобы разрешить обработчику доступ к отладочные регистры.

>"Вредоносные программы, работающие с CPL 0, могут использовать флаг GD, но я пока не нашел ни одного". Интересный. Разве попытка изменить сам флаг GD не вызовет #GP, поскольку DR7 является регистром отладки?

Rahl2500 14.12.2020 16:23

@ Rahl2500: Руководство разработчика программного обеспечения 17.2.4: «Процессор сбрасывает флаг GD при входе в обработчик исключений отладки, чтобы разрешить обработчику доступ к регистрам отладки». Поэтому, если он не установлен, вы можете установить его (начиная с CPL 0). Он остается установленным до тех пор, пока не произойдет исключение отладки. В этот момент он очищается, и если вы все еще хотите, чтобы он был включен, обработчик должен установить его снова.

Nate Eldredge 14.12.2020 16:39

Другие вопросы по теме