C++ Гайд Защита для вашего лоадера. Антидебаг без анти дебага или как на руси защиту придумывали

Олдфаг
Статус
Оффлайн
Регистрация
4 Янв 2020
Сообщения
2,992
Реакции[?]
1,274
Поинты[?]
19K
Дисклеймер. Не стоит сильно воспринимать всерьез сказанное в этой теме. Просто делюсь тем что смог случайно наверное реализовать
Сидя дома и делая лоадер для своего будущего проекта я столкнулся с проблемой защиты потоков от заморозки. И как нельзя кстати мне попалась одна тема на югейме где челик задавал вопрос по этой теме. Там давали весьма дельные советы такие персоны как
Keaton
colby57 и другие. Спасибо вам ребятки за идеи и советы, но сейчас не об этом.
Собственно второй человек из этого списка скинул мне один материальчик в котором было расписано о том как отладчики могу реагировать на трюк с проверкой на заморозку потоков и как оказалось это более чем неплохо в современных реалиях. Если проще с помощью пары строк кода я смог сделать подобие анти-дебага без использование любых антидебаг трюков. Изначально я догадывался что это можно реализовать так, но данный материальчик мне в целом неплохо помог.
Суть в том что отладчики при аттаче могут проворачивать болезненный для себя трюк связанный с заморозкой потоков(тоже самое с бряками). Исходя из этой информации мы с вами можем смело напастить две проверки:
проверка на то заморожен поток или нет и проверка на время исполнения кода. Я покажу оба трюка.
Для начала для тех кто не знал, потоки можно создавать с определенными флагами, пример такого флага - 0x40 (AKA BYPASS PROCESS FREEZE). Данный флаг создает поток который сможет спокойно функционировать даже когда основной поток программы заморожен(из плюсов если у вас какая-то защита в потоке, то при бряке ну и при условии что прога конечно триггернула защиту вы сможете что либо сделать не взирая на саму заморозку процесса). Собственно надеюсь вы поняли как это можно использовать на практике, так что к коду.
Есть в винапи такие веселые функции как: Resume и SuspendThread, что имеют вывод. Да их можно запатчить, но сейчас не об этом. Если первая функция ResumeThread имеет возвращаемое значение отличное от нуля, то можно смело критовать ибо ваш поток был заморожен. Осталось только сделать простую реализацию, создаем поток, получаем хендл нужного для защиты потока путем создания и переменной и задавания ей значения CreateThread.
И все что остается сделать такие рофлы:
P.s это только пример, пожалуйста, учтите что это легко патчится.​
C++:
protectionthread_id = CreateThreadA(args); //пример получения хендла
while (1) {
            if (ResumeThread(GetCurrentThread()) != 0) { //текущий поток
                exit(-1);
            }
            if (ResumeThread(protectionthread_id) != 0) { //поток с защитой например
                exit(-1);
            }
        }
И в сумме такой код в вашем потоке во первых будет критовать при заморозке его самого так еще и при заморозке другого потока, что тоже впринципе доставит геморроя и выполнит поставленную перед нами задачку.
Трюк №2. Время исполнения кода.
Наш любимый колбасник57 уже рассказывал об
этом во все том же треде, но просто повторюсь что любой код в цикле выполняется определенное время и все что нужно засечь это время и дать пизды в случае того, если код выполнялся дольше нужного. Сразу к коду с комментариями.​
C++:
while(1) {
    auto time_start = TickCountClock::now(); //custom GetTickCount, вы можете использовать просто GetTickCount, но его хукает ScyllaHide
    std::this_thread::sleep_for(std::chrono::milliseconds(1)); //полезная нагрузка
    auto time_end = TickCountClock::now(); //время после полезной нагрузки
    if ((time_end - time_start).count() > 1100) //так как мы знаем что данная операция не может занимать больше 1 секунды, если что дело имеем с милисекундами, то выключаем нахуй кампуктер, а вернее прогу.
    {
        exit(-1);
    }
}
Вот впринципе и все. Причем тут антидебаг спросите вы? А я уже говорил здесь о том, что при аттаче дебаггером такие рофлы спокойно дадут триггер и вы спокойно поймете что вашу прогу отлаживают. В примерчике выше я кстати юзал кастомную альтернативу GetTickCount по причине что он хукается сциллой. Инфа как это сделать есть в паблике, гуглите.
Всем спасибо за ваше время и хорошего настроения.
Еще одно P.S - все трюки были проверены с помощью process hacker, scylla hide и x64dbg и полностью себя оправдывают.
И еще одно P.S -
 
Последнее редактирование:
Пользователь
Статус
Оффлайн
Регистрация
11 Июн 2020
Сообщения
177
Реакции[?]
82
Поинты[?]
0
Я даже не знаю что сказать :roflanEbalo:
Как по мне, поста колби было вполне достаточно -- любой смог бы реализовать такой трюк.
А так спасибо за пост, вполне полезно


Кста много воды, гайды лучше писать без отступлений от главной темы
 
Олдфаг
Статус
Оффлайн
Регистрация
4 Янв 2020
Сообщения
2,992
Реакции[?]
1,274
Поинты[?]
19K
Я даже не знаю что сказать :roflanEbalo:
Как по мне, поста колби было вполне достаточно -- любой смог бы реализовать такой трюк.
А так спасибо за пост, вполне полезно


Кста много воды, гайды лучше писать без отступлений от главной темы
В посте колбе был вкратце описан этот трюк только с описанием функции и логикой работы(отдаленно), пришлось додумывать свою реализацию внимание - самому.
А про воду - ну я считаю было нужно рассказать о том что да как.
 
Забаненный
Статус
Оффлайн
Регистрация
22 Апр 2020
Сообщения
731
Реакции[?]
752
Поинты[?]
1K
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Трюк №2. Время исполнения кода.
Наш любимый колбасник57 уже рассказывал об
этом во все том же треде, но просто повторюсь что любой код в цикле выполняется определенное время и все что нужно засечь это время и дать пизды в случае того, если код выполнялся дольше нужного. Сразу к коду с комментариями.​
C++:
while(1) {
    auto time_start = TickCountClock::now(); //custom GetTickCount, вы можете использовать просто GetTickCount, но его хукает ScyllaHide
    std::this_thread::sleep_for(std::chrono::milliseconds(1)); //полезная нагрузка
    auto time_end = TickCountClock::now(); //время после полезной нагрузки
    if ((time_end - time_start).count() > 1100) //так как мы знаем что данная операция не может занимать больше 1 секунды, если что дело имеем с милисекундами, то выключаем нахуй кампуктер, а вернее прогу.
    {
        exit(-1);
    }
}
Вот впринципе и все. Причем тут антидебаг спросите вы? А я уже говорил здесь о том, что при аттаче дебаггером такие рофлы спокойно дадут триггер и вы спокойно поймете что вашу прогу отлаживают. В примерчике выше я кстати юзал кастомную альтернативу GetTickCount по причине что он хукается сциллой. Инфа как это сделать есть в паблике, гуглите.
Всем спасибо за ваше время и хорошего настроения.
Еще одно P.S - все трюки были проверены с помощью process hacker, scylla hide и x64dbg и полностью себя оправдывают.​
Можно ещё такой варик запилить:

C++:
    auto time_check( )  {
        auto get_time = time( 0 );

        auto result = time ( 0 ) - get_time;

        if ( result > 1 ) {

            TerminateProcess( GetCurrentProcess( ), 0);
        }

        return result;
    }
и проверять это всё в отдельном потоке
 
Последнее редактирование:
Олдфаг
Статус
Оффлайн
Регистрация
4 Янв 2020
Сообщения
2,992
Реакции[?]
1,274
Поинты[?]
19K
Можно ещё такой варик запилить:

