Вот собственно решил написать небольшое размышление на тему БОТов.
Небольшое отступление.
Недавно как вы знаете была волна банов, и около 500к пользователей "посадили парится в баню" (на 72 часа | пожизненно) за использование ботов которые автоматизируют боевую ротацию.
Среди них был и я (автор этой темы).
В этой теме я хотел бы порассуждать о том как "поймали" и как по возможности "избежать поимки".
И так, я не использовал бота которым пользовались все, я использовал своего бота (он был написан на подобии PQR, точнее использовал от туда механизм выполнения Lua кода).
Теперь немного анализа о том, как же могли отследить.
1) Для запуска Lua кода в клиенте использовалась функция
FrameScript__ExequteBuffer, то есть сначала в код клиента записывался код, который будет вызывать эту функцию, а потом вызывался этот код.
2) В самом коде Lua (который инжектили в процесс) есть protected функции (CastSpellByName, SpellStopCasting, и т.п.), возможно отследили именно вызов этих функций.
3) AFK режим, у меня был встроен antiAFK - случайным образом посылались нажатия клавиш раз в 2-5 минут. Я очень часто делал так, "цеплял" своего персонажа и уходил по своим делам и получалось что-то на подобии такого:
в связи с этим думаю отслеживали активность персонажа и так звание значение
LastHardwareActionTime, то есть время последнего действия от устройства ввода.
4) ХЗ (Хрен его знает).
И так в связи с этим я начал переделывать бота:
1) Оформил в виде аддона (естественно сам он работать не будет, так как вызов защищенных функций не пройдет проверку в функции
CGGameUI__CanPerformAction.
2) Переписал сам аддон, таким образом, чтобы было больше рандома во времени срабатывания абилок + добавил фейк касты (например заклинание находится на восстановлении, а я его кастую, при этом эмулирую действия пользователя "жмяканье по кнопкам")
3) Для того чтобы не писать больше ничего в память я прицепил отладчик, и с помощью него меняю значение регистра для валидации условия.
это выглядит так:
Код:
008C7657 39 0D E8 6A BB 00 cmp dword_BB6AE8, ecx
сюда я поставил точку останова:
Код:
GetThreadContext(thHandle, &thread_context);
thread_context.Dr0 = hoockAddress;
thread_context.Dr7 = 1;
SetThreadContext(thHandle, &thread_context);
и потом при срабатывании точки, менял значение регистра на нужно мне значение (что-то с флагом не получилось):
Код:
GetThreadContext(thHandle, &thread_context);
thread_context.Ecx = blizzVal;
SetThreadContext(thHandle, &thread_context);
Как водится хукнул функцию
IsDebuggerPresent, чтобы не спалился отладчик.
Пока что это работает на трильном акке, но вот использовать на основном аккаунте пока что стремно.
Если у кого-то есть какие-то идеи/предположения по поводу того как "спалили" и как "защитится", прошу делится мыслями.