Использование TLS для антиотладки
Использование TLS для антиотладки
TLS (Thread Local Storage) - локальная память потока, предназначенная для связки данных с потоком. Эта структура изначально была создана для решения проблемы совместного доступа к данным в многопоточных приложениях. TLS бывают статичными и динамическими. Углубляться в эти дебри сейчас не будем, для этого есть Джеффри Рихтер с его книгой "Windows для профессионалов". Нас интересует только тот факт, что при использовании статичной TLS появляется возможность выполнять произвольный код до передачи управления на EP. Это можно использовать для обнаружения отладчика еще до того, как он получит управление над программой.
Секция TLS представляет собой структуру с фиксированным порядковым номером 9 и строго определенным набором данных. Нарушать их последовательность ни в коем случае нельзя. Вот как это выглядит на FASM:
Code (Assembler) : Убрать нумерацию
- ;------------------------------------------------
- ; Секция TLS
- ;------------------------------------------------
- data 9
- dd 0 ; Raw Data Start VA
- dd 0 ; Raw Data End VA
- dd tls_index ; Address of Index
- dd tls_callbacks ; Address of Callbacks
- dd 0 ; Size of Zero Fill
- dd 0 ; Reserved
- tls_index dd 0 ; Index
- tls_callbacks dd anti_debug1 ; Callbacks
- dd anti_debug2
- dd 0 ; End
- end data
Возвращаемся к структуре. В поле Address of Callbacks прописывается указатель на массив адресов функций, которые должны вызываться при загрузке программы. Массив адресов заканчивается нулевым элементом. Последовательность вызова callback-функций, как несложно догадаться, определяется положением адреса в массиве. Более того, при обработке цепочки callback-функции могут динамически менять или добавлять новые записи в массиве, тут единственное условие, чтобы они стояли после выполняемой в данный момент callback-функции. Загрузчик обрабатывает массив в реальном времени, беря следующую запись только в момент, когда предыдущая callback-функция завершила свою работу.
Для обнаружения отладчика воспользуемся парочкой хорошо известных трюков. Это проверка параметра BeingDebugged из PEB и флага из структуры RTL_USER_PROCESS_PARAMETERS.
Code (Assembler) : Убрать нумерацию
- ;------------------------------------------------
- ; Anti-Debug Trick 1
- ;------------------------------------------------
- proc anti_debug1
- ; Указатель на РЕВ
- mov eax,[fs:30h]
- ; Флаг отладки из PEB
- cmp [eax+PEB.BeingDebugged],0
- ; Отладчик не обнаружен
- jz .loc_ret
- ...
- ; Действия при обнаружении отладчика
- ...
- .loc_ret:
- ret
- endp
Code (Assembler) : Убрать нумерацию
- ;------------------------------------------------
- ; Anti-Debug Trick 2
- ;------------------------------------------------
- proc anti_debug2
- ; Указатель на РЕВ
- mov eax,[fs:30h]
- ; Указатель на PEB.ProcessParameters
- mov eax,[eax+PEB.ProcessParameters]
- ; Проверить 14-й бит в поле флагов
- test [eax+RTL_USER_PROCESS_PARAMETERS.Flags],0x4000
- ; Отладчик не обнаружен
- jnz .loc_ret
- ...
- ; Действия при обнаружении отладчика
- ...
- .loc_ret:
- ; Добавить новую запись в цепочку вызовов
- mov dword [tls_callbacks+4*2],dyn_callback
- mov dword [tls_callbacks+4*3],0
- ret
- endp
- ;------------------------------------------------
- ; Обработчик, который не описан в цепочке вызовов
- ; и добавляется динамически в предыдущей функции
- ;------------------------------------------------
- proc dyn_callback
- ret
- endp
TLS-callbacks в дизассемблере IDA Pro
Несмотря на то, что антиотладочные трюки с использованием TLS давно известны, возможность раннего исполнения кода нельзя недооценивать. Ведь совершенно необязательно сразу кричать об отладке, достаточно взвести какой-нибудь флаг, который будет влиять, например, на корректность расчетов в программе. Да и без поиска отладчиков в callback-функциях TLS можно динамически модифицировать код, расшифровывать какие-нибудь данные и выполнять прочие действия, которые могут надолго озадачить начинающего реверсера.
Сегодня мы в очередной раз убедились, что любую технологию можно использовать как во благо, так и во зло, в зависимости от того, по какую сторону баррикады вы находитесь.
В приложении пример программы с исходным текстом, которая использует TLS для обнаружения отладчика.
Просмотров: 2071 | Комментариев: 1
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(01.11.2021 в 02:26):
Добавил пример с динамической модификацией цепочки вызовов. Архив обновлен.
Добавить комментарий
Заполните форму для добавления комментария