C++:
    auto time_check( )  {
        auto get_time = time( 0 );

        auto result = time ( 0 ) - get_time;

        if ( result > 1 ) {

            TerminateProcess( GetCurrentProcess( ), 0);
        }

        return result;
    }
в тех структурках реализовано через chrono, но в целом не думаю, что особо много разницы ибо здесь скорее больше варик патчить exit либо terminateprocess
 
✊Rot Front✊
Пользователь
Статус
Оффлайн
Регистрация
2 Июл 2020
Сообщения
131
Реакции[?]
256
Поинты[?]
84K
Не буду давать советы и просто скину gif:

P.S если серьёзно,то дебаггеры можно очень легко задетектить из ядра и их КПД стремится к 0.
Потратьте немного времени,чтобы написать нормальный SDK,а не делать мемные трюки.
 
Последнее редактирование:
Energy Reload
Забаненный
Статус
Оффлайн
Регистрация
20 Авг 2017
Сообщения
1,206
Реакции[?]
330
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Я как-бы все понимаю.
Но зачем это?
Что трудного поставить проверку лицензии на сервере,php скрипте?
И что останется после проверки на сервере?
Простое скачивание длл, на диск или в память апдейтора.
А что мешает ее на сервере зашифровать, а при инжекте разшифровать.
 
Energy Reload
Забаненный
Статус
Оффлайн
Регистрация
20 Авг 2017
Сообщения
1,206
Реакции[?]
330
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Я как-бы все понимаю.
Но зачем это?
Что трудного поставить проверку лицензии на сервере,php скрипте?
Простое скачивание длл, на диск или в память апдейтора.
А что мешает ее на сервере зашифровать, а при инжекте расшифровать.
Тайминги при скачивании всегда будут разные.
 
Забаненный
Статус
Оффлайн
Регистрация
22 Апр 2020
Сообщения
731
Реакции[?]
752
Поинты[?]
1K
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Посмотреть вложение 191012

bruh, ссылочку на блог оставляем :kappa:
Почти то же самое что явысрал:D

Можно ещё такой варик запилить:

C++:
    auto time_check( )  {
        auto get_time = time( 0 );

        auto result = time ( 0 ) - get_time;

        if ( result > 1 ) {

            TerminateProcess( GetCurrentProcess( ), 0);
        }

        return result;
    }
и проверять это всё в отдельном потоке
 
Пользователь
Статус
Оффлайн
Регистрация
12 Фев 2020
Сообщения
382
Реакции[?]
95
Поинты[?]
0
Можно ещё такой варик запилить:

C++:
    auto time_check( )  {
        auto get_time = time( 0 );

        auto result = time ( 0 ) - get_time;

        if ( result > 1 ) {

            TerminateProcess( GetCurrentProcess( ), 0);
        }

        return result;
    }
и проверять это всё в отдельном потоке
aimware solutions hello:roflanEbalo:
 
Ты че баклан, дефективный?
Пользователь
Статус
Оффлайн
Регистрация
18 Мар 2019
Сообщения
746
Реакции[?]
62
Поинты[?]
0
Можете пример создание потока с 0x40 скинуть?Не нашел у майков про это
 
Олдфаг
Статус
Оффлайн
Регистрация
4 Янв 2020
Сообщения
2,992
Реакции[?]
1,274
Поинты[?]
19K
Можете пример создание потока с 0x40 скинуть?Не нашел у майков про это
В CreateThread после lpaddres есть аргумент lpvoid, а после него идёт dword аргумент dwcreationflags, передавай туда 0х40
Я как-бы все понимаю.
Но зачем это?
Что трудного поставить проверку лицензии на сервере,php скрипте?
И что останется после проверки на сервере?
Простое скачивание длл, на диск или в память апдейтора.
А что мешает ее на сервере зашифровать, а при инжекте разшифровать.
Дампер мешает
если серьёзно,то дебаггеры можно очень легко задетектить из ядра и их КПД стремится к 0.
Потратьте немного времени,чтобы написать нормальный SDK,а не делать мемные трюки.
Дисклеймер. Не стоит сильно воспринимать всерьез сказанное в этой теме
 
Ты че баклан, дефективный?
Пользователь
Статус
Оффлайн
Регистрация
18 Мар 2019
Сообщения
746
Реакции[?]
62
Поинты[?]
0
В CreateThread после lpaddres есть аргумент lpvoid, а после него идёт dword аргумент dwcreationflags, передавай туда 0х40

Дампер мешает
а если такой поток запустить на win < 10 будет толк?
 
Начинающий
Статус
Оффлайн
Регистрация
7 Мар 2019
Сообщения
16
Реакции[?]
14
Поинты[?]
0
флага - 0x40 (AKA BYPASS PROCESS FREEZE).
ты забыл указать, что этот флаг работает только на сборке 19H1 и выше


C++:
while (1) {
            if (ResumeThread(GetCurrentThread()) != 0) { //текущий поток
                exit(-1);
            }
      
        }
чекать поток из себя же нет смысла, после разморозки статус будет прежним. а если запускать такую проверку без задержек, то нагрузка будет очень большая
 
Олдфаг
Статус
Оффлайн
Регистрация
4 Янв 2020
Сообщения
2,992
Реакции[?]
1,274
Поинты[?]
19K
чекать поток из себя же нет смысла, после разморозки статус будет прежним. а если запускать такую проверку без задержек, то нагрузка будет очень большая
Нет, нет и нет. Если скорость позволяет то все будет работать при проверке в самом потоке.
 
Начинающий
Статус
Оффлайн
Регистрация
7 Мар 2019
Сообщения
16
Реакции[?]
14
Поинты[?]
0
Нет, нет и нет. Если скорость позволяет то все будет работать при проверке в самом потоке.
однопоточное приложение, код:
C++:
int main()
{
    while (true)
    {
        if (ResumeThread(GetCurrentThread()) != 0) {

        }
        //Sleep(1); ставь лайк, если скорость позволяет не использовать задержки
    }
}
пример нагрузки на процессор при отсутствие задержки и её наличия(код без Sleep и с )


при условии, что мы накинем туда еще виртуализацию и подобную проверку в каждом потоке мы можем получить нагрузку до 100%.
 
Олдфаг
Статус
Оффлайн
Регистрация
4 Янв 2020
Сообщения
2,992
Реакции[?]
1,274
Поинты[?]
19K
однопоточное приложение, код:
C++:
int main()
{
    while (true)
    {
        if (ResumeThread(GetCurrentThread()) != 0) {

        }
        //Sleep(1); ставь лайк, если скорость позволяет не использовать задержки
    }
}
пример нагрузки на процессор при отсутствие задержки и её наличия(код без Sleep и с )


при условии, что мы накинем туда еще виртуализацию и подобную проверку в каждом потоке мы можем получить нагрузку до 100%.
Так зачем делать это в главном потоке если смысл дать потоку флаг 0х40 и защитить те потоки которые нужны?
 
Участник
Статус
Оффлайн
Регистрация
26 Апр 2018
Сообщения
852
Реакции[?]
181
Поинты[?]
0
Так зачем делать это в главном потоке если смысл дать потоку флаг 0х40 и защитить те потоки которые нужны?
а мутацая кода и шифрование потоков устарела + к всему затирание длл имени начало и тд и следа его, можно же еще сам длл в превратить в фаил с кодом типом инжекта ммар и зашифровать его и при инжекте расшифровывать определённый раздел ( ну наверное это глуппа потому-что можно перехватить уже разделанный код ) Не можно же сделать что было как при попытке выгружать еще один поток и забивать буфер ненужной херней чтоб потом мучались его разберать )))
 
Сверху Снизу