Показать сообщение отдельно

Низкоуровневое исследование post 3 of 4
  #3  
Старый 14.08.2009, 17:06
Аватар для Dosia
Dosia
Участник форума
Регистрация: 05.06.2009
Сообщений: 127
Провел на форуме:
1313455

Репутация: 249
По умолчанию Низкоуровневое исследование post 3 of 4

e) Показ ping’a пользователей цифрами


Предполагается что “Garena.exe” уже загружена и запущена в вашем отладчике (мы юзаем олю), а также вы уже залогинились и готовы заходить в какую – нибудь свободную комнату (именно свободную или полупустую).
Переходим к окну отладчика, вызываем контекстное меню нажатие правой кнопки мыши на дизассемблированном коде. Выбираем опцию “Search for” -> “All referenced text strings”:

Оля нашла нам все строки которые встречаются в программе (незашифрованные). В появившемся окне перейдем к самой верхней строчке текста, это связано с тем, что наш отладчик ищет строки по порядку: сверху – вниз. Жмем правую кнопку мыши, снова вызывая контекстное меню, после чего выбираем опцию “Search for text”. В появившемся окне введем “|||” , что это? Именно так у обычных пользователей игровой платформы отображается пинг, то есть не цифрами, а вертикальными чертами (“|”,”||”,”|||”, и т.д.).


Жмем “OK”, после чего оказываемся тут:


Видим похожие строки, это явно то что мы искали. Кликнем два раза (ака дабл клик) на найденной нами строке и окажемся тут:


Как мы можем видеть мы находимся на адресе: 4C012B где содержится команда “PUSH 5B19D4” которая помещает в стек значение находящееся по адресу 5B19D4, оля заботливо показала нам подсказку, что это текст “|||”. Осмотрим саму функцию в которой мы находимся: по адресу: 4C00FA идет сравнение EAX, с 190h (CMP EAX,190) после чего идет команда условного перехода (JGE SHORT 004C0122) на следующее сравнение (CMP EAX,258), в случае если перехода не произошло устанавливается количество палок соответствующее данному пингу ( в данном случае две), после чего идет команда RETN – возврат, становится понятно, что в зависимости от пинга именно тут проставляется необходимое колиство палок, но мы то хотим цифры, не так ли?
Сделаем следующее: поставим брекйпоинт на начало данной функции: 4C0080 (щелкнем на строке находящейся по данному адресу, после чего жмем “F2”). Теперь заходим в комнату (выберите какую нибудь полупустую). Оп, окно отладчика всплывает, наша точка останова стработала.


См. также строку состояния:


Зачем мы тут остановились? чтобы вы могли самостоятельно потрассировать программу по “F8” до ближайшей команды “RETN 8”и посмотреть ход её выполнения.
Как только вы остановились на команде “RETN 8”, жмем однократно “F8” и оказываемся на адресе возврата: 004C0251:


Но самое интересное уже произошло выше:


Начнем изучение кода:
по адресу 4C024C мы имеем вызов процедуры которая установит пинг в виде вертикальных линий, следовательно, эта сточка, в ходе выполнения программы не должна быть выполнена. Смотрим выше в поисках переходов, позволяющих нам проскочить через “плохую” строчку. Имеем таковой по адресу: 4C023E, он переносит нас через вызов процедуры (по адресу 4C024C ) и последующий за ним безусловный переход (4C0251). Выше перехода (4C023C)видим сравнение “TEST BL,BL”. Тут надо сказать что опкод TEST Выполняет логическую операцию “И” над числами и по результату (не помещая его в получатель) устанавливает флаг Z. Если в BL будет 0, то переход “JNZ” не будет выполнен и мы будем видеть вертикальные линии вместо цифер. Также на скрине видно, что на это сравнение есть несколько условных переходов: “Jumps from 004C01F5, 004C0203, 004C0218, 004C0223”. С четырех адресов, найдем самый верхний по адресу: 4C01F5. Как я уже говорил в сравнении на которое мы можем попасть с этого условного перехода “JE SHORT 004C023C” проверяется значение регистра BL, значит оно где то устанавливается? Логично? Посмотрим чуть выше в поисках команды mov BL, (что нибудь) или вызова какой либо процедуры.
Чуть выше первого перехода на сравнение, на котором мы сейчас находимся (4C01F5) по адресу: 4C01E5 видим команду MOV BL,AL, а выше нее (4C01E0) вызов процедуры по находящейся по адресу 004D2710, кликнем левой кнопкой мыши по адресу 4C01E0, где находится вызов нашей процедуры, после чего нажмем “Enter” и мы окажемся в процедуре. Сразу надо сказать что в этой процедуре устанавливается значение регистра AL, так как мы уже рассмотрели что после вызова данной процедуры находится команда MOV BL,AL , которая копирует содержимое регистра AL в регистр BL. А так же нам следует помнить что необходимо чтобы AL не был равен нулю, иначе на сравнении мы не перейдем по условному переходу. Ставим точку останова на начало данной процедуры (4D2710), после переходим к окну Garena и входим в комнату, останавливаемся на брейпоинте:


Тут следует сказать почему мы немного углубились в изучение кода, а не пошли по более легкому пути и просто напросто исправили переход по адресу: 4C023E с условного JNZ SHORT 004C0256 на безусловный JMP SHORT 004C0256, что также решило бы проблему отображения цифрового пинга, как видно на скрине выше, эта процедура вызывается не с 1 фиксированного адреса, а с разных адресов, следовательно более правильно будет исправить именно значение возвращаемое этой функцией, нежели просто исправить переход. Это как функция проверки регистрация программы, в которой она проверяет зарегистрированная ли это версия и возвращает соответствующий результат, так вот, это функция может быть вызвана из разных мест программы, для того чтобы программа знала следует ли вводить ограничение на что – либо. И гораздо удобнее будет исправить значение возвращаемое этой функцией, нежели править все возможные переходы, проверяющие результат возвращенный функцией.
Мы на брейкпоинте (4D2710), трассируем программу по “F8”, пока не найдем нечто похожее на MOV AL, (что - либо). Находим нечто похожее:


Видим что по этому адресу (4D27F7) в регистр AL заносится значение находящееся по адресу EDX+44, оля любезно сообщила нам, что этот адрес 0100AE94, а значение находящееся по нему равно 0 (DS:[0100AE94]=00), также видим что текущее значение AL = B0.


Жмем “F8”.


AL = 0 – пинг вертикальными чертами. Изучаем оставшийся код до команды “RENT 4”, больше нигде AL не устанавливается, значит мы на верном пути. Жмем на адрес 4D27F7 – команду “MOV AL,BYTE PTR DS:[EDX+44]" заменим на команду “MOV AL,1” (кликаем на строку, жмем “space bar”,вводим команду “MOV AL,1”, жмем “assemble”), этим мы заставим программу думать что мы привилегированные пользователи.

Как сохранить внесенные в код изменения смотреть в конце статьи.

f) Уберем проверку на использование запрещенных программ

Переходим к окну отладчика, вызываем контекстное меню нажатие правой кнопки мыши на дизассемблированном коде. Выбираем опцию “Search for” -> “All referenced text strings”. В появившемся окне перейдем к самой верхней строчке текста, это связано с тем, что наш отладчик ищет строки по порядку: сверху – вниз. Жмем правую кнопку мыши, снова вызывая контекстное меню, после чего выбираем опцию “Search for text”. В появившемся окне введем “Path:%s” , что это? это путь к запрещенной программе, которую Garena передает на сервер, вместе с ip и логином заблокированного пользователя. Жмем “OK”, совпадение найдено, двойной щелчок на найденной строке и мы тут:


Осмотрев код сразу становится понятно, что мы зашли по адресу. Чуть ниже можно заметить вызов функции “PostMessage”, оля даже смогла определить что параметром “Message” для нее будет “WM_QUIT”, что означает закрытие окна после уличения пользователя в использовании запрещенных программ.
function PostMessage(Wnd: HWnd; Msg, wParam: Word; lParam: Longint): Bool;
Напpавляет сообщение окну пpикладной задачи.

Прокрутив листинг чуть выше можно заметить вызов следующих функций:
GetWindowText, GetWindowThreadProcessId ,FindWindow полезным будет прочитать API help по ним, вызвав справку(как это сделать вы уже знаете). Позвольте вам разъяснить как идет проверка на наличие запрещенных программ:
с помощью функции FindWindow идет поиск окон с заданными заголовками (аля maphack …), если таковое окно найдено, то все выше упомянутые (и некоторые другие, смотрите сами) функции будут выполнены с целью получения пути к исполняемому файлу запрещенной программы. И все это происходит в найденной нами процедуре.
Найдем начало процедуры, прокрутив листинг чуть выше. Адрес 4DBF40 является началом процедуры, кликаем левой кнопкой мыши на строке и видим что оля знает откуда происходит вызов:


Жмем правой кнопкой мыши на подсказке оли и выбираем команду “Go to CALL from 004DC1B5”. Оказываемся тут (004DC1B5):


Выше видим условие(004DC1A4) и условный переход (004DC1A8), условный переход переносит нас через вызов процедуры поиска запрещенных программ, он же является условием выхода из цикла, начинающегося с адреса (004DC1A4) и заканчивающегося (004DC1CF), где стоит безусловный переход на проверку условия. Я думаю что здесь все понятно и наша задача сводится к тому, чтобы код начинающийся с адреса (004DC1B5) никогда не выполнялся. Для этого меняем условный переход по адресу (004DC1A8) “JNZ 004DC2F6” на безусловный “JMP 004DC2F6”.
Как сохранить внесенные в код изменения смотреть в конце статьи.

Последний раз редактировалось Dosia; 19.09.2009 в 23:36..
 
Ответить с цитированием