Steam и фриварная японская говногама [Часть 1].

"Romance of the Three Kingdoms Maker".

Эта игра добавляется в виде бесплатной лицензии на аккаунт, поэтому, если она Вам нахуй не всралась, то и нехуй ее добавлять.

Сразу уточню несколько важных моментов:
  1. Игра накрыта последней (или одной из последних) версией Steam stub, которая шифрует игровой код + steam api для внутристимовых нужд;
  2. Имеет топорный антидамп в виде неебически большого значения virtual size секции .data;
  3. В качестве антиотладки юзаются IsDebuggerPresent + NtSetInformationThread;
Примечание:
Steam stub никогда не портит импорт, что равняет принцип его работы с древними пакерами конца 90-х - начала 00-х годов.

Приступаем.
Забрасываем в отладчик файл Launch.exe и оказываемся на точке входа упаковщика.

Если мы запустим игру под отладчиком, то нам будет выплюнута ошибка, которая означает, что код игры не был распакован из-за обнаружения отладчика, соответственно и Steam не получил управления над процессом.



Поставим брейкпоинт на пролог функции MessageBoxA, а именно на инструкцию Retn 10 и выйдем на то место в коде, в котором происходит проверка.
После нажатия OK в окне с ошибкой наш брейкпоинт сработает.
 


Так же в стеке мы можем наблюдать адрес возврата в код упаковщика (подсвечен синим).
Трассируем внутрь по F7 и пропускаем весь остальной код модулей по Ctrl+F9 до тех пор, пока не доберемся до нужного адреса.
 
 Пролистав чуть выше мы замечаем инструкцию CALL NEAR EDX.
Можем смело сказать, что это вызов функции, адрес которой берется из регистра EDX.
Чуть выше мы можем наблюдать условие проверки такого вида:
122804A0    85D2            TEST EDX,EDX
122804A2    74 14           JE SHORT Launch.122804B8
Поставим аппаратный брейкпоинт на 122804A0 и перезапустимся.

EDX заполнен адресом, указывающим на вызов MessageBoxA, вызываемым через дебри apphelp.dll. Ебаная windows10. Сплошные редиректы и форварды.
Установим флаг Z=1, чтобы пропустить функцию и тем самым удовлетворить условию.
Продолжаем трассировку до тех пор, пока не дойдем до этого адреса:

122804DB    FF95 D0FEFFFF   CALL NEAR DWORD PTR SS:[EBP-130]         ; KERNEL32.TerminateProcess

Мда.Упаковщик собрался загасить процесс, но хуй там плавал.
Ставим New Origin на следующую инструкцию.
Код здесь предельно понятный, поэтому трассируем до RETN.
Попадаем сюда и продолжаем трассировать код дальше и дойдя до RETN видим, что нас хотят вернуть к нулевому адресу.
Забегая вперед скажу, что мы не обошли антиотладку и искусственно дошли до конца процедуры распаковки, но она не вернула нас на точку входа игры.Так будет, если попытаться обойти проверки в лоб.


План Б.
Перезапускаем, фолловим адрес из EBX в дамп и чистим PEB.BeingDebugged.
Теперь ставим брейкпоинт на RETN в функции IsDebuggerPresent и жмем F9.
В EAX у нас ноль, так как мы заставили программу думать, что она не находится под отладкой.
Трассируем внутрь и попадаем в выделенную область памяти.
(Этот массив создается вызовами функции VirtualAlloc, а с помощью VirtualProtect ему выставляются необходимые права доступа).


Так как EAX=0, то условие выполнится и нас переместят дальше по коду.

Продолжаем трассировку, но будем очень внимательны.
Смело можем трассировать до данного адреса:

14516244    FFD6            CALL NEAR ESi                            ; 
ntdll.ZwSetInformationThread

