Вызывает ли чтение регистра отладки исключение, если установлен флаг 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>

person Rahl2500    schedule 14.12.2020    source источник
comment
Действительно, в руководствах Intel иногда говорится о доступе, а иногда о модификации, например. в Таблице 17-2, Исключительные условия отладки.   -  person Nate Eldredge    schedule 14.12.2020
comment
Ваш пример вообще не обращается к регистрам отладки. ContextRecord не присущ центральному процессору и не подвергается какой-либо специальной обработке (помимо обычной сегментации памяти и разбиения по страницам).   -  person ecm    schedule 14.12.2020
comment
@ecm Я добавил недостающий код для большего контекста (без каламбура), если теперь это имеет смысл. Исходные инструкции являются частью обработчика исключений, который помещается в стек и вызывается позже, откуда смещение используется для доступа к записи контекста.   -  person Rahl2500    schedule 14.12.2020
comment
@ Rahl2500: добавленный код также не имеет прямого доступа ни к одному из регистров отладки. Только инструкции формы mov XXX, drX (xxx = регистр, x = число) имеют прямой доступ к ним.   -  person ecm    schedule 14.12.2020


Ответы (1)


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

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

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

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

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

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

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

person Margaret Bloom    schedule 14.12.2020
comment
›Вредоносные программы с CPL 0 могут использовать флаг GD, но я пока не нашел ни одного. Интересно. Разве попытка изменить сам флаг GD не вызовет #GP, поскольку DR7 является регистром отладки? - person Rahl2500; 14.12.2020
comment
@Rahl2500: Руководство разработчика программного обеспечения 17.2.4: Процессор очищает флаг GD при входе в обработчик исключений отладки, чтобы разрешить обработчику доступ к регистрам отладки. Поэтому, если он не установлен, вы можете установить его (начиная с CPL 0). Он остается установленным до тех пор, пока не произойдет исключение отладки. В этот момент он очищается, и если вы все еще хотите, чтобы он был включен, обработчик должен установить его снова. - person Nate Eldredge; 14.12.2020