Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 12 ноября!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

Securom 7 на F.E.A.R. или Мы ожидали большего.

Обсудить статью на форуме

Хорошая подборка видеоуроков, инструментов крэкера, книг и статей - здесь.

Автор: Ra$cal <rascalspb dog mail dot ru>

Доброго времени суток всем читающим. Надеюсь, все знакомы с игрой F.E.A.R. Если всё же кто-то не в курсе, очень ожидаемая игра, одна из единиц, в которые мне хотелось играть. Графика хороша(большего не позволяет мой Celeron:), геймплэй страшноватый-затягивающий (ночью без света со звуком лучше все-таки не играть) вобщем у кого машина посильнее очень рекомендую. Теперь по поводу используемой защиты: в папочке лежит программа с названием “SR7Stop.exe”, а одна из секций называется securom, что наталкивает нас на мысль о присутствии защиты от Sony: Securom, и похоже 7 версии. В прошлой моей статье про игру Emire Earth 2 я рассматривал Securom 4-ой версии. Чудно, посмотрим, как изменилась эта защита.

Ну что, для начала смотрим, что нам говорит PeiD, а говорит он “nothing found”, ну и ладно, не очень-то и надо было. Теперь пробуем открыть fear.exe в Olly. Точка входа незнакома. Ладно, в прошлый раз мы ловили апи CreateEvent, попробуем и в этот раз, вдруг прокатит, ставим бряку и отпускаем прогу и... очень странно, в статус баре видим access violation when reading XXXXXXXX. Жмём паузу и смотрим, снимаем в опциях отладчика все флажки по поводу исключений и продолжаем гаму. Исключение происходит здесь:


007AEB58    66:813E 4D5A      CMP WORD PTR DS:[ESI],5A4D
 007AEB5D    75 3E             JNZ SHORT FEARR.007AEB9D
 007AEB5F    8B46 3C           MOV EAX,DWORD PTR DS:[ESI+3C]
 007AEB62    03C6              ADD EAX,ESI
 007AEB64    8138 50450000     CMP DWORD PTR DS:[EAX],4550
 007AEB6A    75 31             JNZ SHORT FEARR.007AEB9D
 007AEB6C    0FB758 16         MOVZX EBX,WORD PTR DS:[EAX+16]
 007AEB70    33C9              XOR ECX,ECX
 007AEB72    F7C3 00200000     TEST EBX,2000
 007AEB78    74 20             JE SHORT FEARR.007AEB9A
 007AEB7A    8378 78 00        CMP DWORD PTR DS:[EAX+78],0
 007AEB7E    74 1A             JE SHORT FEARR.007AEB9A
 007AEB80    8B58 78           MOV EBX,DWORD PTR DS:[EAX+78]
 007AEB83    03DE              ADD EBX,ESI
 007AEB85    8B4B 0C           MOV ECX,DWORD PTR DS:[EBX+C]
 


(справка: 5A4D - MZ, 4550 – PE :). Смотрим в стек и видим:


00210E04   0022FFB0  Pointer to next SEH record
 00210E08   007AEBC3  SE handler
 


Теперь топаем сюда - 007AEBC3. Это обработчик исключений, заданный самим секуромом. Ставим туда бряку и жмём Shift+F9.


007AEBC3    55                PUSH EBP
 007AEBC4    8BEC              MOV EBP,ESP
 007AEBC6    53                PUSH EBX
 007AEBC7    8B5D 10           MOV EBX,DWORD PTR SS:[EBP+10]
 007AEBCA    8B45 08           MOV EAX,DWORD PTR SS:[EBP+8]
 007AEBCD    A1 A024C400       MOV EAX,DWORD PTR DS:[C424A0]
 007AEBD2    8983 B8000000     MOV DWORD PTR DS:[EBX+B8],EAX
 007AEBD8    33C0              XOR EAX,EAX
 007AEBDA    5B                POP EBX
 007AEBDB    8BE5              MOV ESP,EBP
 007AEBDD    5D                POP EBP
 007AEBDE    C3                RETN



Немного потрейсим и обратим внимание на строки:


007AEBCD    A1 A024C400       MOV EAX,DWORD PTR DS:[C424A0]
 007AEBD2    8983 B8000000     MOV DWORD PTR DS:[EBX+B8],EAX


Как можно заметить число по адресу DWORD PTR DS:[C424A0] лежит в диапазоне адресов кода секурома. Смотрим, куда он указывает - 007AEB9D:


007AEB9D    81E6 0000FFFF     AND ESI,FFFF0000
 007AEBA3    81C6 00000100     ADD ESI,10000
 007AEBA9    81FE 000000C0     CMP ESI,C0000000
 007AEBAF  ^ 72 A7             JB SHORT FEARR.007AEB58
 007AEBB1    64:8F05 00000000  POP DWORD PTR FS:[0]


То есть обнуляет 2 младших байта, затем прибавляет 10000, если это меньше C0000000, тогда переходит туда, где обычно происходит исключение, иначе восстанавливаем SEH и валим. В этом блоке, кто ещё не догадался, защита ищет загруженные библиотеки и их адреса загрузки (MZ и PE – для проверки, исполняемый файл или нет, то бишь библиотека). Без апи, плюс к этому в Olly это занимает много времени, поэтому, когда мы дождёмся конца этой функции, нас пошлют. Можно подменять адреса нужными, глядя на меморимап, но нас всё равно обломают. Есть идея получше – мы запускаем гаму отдельно, после запуска с максимальной скоростью аттачимся к ней (чтобы было проще и быстрее я в PEExplorer’e немного увеличил размеры окна аттача в Olly, чтобы не тратить время на прокрутку). Теперь ставим бряки на доступ на все секции и жмём Shift+F9 пока не дойдём до такого места:


00535EEA    8B3D 78405400    MOV EDI,DWORD PTR DS:[544078]            ; kernel32.GetModuleHandleA
 00535EF0    FFD7             CALL NEAR EDI
 00535EF2    66:8138 4D5A     CMP WORD PTR DS:[EAX],5A4D
 00535EF7    75 1F            JNZ SHORT FEARR.00535F18
 00535EF9    8B48 3C          MOV ECX,DWORD PTR DS:[EAX+3C]
 00535EFC    03C8             ADD ECX,EAX



Прокрутив немного выше можно узнать стандартное начало программ на С++.


00535ED8    6A 74            PUSH 74
 00535EDA    68 30965500      PUSH FEARR.00559630
 00535EDF    E8 F0040000      CALL FEARR.005363D4
 00535EE4    33DB             XOR EBX,EBX
 00535EE6    895D E0          MOV DWORD PTR SS:[EBP-20],EBX
 00535EE9    53               PUSH EBX
 00535EEA    8B3D 78405400    MOV EDI,DWORD PTR DS:[544078]            ; kernel32.GetModuleHandleA
 00535EF0    FFD7             CALL NEAR EDI
 00535EF2    66:8138 4D5A     CMP WORD PTR DS:[EAX],5A4D


Мы остановились на несколько команд позже, чем надо было, поэтому не забудем поправить OEP на 135ED8. Теперь надо сдампить нашу почти уже распакованную игруху. Если дампим в Olly, не забываем убрать галочку “Rebuild Import”, жмём Dump и видим фигу. Ещё один финт протектора. Пробуем в PETools. Tools’ы говорят ОК, но глядя на дамп этого не скажешь (2 Мб – код протектора конечно занимает место, но не 2.4 же метра, да и куда иконка делась). Тогда пробуем дампить по частям. По адресу 00561000 сдампить не можем. Значит некоторые страницы заблокированы (PAGE_GUARD, вещают нам Tools). Опять открываем отладчик с нашей гамой и в memorymap в свойствах всех секций выбираем Set access->Full Access. Теперь дампится всё и без ошибок. У дампа импорт перестраивать не надо, как и раньше секция импорта на месте и без повреждений. Дамп готов поехали дальше...

Пробуем запустить наш свеженький дамп и, ожидаемо, получаем ошибку, не может быть всё так просто, это ж всё таки протектор. Теперь пробуем запустить дамп под отладчиком:


007C89E6    8B12              MOV EDX,DWORD PTR DS:[EDX]
 007C89E8    891424            MOV DWORD PTR SS:[ESP],EDX
 007C89EB    85D5              TEST EBP,EDX



Исключение в первой строке. Надо найти, откуда оно берётся, и что из себя собсно представляет этот механизм защиты. Можно дойти по шагам, а можно посмотреть в стеке, по шагам надёжнее, но я уже знаю, что и откуда вызывалось, по этому пойду через стек:


0012FEE8   018809D8
 0012FEEC   00000202
 0012FEF0   77E7AD86  kernel32.GetModuleHandleA
 0012FEF4   005610A8  Копия_Ко.005610A8
 0012FEF8   0012FFC0
 0012FEFC   0012FF10
 0012FF00   00000000
 0012FF04   7C38B1D8  MSVCR71.7C38B1D8
 0012FF08   00562298  Копия_Ко.00562298
 0012FF0C   00537D20  Копия_Ко.00537D20
 0012FF10   00D9608E  RETURN to Копия_Ко.00D9608E from Копия_Ко.007C86D0
 0012FF14   0040A495  Копия_Ко.0040A495
 0012FF18   00537D30  RETURN to Копия_Ко.00537D30 from Копия_Ко.0040D940
 0012FF1C   7C341CD6  RETURN to MSVCR71.7C341CD6
 0012FF20   0012B998
 0012FF24   00536007  RETURN to Копия_Ко.00536007 from <JMP.&MSVCR71._initterm>


Последняя строчка (<JMP.&MSVCR71._initterm>) показывает, что вызвалась функция _initterm. Она вызывается обычно в самом начале работы программы.


0012FF18   00537D30  RETURN to Копия_Ко.00537D30 from


Последней вызов из секции кода игры. Идем туда и заходим в вышерасположенный call. Что мы видим там, прыжок в секцию секурома:


0040D940   $- E9 3F879800     JMP Копия_Ко.00D96084
 0040D945      1750D700        DD Копия_Ко.00D75017
 0040D949      9F51D700        DD Копия_Ко.00D7519F
 0040D94D      FF52D700        DD Копия_Ко.00D752FF
 0040D951      9F54D700        DD Копия_Ко.00D7549F
 0040D955      F755D700        DD Копия_Ко.00D755F7
 .
 поскипано
 .
 0040DA7F   . /EB 08           JMP SHORT Копия_Ко.0040DA89
 0040DA81   . |EB 06           JMP SHORT Копия_Ко.0040DA89
 0040DA83   . |EB 04           JMP SHORT Копия_Ко.0040DA89
 0040DA85     |EB              DB EB
 0040DA86     |00              DB 00
 0040DA87     |00              DB 00
 0040DA88     |00              DB 00
 0040DA89   > \C3              RETN



Теперь посмотрим, что же там, в секции секурома:


00D96084    68 95A44000       PUSH Копия_Ко.0040A495
 00D96089    E8 4226A3FF       CALL Копия_Ко.007C86D0
 00D9608E  - E9 F67967FF       JMP Копия_Ко.0040DA89


Посмотрите внимательно, куда ведёт прыжок из секции секурома... на ret в коде игры, то есть на конец процедуры. Это очень похоже на антидмпы или code splising в Armadillo, только здесь убрана процедура целиком и прыжок идёт в пределы программы, а не в аллоченную память. Но ошибка где-то глубже, значит, копаем дальше. Можно посмотреть громадную функцию секурома (где исключение), а можно посмотреть причину, что по-моему логичнее. Итак, прот обращается к памяти, которая недоступна. Обращение у меня идёт по адресу 018809D8. Значит мне нужен участок памяти, начиная с 01880000. Адрес начала участка в открытом виде не используется, в EDX кладётся число, к нему прибавляется другое, далее для доступа будет использоваться и регистр EAX. Следить за всеми превращения мне влом, тем более и тут видимо есть проверка, т.к. нераспакованный FEAR после тщательных неторопливых исследований вылетел с неизвестной ошибкой. Это нужно было для разбора принципа работы этой функции относительно выделенного куска памяти, то есть откуда берутся его адреса и как они обрабатываются, чтобы потом припаять его к новой последней секции и перенаправить указатели у секурома. Раз уж это не работает, тогда делаем ещё проще:

1) Дампим участок памяти по адресу 01880000
2) В PEEditore грузим секцию с диска, увеличиваем виртуальный размер секции .securom (то есть перед добавленной) так, чтобы она заканчивалось на адресе 01880000, то есть к VS += 01880000 – (VO+VS)
3) У новой секции ставим Virtual Offset 01880000
4) Я не учёл ImageBase, поэтому после проверки уменьшил Virtual Offset новой секции на 400000 и стало это 01480000

Не надеясь на рабочее состояние игры я после проверки работоспособности добавления отпустил гаму в поисках других ошибок. Каково же было моё удивление, когда всё заработало. Правда выход осуществился в разрешение 800Х600 и винда благородно разместила все значки, которые я расставлял несколько дней в поисках абсолютного удобства, в зоне видимости, смешав всё в фарш. Ещё была замечена фишка, что если после нескольких разов попытаться прицепиться к игре и выйти через F4 секуром после F9 не продолжал выполнение, с этим можно бороться запуская FearRun.exe, правда если у вас именно тот DVD, который и у меня.

Предвкушая новые извращения над импортом (вспомните статью про Empire Earth 2) и увидев их отсутствие я был сильно обломан. Но может это и к лучшему, игра работает без них быстрее, а с её требования и моими возможностями это ой как важно. За сим разрешите откланяться.

Все претензии и прочее шлите мылом: rascalspb dog mail dot ru



Обсуждение статьи: Securom 7 на F.E.A.R. или Мы ожидали большего. >>>


Материалы находятся на сайте https://exelab.ru



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS