Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Опустим пояснения за шмот (что это, зачем и нахуя ты это выложил) и перейдём сразу к делу.
Коротко о том как сейчас работает последняя версия анти-стиллера.
> 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
Залетаем внутрь тела хука и наблюдаем такую картину, по скольку анти-стиллер позволяет вызывать Nt/ZwWriteVirtualMemory для собственного процесса, ебашим у себя вызов, ставим железный бряк и трассируем, проделав тоже самое с хендлом к левому процессу можно увидеть что решающий момент определяет вот этот условный переход который и является фильтром вызова после которого нас перекидает в место откуда передаются параметры функции и осуществляется переход на трамплин.
Но как же нам его пропатчить если в предыдущем месте у нас не было прав на запись?
Переходим к карте памяти и смотрим какие права у нас есть на само тело хука
Благодаря тому что автор забыл забирать права на запись внутри самого хука - его можно патчить.
Накидаем простенькую функцию патчущую нужную нам функцию. Но стоит помнить что это нам поможет только в том случае если у функции есть трамплин.
Отлично! Теперь можно пропатчить все необходимые нам NT функции из цепочки необходимой для DLL инжекта. А уже когда наша длл попадёт в сторонний процесс - мы можем с неё творить всё что душе влезит :)
Проблему с поиском ида нужного нам процесса решим следующим образом, анти-стиллер патчит перебор процессов но не патчит перебор потоков внутри структуры которых можно узнать ид процесса к которому он пренадлежит и через OpenProcess + GetModuleInformationEx узнать его имя что даст нам возможность найти нужный ид процесса.
Гайд by ЯedЯuM специально для портала blast.hk
Коротко о том как сейчас работает последняя версия анти-стиллера.
> 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
Залетаем внутрь тела хука и наблюдаем такую картину, по скольку анти-стиллер позволяет вызывать Nt/ZwWriteVirtualMemory для собственного процесса, ебашим у себя вызов, ставим железный бряк и трассируем, проделав тоже самое с хендлом к левому процессу можно увидеть что решающий момент определяет вот этот условный переход который и является фильтром вызова после которого нас перекидает в место откуда передаются параметры функции и осуществляется переход на трамплин.
Но как же нам его пропатчить если в предыдущем месте у нас не было прав на запись?
Переходим к карте памяти и смотрим какие права у нас есть на само тело хука
Благодаря тому что автор забыл забирать права на запись внутри самого хука - его можно патчить.
Накидаем простенькую функцию патчущую нужную нам функцию. Но стоит помнить что это нам поможет только в том случае если у функции есть трамплин.
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; // патчим её на короткий безусловный прыжок
}
Проблему с поиском ида нужного нам процесса решим следующим образом, анти-стиллер патчит перебор процессов но не патчит перебор потоков внутри структуры которых можно узнать ид процесса к которому он пренадлежит и через 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
Последнее редактирование: