PWI / Rus / Indo удаление красного спама, поиск оффсетов, инжект патча в ОЗУ
Сокращённый перевод , оригинал [Ссылки могут видеть только зарегистрированные пользователи. ]
Краткое описание
В программу заложена возможность выбора окна клиента по имени .персонажа.
Возможность установки патча в процесс запущенный в ОЗУ.
Возможность управлять фильтрами чата через интерфейс программы, настройки при этом сохраняются после релога и использования внутриигровой панэли настроек.
Автоматический поиск нужных оффсетов в запущеном процессе.
Инструкция к программе, и исходные материалы - тут.
Интерфейс программы -
[Ссылки могут видеть только зарегистрированные пользователи. ]
Итак, для начала необходимо определить, что именно изменяется (адреса в ОЗУ ) в момент использования внутриигровой панели настроек.
Запускаем Cheat Engine , прикрепляем к процессу клиента.
На внутриигровой панели настроек имеются 6 каналов чата ( Основной, Группа, Клан .... ) и 11 опций фильтра (Общий, Группа, Обьявления ... )
Напрашивается вывод о том что в памяти должна присутствовать область, сохраняющая 66 значений настроек фильтров. Так же , легко предположить что в целях экономии ресурсов ОЗУ , настройки сохраняются в виде отдельных байтов, при этом 1- означает что фильтр включен, 0 - выключен.
После прикрепления СЕ к клиенту , открываем внутриигровую панель настроек, выбираем Основной чат , ставим галочку в Общее. В СЕ запускаем поиск байтов со значением 1 .
[Ссылки могут видеть только зарегистрированные пользователи. ]
В результате получаем несколько миллионов адресов. Если бы мы начали поиск со значения 0, адресов было бы найдено существенно больше. По этому мы начинаем поиск со значения , отличного от 0.
Далее выключаем фильтр основного чата в игре, изменяем параметр поиска в СЕ на 0, нажимаем Next Scan. Колличество найденных адрессов сократится до несколльких тысяч. Ничего не меняя в настройках клиента и СЕ продолжаем нажимать Next Scan еще несколько раз. Колличество адрессов будет резко сокращаться с каждым сканированием.
Заново включаем фильтр, и записываем 1 в строку поиска СЕ, сканируем. Продолжаем менять значения и сканировать до тех пор пока в окне поиска не останется 2 - 3 адресса.
Для просмотра памяти выбираем адресс ПКМ, в открывшемся меню выбираем browse memory region.
Адресс который нам нужен будет иметь вид - 100100011000101 ...
Теперь изменяя значения байтов, мы можем изменять настройки фильтров в клиенте, однако следует заметить что порядок настроек в фильтре и в ОЗУ могут отличаться.
[Ссылки могут видеть только зарегистрированные пользователи. ]
порядок фильтров в памяти ( для ПВИ ) следующий -
Код:
мessageTypes (see chatObj->msgScope)
Local // 0
World // 1
Squad // 2
Faction // 3
Whisper // 4
5 // 5
6 // 6
Trade // 7
Notification // 8
System // 9
Gen. Info // 0xa
Local info(b) // 0xb
Local info(c) // 0xc
Видно, что фильтров на самом деле не 11 а 14, при чем 3 последних - скрыты, в скрытых фильтрах и сохранены настройки для горнов и красного чата.
Итак, мы имеем 13*6 = 78 фильтров. Их оффсеты для каждой области чата (ПВИ ) следующие -
Код:
Common -> Normal = 0
Squad -> Normal = 0xD
Faction -> Normal = 0x1A
Whisper -> Normal = 0x27
Trade -> Normal = 0x34
General -> Normal = 0x41
Теперь когда обнаружены адреса фильтров в ОЗУ , проведем эксперимент. В окне СЕ browse memory region изменим значнеие байта отвечающего за известный нам первый фильтр - Основной - Общий. при этом галочка в окне внутриигровой панели не отреагирует на изменение.
Однако, если мы переключим область чата, например на группу и вернёмся в Основной, мы увидим что галочка появилась (если в СЕ 0 заменён на 1 ) или ищезла. Теперь если нажать Применить , белый чат появится/ пропадёт в основном канале. Попробуем найти ячейку для красного или желтого чата, и проделать то же самое . Чат пропадёт, при записи 0 в ячейку, но если закрыть и заново открыть панель настроек в игре, и галочка и чат вернутся на своё место.
Это наводит на мысль о том, что настройки фильтров храняяся еще гдето.
Есть несколько способов найти у область в памяти.
Первый - искать адресс с набором ячеек , значения в которых бы совпадали с прежде найденным адрессом. (Ищем после нажатия применить в панели игры )
Либо найти фрагмент кода, который из вне транслирует информацию по найденому нами адресу . Этот способ и рассмотрим.
Можно воспользоватся встроенным дебагером СЕ, но лучше выбрать инструмент более проффесиональный - OllyDbg
Запускаем OllyDbg , прикрепляем к клиенту ( СЕ если был прикреплён, отсоединяем ) Как только дебагер сообщает о соеденении с процессом нажимаем F9 - разблокируем клиент.
В списке "Executable modules" (Alt+E) двойным ЛКМ выбираем "ElementClient" 2 раза. Далее обращаемся к таблице memory dump area и вызываем функцию перехода по заданному адресу Ctrl+G (Goto address) , вводим адрес найденый с помощю СЕ, выбираем ячейку сохраняющую настройку фильтра Основной - Общий. ПКМ по ячейке, в меню выбираем set a memory breakpoint on write access (брек пойнт при записи памяти )
[Ссылки могут видеть только зарегистрированные пользователи. ]
Примечание - в зависимости от версии дебагера интерфейс и меню могут отличаться.
В игре открываем настройки, окно игры будет заморожено, активируется окно дебагера, который покажет нам следующий фрагмент кода
Снова открываем настройки в игре. В EAX запишется значение baseCall static offset ( &baseCall = 0xAFF144, *baseCall = AFF7E8) (ПВИ)
Из написанного выше также видно что данный фрагмент программы копирует значения из динамической области хранения настроек чата в постоянную область хранения.
А так же легко вычислить оффсет для постоянной области , он будет равен
Код:
[[[baseCall]+0x18]+0x155]
Добавим найденные ранее значения в таблицу оффсетов СЕ как показано на иллюстрации (Выбераем тип 'Array of bytes' , длинна 78) -
[Ссылки могут видеть только зарегистрированные пользователи. ]
также добавим Array of bytes для адресса найденного ранее . теперь мы можем сравнить содержимое по этим адресам памяти визуально.
[Ссылки могут видеть только зарегистрированные пользователи. ]
Бросается в глаза смещение на 4 байта . Эти 4 байта использубтся для настроек Отказа от группы и торговли , A.D. инверсии осей мышки.
Таким образом , необходимо прибавить 4 к найденному выше оффсету, и окончательный вид оффсетов для чата -
Код:
[[[baseCall]+0x18]+0x159]
теперь после настройки фильтров и нажатия применить обе строки должны совпадать
Мы нашли где настройки сохраняются постоянно, временно, а так же то, что красный чат и горны включаются откудато из вне, принудительно после выключения в памяти .
Мы знаем что желтый чат так же принудительно включается в основном канале . В OllyDBG ставим брекпойнт на запись в регистр желтого чата.
Итак , адрес наш адрес -адрес base динамических фильтров + 1, ( адрес динамических фильтров ПВИ [[[[[baseCall]+0x18]+0x8]+0x4B0]+0x218]).
Ставим брекпойнт на 1 байт выше этого адреса ( для желтого чата) .
В игре открываем настройки, дебагер покажет прежний адрес, жмём F9 , и останавливаемся на строке
Что происходит -
при открытии панели настроек
1 настройки из статических фильтров копируются в динамические фильтры
2 некоторые динамические фильтры включаются принудительно ( красный и желтый чат ,шепот, рупоры )
3 настройки из динамических фильтров возвращаются в статические фильтры , и открывается сам интерфейс панели настроек.
Итак, для постоянного отключения красного и других принудительно включаемых фильтров , необходимо сначала устранить момент их включения, затем обнулить настройки по адресам их хранения.
Рассмотрим далее найденный нами участок программного кода
Код:
00569186 |. 8895 19020000 MOV BYTE PTR SS:[EBP+219],DL ; Common -> World On
0056918C |. 889D 5A020000 MOV BYTE PTR SS:[EBP+25A],BL ; General -> World off
00569192 |. 889D 62020000 MOV BYTE PTR SS:[EBP+262],BL ; General -> System off (red)
00569198 |. 889D 5D020000 MOV BYTE PTR SS:[EBP+25D],BL ; General -> Whisper off
0056919E |. 889D 65020000 MOV BYTE PTR SS:[EBP+265],BL ; General -> Horn? off
Всё это касается только Основного чата. Далее при рассмотрении кода находим обьяснение
Фрагмент кода обращается (посредством ADD EAX, 0D) ко всем областям чата и устанавливает некоторые фильтры .
Как мы помним щффсет динамических фильтров [[[[[baseCall]+0x18]+0x8]+0x4B0]+0x218] , однако на несколько строк выше мы видим
Код:
00569167 |. 8D85 1C020000 LEA EAX,[EBP+21C]
начинаем с 5 го фильтра в Общем чате (шёпот ) видим что фрагмент кода включает фильтры в последовательности
Единственный способ прервать принудительное включение фильтров красного , желтого , и канала горна - с помощью патча устранить фрагменты кода ответственные за принудительное включение фильтров в клиенте , либо в файле на диске , либо процессе клиента в ОЗУ .
Автор программы выбрал второй вариант , рассмотрим его
программа сканирует запущенный процесс клиента в ОЗУ, и отыскивает строки -
В продолжении - оригинальная реализация функции Применить настройки из интерфейса программы .
По материалам [Ссылки могут видеть только зарегистрированные пользователи. ]
Итак, с хранением и изменением настроек фильтра вопрос решен, однако для того чтобы настройки вступили в действие , их необходимо активировать в запущенном приложении.
Грубо говоря - нажать кнопку применить во внутригровой панели. Попробуем вынести эту функцию в интерфейс нашей программы.
Клиент ПВ построен так , что найти что либо связанное с функцией Применения настроек - не просто, по этому автор программы пошел другим путём. Бобавленно несколько инжектов которые связывают
нажатия кнопок в программе , с внутриигровой панелью.
По причине того, что как сказанно выше , настройки копируются из статической области хранения в динамическую ( GUI игры ) , затем обратно, был разработан следующий алгоритм для активации изменений настроек -
1 Закрыть внутриигровую панель если она открыта.
2 Записать настройки в постоянную область хранения
3 ОВызвать функцию ткрытия интерфейса настроек в игре , и открыть внутриигровую панель настроек
4 Вызвать функцию эмулирующую нажатие Применить во внутриигровом интерфейсе
5 Закрыть внутриигровой интерфейс
В Оlly - в окне с кодом выбираем любую строку, ЛКМ, в мею выбираем 'Search for' -> 'All referenced strings'
Должно появится окошко, со списком всех констант используемых в приложении. ПКМ , в этом окне, и в меню выбираем 'Search for text' (Ctrl+F) . Ищем "Dlg_Building" , эта строка должна быть 1 , и место нахождения её должно быть единственным. 2 раза щёлкаем по ней ЛКМ, и дебагер показывает нам фрагмент кода связанного со строкой. На этом этапе можно открыть IDA disassembler , ввести найденный только что адрес начала функции. Код в этом месте достаточно запутан, придется отмотать несколько страниц его вверх, пока не пойдет последовательность NOP ов. Начало функции - первая строка после NOP ов. В текущей версии ПВИ , она находится по адресу 0x604B30 , а код выглядит так -
2 и 4 инструкции сдесть загружают внутриигровой интерфейс, и указатель gui object соответственно. Ставим брекпойнт на 5 строку (PUSH EDI ), на внутриигровом интерфейсе нажимаем кнопку Применить.
Когда брекпойнт сработает, мы увидим значение в ESI, которое будет объектом gui и ссылкой последовательности в EBX, которая будет командой. Команда для кнопки применять - просто текстовая строка, "apply".
Если Вы cделаете это несколько раз для некоторых других элементов, то есть, откроете интерфейс параметров настройки игры или закроете его (X) , Вы получите командные строки для них также. Они - "gamesetting" и "Btn_Close" соответственно.
Обратите внимание на значение ESI, когда Вы входите в эту функцию после нажатия кнопки применять, в панели настроек игры.
Оффсет для внутриигровой панели настроек имеет вид
Код:
[[[[[baseCall]+0x1C]+0x18]+0x8]+0x4B0]
Команды управления панелью игровых настроек мы будем посылать сюда.
Восновном это будет псевдо код того, что мы хотим сделать .
Наша функция guiCommand() будет выглядеть примерно так
If gameSettingsTab is open
{
guiCommand("Btn_Close", gamesettingTabObject) // close the tab
Wait until it's closed
}
setChatFilters() // Write our preferred filters to the static filter array
guiCommand("gamesetting", gamesettingTabObject) // Open the tab again
guiCommand("apply", gamesettingTabObject) // Hit apply
guiCommand("Btn_Close", gamesettingTabObject) // close the tab again
файл PW_ChatFilter.au3 содержит инжект нашей функции управления в приложение, там с ним и можно ознакомится .
ENDS.
Сокращённый ручной перевод выполнен по поросбе Nitrogen
________________
Не люблю давать глупые ответы ) По этому глупые вопросы - в игноре
Последний раз редактировалось t212; 20.11.2011 в 01:11.