Доброго всем времени суток! Наша жертва - Garena Client ([Ссылки могут видеть только зарегистрированные пользователи. ]) - это клиент игровой сетевой платформы, позволяющая играть в различные игры по интернету без лагов. Вообще вещь достаточно популярная, поэтому она и вызвала у меня особый интерес для реверса. Чтобы поиграть, нужно сначала зайти в комнату, но первые комнаты вечно забиты и прорваться туда очень сложно (но нужно, ибо именно там лучшие соперники). После попытки зайти в комнату и сообщении о том, что данная рума переполнена, нам нельзя пытаться зайти в неё снова ещё 5 секунд, что существенно снижает процент захода. Для меня стало целью убрать это ограничение дабы повысить процент захода в топовые румы (не себе, конечно, сам то я не гамаю =)
На портале и вообще в крэкинге я только "чайник продвинутый", хехе, а посему буду рад выслушать любую критику.
Ну чтож, начнем-с!
Часть 1 - Поиск и удаление "таймера"
Запустив Garena.exe в пропатченной и "проплагиненной" Ольке (по урокам Рикардо Нарвахи) у меня почему то не запускается Garena - виснет на загрузке Chenyx.dll из папки pluginsUI. Кто может объяснить или высказать свои мнения по этому поводу, пожалуста пишите.
Поэтому я поставил чистую Ольку, на которой все прекрасно грузится =). Итак, после повторного входа в комнату, появляется окошко с надписью "Sorry, you can only try join a room every 5 seconds". Можно попробовать поставить бряки на MessageBox, но это не поможет: 1). Это не "великое сообщение" =) 2). видимо, гарена ставит VirtualProtect, поэтому ставить обычные бряки не получится, ну и пусть, воспользуемся аппаратными.
Лично я нашёл такой способ: до начала появления первого пятисекундного предупреждения, ищем в памяти юникод-строку, она находится в секции .rsrc модуля Garena.
Далее ставим на неё Hardware Breakpoint on access на первый байт и пытаемся повторно зайти в комнату, останавливаемся тут:
Мы находимся в модуле Language - чисто по названию можно предположить, что это модуль "общение с юзером", или что то в этом роде, но врядли тут окажется проверка на конец таймера. Кстати, таймер организован не через функцию вроде SetTimer, а других я пока не знал =) Так же и не дал каких то результатов и поиск в коде "PUSH 1388" (5000 в dec).
Так как мы предположили, что этот модуль нам не нужен, идем дальше до "RETN 8" (если идти по F7F8 то прога опять у меня виснет, так что я поставил hr на эту инструкцию). После выхода из Language, оказываемся тут:
Ок, теперь мы в основном модуле, его мы и будем копать. Мы находимся в функции, о чем свидетельствует жирная дуга слева от опкода. Видим, что кроме CALL'a, из которого мы вышли, в этой функции больше ничего сверху нету (код выполняется линейно), а поэтому поставим hr на на PUSH -1 и посмотрим в стеке, откуда вызывается сиё чудо (не забывайте удалять ненужные hr бряки, ибо их всего четыре) :
Пытаемся зайти в руму, отладчик незамедлительно всплывает, а esp указывает на адрес возврата:
Код:
0012E358 00499227 RETURN to Garena.00499227 from Garena.004E0B30
Запоминаем его, теперь надо выполнить следующую вещь: пытаемся зайти в комнату, и когда всплывает отладчик быстро жмем F9 и снова заходим в руму, тем самым спровоцировав появление окошка. Отладчик всплывает и в этом случае, но сейчас адрес возврата уже другой:
Код:
0012D91C 00540954 RETURN to Garena.00540954 from Garena.004E0B30
Так так,немного поразмыслив, можно предположить, что есть некая функция и в зависимости от каких то действий происходит её вызов с различными параметрами (так как функция вызывается в обоих случаях).
Дальше всё очевидно: ставим курсор на esp (строка выше) и давим на Enter, оказываемся тут (попадаем в место вызова процедуры с плохими параметрами):
Ок, кажется, мы нашли то, что нужно: вызывается функция GetTickCount, затем высчитывается какая то разность и сравнивается с ... 1388!!! (для тех, что не помнит, это 5000 в dec). И как я мог забыть поискать кроме пуша ещё и сравнение
По адресу 0054093E находится переход, который ведет на 005409A0, в Ольке очень хорошо видно, что этот переход как раз и пропускает вызов функции с "плохими параметрами" =).
Пробуем, ставим hr бряк по адресу 0054093E, ломимся в комнату, отладчик всплывает и сейчас всё TRUE (мы пролетаем через функцию). Теперь быстренько (надо успеть за пять секунд) жмакаем F9 и опять ломимся -> отладчик всплывает, но теперь уже не True, меняем флаг C и, отпустив прогу на волю, видим, что мы пытаемся зайти второй раз!! Ура товарищи, у нас всё получилось!!!
Если вы подумали, что это всё, то ошиблись, хехе.
Давайте сделаем патч: очевидно надо заменить JNB переход на JMP, но когда прога уже загружена, сделать это не удастся, поэтому запоминаем адрес перехода - 0054093E, нажимаем Ctrl+F2, переходим по адресу (Ctrl+G -> 0054093E -> Enter) и меняем переходик. После чего жмакаем правой кнопкой по листингу -> Copy to Executable -> All modifications -> Copy All. Сохраняем под новым именем, и... нет, ещё не закрываем статью, потому что дальше будет поинтереснее =).
Часть 2 - Убираем проверку на "вшивость" патченного EXE
Те, кто уже обрадовались, что всё закончено, ошибались, ибо после запуска Garena.exe появляется окошко с надписью "You are using a *****ed version of Garena. Garena will close shortly ...". Эх, а я то уж обрадовался...
Снова загружаем Garen'у в Ольгу, и ставим hr на USER32.CreateDialogParamW (для этого нажимаем Ctrk+N, набираем "cre", оказываемся на функции, далее правай кнопка-> Follow import in disassembler и мы в первой строке кода данной API). Запускаем прогу и пропускаем все ненужные срабатывания бряка. Как только прога запустилась, сидим и ждем всплытие отладчика .
Ок, отладчик всплыл, вот стек:
Итак, вся соль в Avoid*****Plugin.dll, которая находится в папке с плагинами(пусть можно узнать, нажав Alt+E в Ольке). Её название говорит само за себя, чтоб постараемся устранить проверку на вшивость ЕХЕ-шника. Выходим к тому месту, где была вызвана брякнутай апишка:
Код:
0012E630 04E793F7 /CALL to CreateDialogParamW from AvoidCra.04E793F1
Дальше по логике вещей надо посмотреть выше вызова USER32.CreateDialogParamW на переходы, которые перескакивают через этот самый вызов =)
Здесь их три штуки, и все они прыгают на один и тот же код, следовательно, проверка проверяется по трем критериям, и если первое правильное, то проверяем второй и т.д. Кароче нам надо заменить самый старший (читай стоящий выше) условный переход на безусловный. Чтобы убедится, что нам нужно менять именно этот переход, можно поставить hr бряк на него :
Код:
04E79370 /0F84 83000000 JE AvoidCra.04E793F9
Рестартуем Garena -> Ctrl+F2, и запускаем -> F9. Останавливаемся на бряке, и видим, что он сейчас не сработает, меняем флаг Z и никакого окошка не появляется! Ура, товарищи!
Теперь есть один момент по поводу того, как сделать так, чтобы был jmp а не je. Как вы знаете, править то нам сейчас нельзя, а при рестарте прога ещё не загрузила DLL. Есть, конечно всевозможные методы инлайна, но мы воспользуемся более простым - замена опкода команды в файле. Как вы уже поняли, менять будем не опкод команды jmp на je, а "xor eax, eax" на "test eax,eax", стоящий выше перехода. Почему? Да потому что у test и xor всегда одинаковый опкод, независимо от из расположения по какому либо смещению, потому что они не работают со смещениями (не пользуются ими), а у je и jmp опкод высчитывается исходя из того, на каком месте стоит команда и куда она прыгает (для проверки сами попробуйте расположить эти команды по разным местам и увидите различия в опкоде).
Итак, меняем "test eax, eax" на "xor eax,eax" (85С0 меняем на 33С0). Я буду юзать HIEW32. Открываем файл в HIEW32, жмем F4, выбираем HEX и нажимаем F7 для поиска, теперь пишем опкоды команд (желательно брать побольше, чтобы нашлось только одно уникальное совпадение, в данном случае достаточно ввести опкоды test'a и следующего mov'a - 85 C0 89 47 14). Ок, теперь нажимаем F3, вводим 33 и нажимаем F9, а затем и F10 для выхода. "Теперь можно спокойно играть? ", - нет нет, есть ещё одна проверочка, хехе.
Часть 3 - Убираем проверку в EXE на вшивость DLL'ок xD
Теперь если мы попытаемся запустить ЕХЕ, то выдается ошибка "Check File (...Avoid*****Plugin.dll)Error". Хехе, наблюдаем мат Garen'ы, которая обнаружила вторжение во владение DLL. Давайте исправлять... Попытаемся найти проверку в EXE на валидность DLL'ок. Грузим в Ольку наш ранее патченный EXE.
Существует несколько способов снятия защиты проверки DLL, я напишу тот, который попроще:
Можно предположить, что сначала происходит проверка, а потом, если DLL в норме, то она загружается. Ок, ставим hr бряк на функцию LoadLibraryW вышеописанным способом, и запускаем прогу.
Видим, что сразу происходит остановка, и если чуть придавить F9 кирпичом, то можно заметить, что все DLL, лежащие в папке plugins грузятся из одного места (смотрим на адрес возврата):
Код:
0012E710 004FC673 /CALL to LoadLibraryW from Garena1.004FC66D
0012E714 001F5178 FileName = "C:ProgramsGarenapluginsUI/ViwawaPlugin.dll"
Выходим по адресу возврата и оказываемся тут:
Код:
004FC66A . /74 5D JE SHORT Garena1.004FC6C9 ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
004FC66C > |57 PUSH EDI ; /FileName
004FC66D . |FF15 F8125A00 CALL DWORD PTR DS:[<&KERNEL32.LoadLibrar>; LoadLibraryW
Выше есть переход, который я и попробовал первым делом: ставим бряк (хардварный, конечно) и смотрим, что же происходит: АГА, прыжка не происходит никогда, кроме... хехе, догадайтесь сами)
Инвертируем флаг Z и... УРА! Garena успешно стартовала!!!
Остается дело за малым: запоминаем адрес перехода, давим на Ctrl+F2, затем переходим по адресу и забиваем переход командами nop.
Чтож, теперь всё работает и таймер убран) Можно играть в доту и не пытаться войти в топовые комнаты по полчаса, теперь шанс значительно увеличен.
Взято с *****lab.ru, Автор: [PNZ]human <[Ссылки могут видеть только зарегистрированные пользователи. ]>
От себя добавлю: если вы хотите заниматься реверсингом, но не знаете с чего начать - этот минигайд для Вас.