Нас встречает очередная антиотладочная функция, в случае выполнения которой мы потеряем управление и в результате возникшего исключения не сможем продолжить дальнейшие действия.Ставим New Origin на следующую инструкцию и продолжаем трассировку.
Первый встречающийся CALL мы пропустим, но на втором остановимся.

Далее будут приведены скриншоты с другими адресами, но это не суть как важно.При каждом перезапуске Steam меняет область памяти, из которой выполняется процесс расшифровки оригинального файла.

Если мы посмотрим на загруженные модули, то не заметим ничего интересного.
А что будет, если мы выполним данную инструкцию:
144F6277    E8 94FCFFFF     CALL 144F5F10


Steam подгрузил свои дополнительные библиотеки и все необходимое, в т.ч. криптографический модуль, входящий в состав windows.
Определенно, это процедура расшифровки.Мы не будет детально разбираться в ее кишках, просто переместимся к следующей инструкции по F4.

Примечание.Сам Steam сейчас считает, что игра запущена, т.е. ничего подозрительного не происходит.
Далее по коду мы можем наблюдать пару условий:
А конкретно первое у нас будет выполнено.


Фактически оно у нас означает, что игра распаковалась, отладки нет, но мы пропускаем важный вызов:
144F628E    E8 7DFAFFFF     CALL 144F5D10
Если мы его зафолловим, то заметим вызов функции GetCommandLineA и аргумент -applaunch.
 
А в прологе процедуры можно заметить вызов ShellExecuteA.

Иными словами, Steam собирается запустить игру, но мы ему не дадим это сделать, а уже описанное выше условие это сделать не позволит, а соответственно управления над процессом мы не потеряем и при этом не получим ошибки.

Но в случае, если условие
144F6281    80FB 30         CMP BL,30
144F6284    74 1B           JE SHORT 144F62A1
будет не выполнено, то произойдет очередная проверка:
144F6286    80FB 35         CMP BL,35
144F6289    75 0B           JNZ SHORT 144F6296
Условие которой будет выполнено, ибо BL=30, что отлично от 35.
Если мы будем трассировать код до конца процедуры распаковки, вид которого можно посмотреть в первой части статьи, то адрес возврата уже будет не нулевым, но и совершенно не тем, который нам нужен.
Если нажмем F9, то получим необрабатываемое исключение.

А если отправим секцию кода в дизассемблер, то получим кашу, так как распаковщик не перезаписал распакованный и расшифрованный код и в целом отработал неверно.

Вернемся к первому условию.Нас перемещают сюда:

Смело трассируем до следующего важного условия.Почему оно важное ?
Я снимал стим стаб старых версий и всегда в процессе расшифровки  и перед выходом на точку входа это условие выполнялось.Это своего рода сигнатура.

Делаем флаг Z=1, чтобы оно выполнилось и выходим из процедуры, трассируя внутрь.
Мы можем пропустить данный цикл, нажав F4 ниже условного перехода, подсвеченного синим, и продолжить трассировку.
Если все сделано правильно, то мы окажемся на знакомом месте - концовке процедуры распаковки.
Трассируем дальше и замечаем интересную вещь:
Регистр EAX содержит довольно интересный адрес.Отправляем его в дизассемблер.

Хех.Это точка входа, стандартная для эксешников, скомпилированных в MS VisualStudio (не древних версий).
Трассируем дальше и в последующем коде, после извлечения из стека значений для всех регистров, будет выполнена долгожданная инструкция RETN, которая вернет нас прямиком на точку входа.

Снимаем дамп.

Получаем дамп неебических размеров.
Всему виной размер секции .data.
Чтобы не ебать себе мозги, я воспользуюсь ребилдером, встроенным в PeTools.
Охуенчик.Файл ужался на 99%....

 
И он запускается..А стим не замечает подвоха.
 

Продолжение следует...

Комментарии

Популярные сообщения из этого блога

[Patch] Alone In The Dark - The New Nightmare

Steam и фриварная японская говногама [Часть 2].

Mafia 3 Savegame Editor