Исходник Гайд [C++] Обходим Анти-стиллер by DarkP1xel v5.1.0

ЯedЯuM

Malware Maker
Автор темы
242
302
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Опустим пояснения за шмот (что это, зачем и нахуя ты это выложил) и перейдём сразу к делу.
Коротко о том как сейчас работает последняя версия анти-стиллера.

> WIN API хуки на интернет функции и тд. (После обновления их число несколько уменьшилось в целях оптимизации, часть хуков на опасные функции были перенесено в ntdll.dll (NT API)
> NATIVE API хуки (запись в память стороннего процесса, выделение и смена прав памяти в процессах, создание своего процесса, создание удалённых потоков, Windows хуки, переборы списков запущенных процессов а так же поиски окон.

В кратце сейчас анти-стиллер делает всё чтобы не позволить даже такие обходы как инжект дллки в левый процесс а так же создание своего собственного каким либо образом.
Даже попытки получить адрес какой либо интересующей функции NT/WIN API через GetProcAddress либо непосредственно через свой кастомный парсер Export TABLE обречены на провал поскольку анти-стиллер хукает таблицу экспорта в загруженных системных модулях. При попытке достать какой либо адрес на захуканую им функцию вы получите не её реальный адрес а сразу же адрес хука анти-стиллера(Здесь сразу же отсев долбоёбов, весьма умно).
Так же в нём весьма распространено перекрёстное перехвачиванние внутренних функций из реализации какой либо WIN/NT API функции чтобы наверняка не помог даже перепрыг хука.
Его самозащита организована следующим образом - отнимаются права памяти на перехваченную функцию благодаря чему нельзя удалить хук, но как же VirtualProtect? Опять таки не всё так просто, он тоже не имеет в себе прав на запись в память и сам же захукан чтобы им нельзя было менять атрибуты памяти там где не нужно.

Так какие варианты у нас есть?
> Эмуляция прямого системного вызова на Native API функции (Но это чревато проблемами с разными номерами сервисов от версии и даже от её номера текущего билда а так же различной архитектурой на x32-x64 системах)
> Эмуляция пролога системного вызова (первых 5 байт) с последующим переходом в оригинал но на 5 байт дальше (перепрыгивание хука) - разумеется что данный способ лучше за предыдущий но всё равно требует чтения номера сервиса в функциях которые находятся в коде выше/ниже текущего тела функции но в отличии от способа выше нам не нужно эмулировать остальные инструкции, достаточно лишь узнать номер сервиса. Но всё равно такой способ часто конфликтует, по непонятным мне причинам с некоторым перечнем .asi плагинов. Да и на разных ОС - порядок расположения функций может отличатся а некоторых и во все может не быть.
> Manual Mapping дубликатной системной библиотеки, например ntdll.dll но не уверен что она будет корректно работать под хуками анти-стиллера по скольку все её функции имеют тот же RVA что и в оригинале и внутренние функции из реализации экспортированного интерфейса могут вызывать не свои а "оригинальные". Вообщем у меня хватает сомнений касательно этого способа.
> Инжект своей DLL в сторонний процесс (например samp.exe который почти всегда запущен вместе с игрой до конца её сеанса), сама процедура инжекта будет производится посредством Native API.
(NtOpenProcess + NtAllocateVirtualMemory + NtWriteVirtualMemory + NtCreateThreadEx) но опять таки требует другого способа получения ида интересующегося процесса.

Каким путём пойдём мы?

Лично я выбрал последний способ потому что он самый простой и удобный в реализации а главное стабильный на различных версиях ОС. Я решил его несколько модифицировать чтобы у нас была возможность использовать весь тот перечисленный функционал не смотря на хуки анти-стиллера.

Открываем отладчик, зайдём внутрь тела хука и посмотрим что же там происходит и каким образом происходит отсев исключений для разрешенных вызовов.
В качестве примера выступит ZwWriteVirtualMemory
Безымянный.png

Залетаем внутрь тела хука и наблюдаем такую картину, по скольку анти-стиллер позволяет вызывать Nt/ZwWriteVirtualMemory для собственного процесса, ебашим у себя вызов, ставим железный бряк и трассируем, проделав тоже самое с хендлом к левому процессу можно увидеть что решающий момент определяет вот этот условный переход который и является фильтром вызова после которого нас перекидает в место откуда передаются параметры функции и осуществляется переход на трамплин.
Безымянный.png

Но как же нам его пропатчить если в предыдущем месте у нас не было прав на запись?
Переходим к карте памяти и смотрим какие права у нас есть на само тело хука
Безымянный.png

Благодаря тому что автор забыл забирать права на запись внутри самого хука - его можно патчить.
Накидаем простенькую функцию патчущую нужную нам функцию. Но стоит помнить что это нам поможет только в том случае если у функции есть трамплин.
C++:
void PatchAS(const char *libname, const char* funcName)
{
    DWORD JE_Offset = (DWORD)GetProcAddress(GetModuleHandleA(libname), funcName); // Поскольку // гетпрокадрес захукан - он вернёт нам сразу же базовый адрес хука который нам и нужен.
    while (*(byte*)JE_Offset != 0x74) JE_Offset++; // ищем первую встречную JE инструкцию
    *(byte*)JE_Offset = 0xEB; // патчим её на короткий безусловный прыжок
}
Отлично! Теперь можно пропатчить все необходимые нам NT функции из цепочки необходимой для DLL инжекта. А уже когда наша длл попадёт в сторонний процесс - мы можем с неё творить всё что душе влезит :)
Проблему с поиском ида нужного нам процесса решим следующим образом, анти-стиллер патчит перебор процессов но не патчит перебор потоков внутри структуры которых можно узнать ид процесса к которому он пренадлежит и через OpenProcess + GetModuleInformationEx узнать его имя что даст нам возможность найти нужный ид процесса.
C++:
DWORD GetProcID(const char* ProcName)
{
    THREADENTRY32 th32;
    HANDLE hSnapshot = NULL;
    th32.dwSize = sizeof(THREADENTRY32);
    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    if (Thread32First(hSnapshot, &th32))
    {
        do
        {
            if (th32.th32OwnerProcessID == GetCurrentProcessId()) continue;
            HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, th32.th32OwnerProcessID);
            if (!hProc) continue;
            if (!strcmp(GetProcName(hProc).c_str(), ProcName))
            {
                CloseHandle(hProc);
                CloseHandle(hSnapshot);
                return th32.th32OwnerProcessID;
            }
            else CloseHandle(hProc);
        }
        while (Thread32Next(hSnapshot, &th32));
    }
    if (hSnapshot != INVALID_HANDLE_VALUE) CloseHandle(hSnapshot);
    return -1;
}

Гайд by ЯedЯuM специально для портала blast.hk
 
Последнее редактирование:

ЯedЯuM

Malware Maker
Автор темы
242
302
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.

ЯedЯuM

Malware Maker
Автор темы
242
302
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.

ЯedЯuM

Malware Maker
Автор темы
242
302
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.

ЯedЯuM

Malware Maker
Автор темы
242
302
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Опкодер, на путь исправления встал, или что?
Не буду лгать, у меня свой мотив но он не идёт в разрез разработчику анти-стиллера, в какой то степени ему это тоже выгодно - лишний повод людям задонатить на обновления.
 
  • Нравится
Реакции: SiTrak

ЯedЯuM

Malware Maker
Автор темы
242
302
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Лучший обход антистиллера — загрузиться раньше него и удалить его самого
:-|
Интересно как же ты впаришь на аудиторию файл с нужным именем так чтобы его ещё не переименовали после скачивания.
 
  • Нравится
Реакции: DarkP1xel и imring