Гайд [Reverse-Engineering] Ломаем всю защиту лоадера QHide

Разработчик
Статус
Оффлайн
Регистрация
18 Мар 2020
Сообщения
439
Реакции[?]
870
Поинты[?]
195K
Шалом! Это моя первая статья здесь, в честь моего недавнего разбана я решил сюда закинуть довольно интересную статью с нахождением и патчей анти-дебаг трюков.

1. Архитектура файла

Сам файл имеет x64 разрядность и накрыт VMProtect, однако она тут играет малую роль, из всего функционала там используется только антидебаг из юзермода и мутация кода. Импорты никак не защищены, будем иметь это в виду =)

2. Проверка на валидный пароль

Из моей последней статьи на синем форум можно понять, что пароль в лоадере генерировался за счёт никнейма. В дебаггере в два регистра передавались две переменные: Пароль и ник, и после этого вызывалась функция с генерацией и проверки пароля, если функция возвращала 0, значит пароль был невалидным.

1631310005862.png

Код:
QWORD PTR SS:[RSP+140] - Пароль
QWORD PTR SS:[RSP+1B0] - Ник

CALL 00007FF746B52AF0 - Вызов генерации и проверки
На пароль сейчас не будем обращать внимание, ибо мы хотели сломать всю защиту :)


3. Архитектура защиты

В этой части я столкнулся с неприятными антидебаг трюками, которые я разделю на подпункты.

3.1. Антидебаг с помощью VEH

А эта проверка была написана исключительно для меня :D

В прошлых версиях лоадера я обходил всю защиту меняя адрес RIP на начало функции инжекта и деттачился, чтобы не наткнуться на антидебаг функцию во время инжекта. В этой версии кодер это зафиксил добавив переменные, которые будут меняться в других функциях, да бы я просто так не прошел уже меняя адрес, ну и что-то по типу PAGE_GUARD хуков но с другим назначением.

1631310066343.png

Суть в том чтобы вызвать PAGE_GUARD исключение и схватить его, в адресе на котором установлен VEH идет проверка на значение исключение, т.е. если исключение == 80000001 (PAGE_GUARD), то лоадер прекращает свою работу, все это выглядит так:

1631310088832.png

Если же джамп не произошел, то идет проверка уже на C0000005. Просто нопаем JNE проверку и антидебаг трик побежден :)


3.2. Хитрый трюк против ScyllaHide

Этот трюк выполняется уже во время вызова TLS Callback. Все мы знаем про хуки сциллыхайд и её проверки на параметры вызывающей функции. Тут трюк состоял в том чтобы патчить проверку у сциллыхайд на хук NtSetInformationThread, т.е. оригинальный хук проверял ThreadInformationClass на наличие 0x11 (ThreadHideFromDebugger) с помощью JNE, если они не были равны, то он просто скипал и шел дальше, но тут QHide просто меняет JNE на JMP и из-за этого хук сциллыхайд перестает работать и поток по итогу всё равно скрывается :) Довольно интересный трюк, который сразу и не заметишь, если не обратить внимание на вызов TLS Callback и завершающий код процесса (0x80000003).

До TLS каллбэка:


После TLS каллбэка:


Просто ставим RET в начало функции и этот трик побежден :)

3.3. Поток с проверкой на анти-дебаг

По своей невнимательности на этот трюк я потратил больше всего времени, ибо не совсем понимал почему вызывался NtCreateThreadEx, а адреса в регистре не было :) Затем заметив функцию с которой стартовал поток я начал её листать и понял что это детект hardware бряков. Этот трюк довольно распространенный и обходится он все также хуками от сциллыхайд.



Исходный код детекта:



3.4. Проверки на Breakpoints и патч return

В этом подпункте QHide сделал проверки на байты на важные функции, список байтов которые он проверял:
Код:
0xC3 - RET
0xCC - INT3 (Software Breakpoint)
Проверки на байты:


Уже ничего не мешало составить паттерны для нахождения других мест с проверками.
Паттерны:
Код:
3D C3 00 00 00 - cmp eax, 0xC3
3D CC 00 00 00 - cmp eax, 0xCC
Патчим все это дело и переходим к последнему подпункту.

3.5. Анти-дебаг трюки во время инжекта

В ранних версиях QHide никак не защищал дллку, а лишь просто держал её в репозитории гитхаба делая хттп реквест чтобы скачать. Теперь же в этой версии она сидит там уже зашифрованной, и в функции инжекта сидят антидебаг трюки, здесь уже было тяжело трассировать по той причине, что любой колл мог привести к антидебаг трюку и по итогу не загрузить длл полностью. Но тем не менее этот трюк переставал работать из-за хуков сциллыхайд. А именно лоадер вызывал NtQueryInformationProcess с параметром Debug Port (можно понять по 0x7 параметру)


Нопаем проверку и на этом отключение защиты подходит к концу.

Затем нопаем саму проверку авторизации и получаем нашу заветную длл, которая будет находится в регионе памяти лоадера с правами RWX :)



На этом у меня всё, возможно я упустил некоторые детали, но тем не менее защита отключена, дллка чистая у меня. Сама статья по содержанию кажется не очень длинной, но вот дебажить это чудо было затратно по времени. Спасибо кто решился почитать эту статью, мне и самому было весело это сидеть и патчить :D

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


Всего хорошего!
 
Последнее редактирование:
Участник
Статус
Оффлайн
Регистрация
29 Дек 2019
Сообщения
381
Реакции[?]
168
Поинты[?]
3K
Шалом! Это моя первая статья здесь, в честь моего недавнего разбана я решил сюда закинуть довольно интересную статью с нахождением и патчей анти-дебаг трюков.

1. Архитектура файла

Сам файл имеет x64 разрядность и накрыт VMProtect, однако она тут играет малую роль, из всего функционала там используется только антидебаг из юзермода и мутация кода. Импорты никак не защищены, будем иметь это в виду =)

2. Проверка на валидный пароль

Из моей последней статьи на синем форум можно понять, что пароль в лоадере генерировался за счёт никнейма. В дебаггере в два регистра передавались две переменные: Пароль и ник, и после этого вызывалась функция с генерацией и проверки пароля, если функция возвращала 0, значит пароль был невалидным.

Посмотреть вложение 171192

Код:
QWORD PTR SS:[RSP+140] - Пароль
QWORD PTR SS:[RSP+1B0] - Ник

CALL 00007FF746B52AF0 - Вызов генерации и проверки
На пароль сейчас не будем обращать внимание, ибо мы хотели сломать всю защиту :)


3. Архитектура защиты

В этой части я столкнулся с неприятными антидебаг трюками, которые я разделю на подпункты.

3.1. Антидебаг с помощью VEH

А эта проверка была написана исключительно для меня :D

В прошлых версиях лоадера я обходил всю защиту меняя адрес RIP на начало функции инжекта и деттачился, чтобы не наткнуться на антидебаг функцию во время инжекта. В этой версии кодер это зафиксил добавив переменные, которые будут меняться в других функциях, да бы я просто так не прошел уже меняя адрес, ну и что-то по типу PAGE_GUARD хуков но с другим назначением.

Посмотреть вложение 171193

Суть в том чтобы вызвать PAGE_GUARD исключение и схватить его, в адресе на котором установлен VEH идет проверка на значение исключение, т.е. если исключение == 80000001 (PAGE_GUARD), то лоадер прекращает свою работу, все это выглядит так:

Посмотреть вложение 171194

Если же джамп не произошел, то идет проверка уже на C0000005. Просто нопаем JNE проверку и антидебаг трик побежден :)


3.2. Хитрый трюк против ScyllaHide

Этот трюк выполняется уже во время вызова TLS Callback. Все мы знаем про хуки сциллыхайд и её проверки на параметры вызывающей функции. Тут трюк состоял в том чтобы патчить проверку у сциллыхайд на хук NtSetInformationThread, т.е. оригинальный хук проверял ThreadInformationClass на наличие 0x11 (ThreadHideFromDebugger) с помощью JNE, если они не были равны, то он просто скипал и шел дальше, но тут QHide просто меняет JNE на JMP и из-за этого хук сциллыхайд перестает работать и поток по итогу всё равно скрывается :) Довольно интересный трюк, который сразу и не заметишь, если не обратить внимание на вызов TLS Callback и завершающий код процесса (0x80000003).

До TLS каллбэка:


После TLS каллбэка:


Просто ставим RET в начало функции и этот трик побежден :)

3.3. Поток с проверкой на анти-дебаг

По своей невнимательности на этот трюк я потратил больше всего времени, ибо не совсем понимал почему вызывался NtCreateThreadEx, а адреса в регистре не было :) Затем заметив функцию с которой стартовал поток я начал её листать и понял что это детект memory бряков. Этот трюк довольно распространенный и обходится он все также хуками от сциллыхайд.



Исходный код детекта:



3.4. Проверки на Breakpoints и патч return

В этом подпункте QHide сделал проверки на байты на важные функции, список байтов которые он проверял:
Код:
0xC3 - RET
0xCC - INT3 (Software Breakpoint)
Проверки на байты:


Уже ничего не мешало составить паттерны для нахождения других мест с проверками.
Паттерны:
Код:
3D C3 00 00 00 - cmp eax, 0xC3
3D CC 00 00 00 - cmp eax, 0xCC
Патчим все это дело и переходим к последнему подпункту.

3.5. Анти-дебаг трюки во время инжекта

В ранних версиях QHide никак не защищал дллку, а лишь просто держал её в репозитории гитхаба делая хттп реквест чтобы скачать. Теперь же в этой версии она сидит там уже зашифрованной, и в функции инжекта сидят антидебаг трюки, здесь уже было тяжело трассировать по той причине, что любой колл мог привести к антидебаг трюку и по итогу не загрузить длл полностью. Но тем не менее этот трюк переставал работать из-за хуков сциллыхайд. А именно лоадер вызывал NtQueryInformationProcess с параметром Debug Port (можно понять по 0x7 параметру)


Нопаем проверку и на этом отключение защиты подходит к концу.

Затем нопаем саму проверку авторизации и получаем нашу заветную длл, которая будет находится в регионе памяти лоадера с правами RWX :)



На этом у меня всё, возможно я упустил некоторые детали, но тем не менее защита отключена, дллка чистая у меня. Сама статья по содержанию кажется не очень длинной, но вот дебажить это чудо было затратно по времени. Спасибо кто решился почитать эту статью, мне и самому было весело это сидеть и патчить :D

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


Всего хорошего!
quality content
 
Memories of you
Эксперт
Статус
Оффлайн
Регистрация
14 Дек 2018
Сообщения
1,864
Реакции[?]
484
Поинты[?]
11K
Шалом! Это моя первая статья здесь, в честь моего недавнего разбана я решил сюда закинуть довольно интересную статью с нахождением и патчей анти-дебаг трюков.

1. Архитектура файла

Сам файл имеет x64 разрядность и накрыт VMProtect, однако она тут играет малую роль, из всего функционала там используется только антидебаг из юзермода и мутация кода. Импорты никак не защищены, будем иметь это в виду =)

2. Проверка на валидный пароль

Из моей последней статьи на синем форум можно понять, что пароль в лоадере генерировался за счёт никнейма. В дебаггере в два регистра передавались две переменные: Пароль и ник, и после этого вызывалась функция с генерацией и проверки пароля, если функция возвращала 0, значит пароль был невалидным.

Посмотреть вложение 171192

Код:
QWORD PTR SS:[RSP+140] - Пароль
QWORD PTR SS:[RSP+1B0] - Ник

CALL 00007FF746B52AF0 - Вызов генерации и проверки
На пароль сейчас не будем обращать внимание, ибо мы хотели сломать всю защиту :)


3. Архитектура защиты

В этой части я столкнулся с неприятными антидебаг трюками, которые я разделю на подпункты.

3.1. Антидебаг с помощью VEH

А эта проверка была написана исключительно для меня :D

В прошлых версиях лоадера я обходил всю защиту меняя адрес RIP на начало функции инжекта и деттачился, чтобы не наткнуться на антидебаг функцию во время инжекта. В этой версии кодер это зафиксил добавив переменные, которые будут меняться в других функциях, да бы я просто так не прошел уже меняя адрес, ну и что-то по типу PAGE_GUARD хуков но с другим назначением.

Посмотреть вложение 171193

Суть в том чтобы вызвать PAGE_GUARD исключение и схватить его, в адресе на котором установлен VEH идет проверка на значение исключение, т.е. если исключение == 80000001 (PAGE_GUARD), то лоадер прекращает свою работу, все это выглядит так:

Посмотреть вложение 171194

Если же джамп не произошел, то идет проверка уже на C0000005. Просто нопаем JNE проверку и антидебаг трик побежден :)


3.2. Хитрый трюк против ScyllaHide

Этот трюк выполняется уже во время вызова TLS Callback. Все мы знаем про хуки сциллыхайд и её проверки на параметры вызывающей функции. Тут трюк состоял в том чтобы патчить проверку у сциллыхайд на хук NtSetInformationThread, т.е. оригинальный хук проверял ThreadInformationClass на наличие 0x11 (ThreadHideFromDebugger) с помощью JNE, если они не были равны, то он просто скипал и шел дальше, но тут QHide просто меняет JNE на JMP и из-за этого хук сциллыхайд перестает работать и поток по итогу всё равно скрывается :) Довольно интересный трюк, который сразу и не заметишь, если не обратить внимание на вызов TLS Callback и завершающий код процесса (0x80000003).

До TLS каллбэка:


После TLS каллбэка:


Просто ставим RET в начало функции и этот трик побежден :)

3.3. Поток с проверкой на анти-дебаг

По своей невнимательности на этот трюк я потратил больше всего времени, ибо не совсем понимал почему вызывался NtCreateThreadEx, а адреса в регистре не было :) Затем заметив функцию с которой стартовал поток я начал её листать и понял что это детект memory бряков. Этот трюк довольно распространенный и обходится он все также хуками от сциллыхайд.



Исходный код детекта:



3.4. Проверки на Breakpoints и патч return

В этом подпункте QHide сделал проверки на байты на важные функции, список байтов которые он проверял:
Код:
0xC3 - RET
0xCC - INT3 (Software Breakpoint)
Проверки на байты:


Уже ничего не мешало составить паттерны для нахождения других мест с проверками.
Паттерны:
Код:
3D C3 00 00 00 - cmp eax, 0xC3
3D CC 00 00 00 - cmp eax, 0xCC
Патчим все это дело и переходим к последнему подпункту.

3.5. Анти-дебаг трюки во время инжекта

В ранних версиях QHide никак не защищал дллку, а лишь просто держал её в репозитории гитхаба делая хттп реквест чтобы скачать. Теперь же в этой версии она сидит там уже зашифрованной, и в функции инжекта сидят антидебаг трюки, здесь уже было тяжело трассировать по той причине, что любой колл мог привести к антидебаг трюку и по итогу не загрузить длл полностью. Но тем не менее этот трюк переставал работать из-за хуков сциллыхайд. А именно лоадер вызывал NtQueryInformationProcess с параметром Debug Port (можно понять по 0x7 параметру)


Нопаем проверку и на этом отключение защиты подходит к концу.

Затем нопаем саму проверку авторизации и получаем нашу заветную длл, которая будет находится в регионе памяти лоадера с правами RWX :)



На этом у меня всё, возможно я упустил некоторые детали, но тем не менее защита отключена, дллка чистая у меня. Сама статья по содержанию кажется не очень длинной, но вот дебажить это чудо было затратно по времени. Спасибо кто решился почитать эту статью, мне и самому было весело это сидеть и патчить :D

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


Всего хорошего!
Вот таким образом и взломали жопу езоротика
Абдулов moment
 
Продавец
Статус
Оффлайн
Регистрация
28 Окт 2019
Сообщения
1,153
Реакции[?]
302
Поинты[?]
3K
Хз почему, но у меня ничего не сработало здесь, Ставлю на ntsetinformationthread ret, ноплю проверку на page_guard, патчу проверку байтов на breakpoint, чтоб обойти вызов месаджбокса, все остальное по заверению автора должно обходиться хуками скиллы хайд, которая включена по полному и нихрена, пишет об обнаружении дебаггера, мб версия другая или че хз
 
Разработчик
Статус
Оффлайн
Регистрация
18 Мар 2020
Сообщения
439
Реакции[?]
870
Поинты[?]
195K
Ставлю на ntsetinformationthread ret
Ты хотя бы понимаешь, что NtSetInformationThread во время работы программы вызывается не только с лоадера? Поставь на него бряк и посчитай сколько раз будет совершен вызов с условного kernelbase


пишет об обнаружении дебаггера
Ну видимо ты плохо пропатчил, msgbox вылезает если человек завалил проверку с байтами или проверку на hardware бряки, второй чек происходит в новом потоке
 
Продавец
Статус
Оффлайн
Регистрация
28 Окт 2019
Сообщения
1,153
Реакции[?]
302
Поинты[?]
3K
Ты хотя бы понимаешь, что NtSetInformationThread во время работы программы вызывается не только с лоадера? Поставь на него бряк и посчитай сколько раз будет совершен вызов с условного kernelbase



Ну видимо ты плохо пропатчил, msgbox вылезает если человек завалил проверку с байтами или проверку на hardware бряки, второй чек происходит в новом потоке
Скорее всего я не пропатчил скрытие потока и второй чек вызвал месаджбокс.
Я просто не понял, что ты имел ввиду в фразе "Просто ставим RET в начало функции и этот трик побежден :)" в пункте 3.2. Какой конкретно функции, в TLS или в самой функции ntsetinformation thread ?
 
Разработчик
Статус
Оффлайн
Регистрация
18 Мар 2020
Сообщения
439
Реакции[?]
870
Поинты[?]
195K
Скорее всего я не пропатчил скрытие потока и второй чек вызвал месаджбокс.
Я просто не понял, что ты имел ввиду в фразе "Просто ставим RET в начало функции и этот трик побежден :)" в пункте 3.2. Какой конкретно функции, в TLS или в самой функции ntsetinformation thread ?
ну если ты перечитал бы ещё пару раз и внимательно вникал, то понял бы шо надо патчить tls каллбэк
 
practice makes perfect
Пользователь
Статус
Оффлайн
Регистрация
16 Мар 2019
Сообщения
87
Реакции[?]
68
Поинты[?]
20K
Скорее всего я не пропатчил скрытие потока и второй чек вызвал месаджбокс.
Я просто не понял, что ты имел ввиду в фразе "Просто ставим RET в начало функции и этот трик побежден :)" в пункте 3.2. Какой конкретно функции, в TLS или в самой функции ntsetinformation thread ?
Забей,мой лоадер нереально крякнуть
 
Сверху Снизу