beatcracker: (Default)
Давно заметил за собой, что ковыряться в игрушках, мне порою гораздо интересней, чем играть в них. В этот раз, в мои руки попал Need for Speed: Carbon - очередное творение программистов из EA BlackBox.

Имевшаяся у меня версия игры, была собрана криворукими пиратами, как бог на душу положит. Вот куски из лога инсталлера:

File Overwrite: C:\XP\system32\msvcrt.dll
File Overwrite: C:\XP\system32\mfc42.dll

поскипано

Self-Register: C:\XP\system32\mfc42.dll
Self-Register: C:\XP\system32\xmlinst.exe
Self-Register: C:\XP\system32\vp6dec.ax
Self-Register: C:\XP\system32\olepro32.dll
Self-Register: C:\XP\system32\oleaut32.dll
Could not Self-Register: C:\XP\system32\msxml4r.dll
Could not Self-Register: C:\XP\system32\msxml4a.dll
Self-Register: C:\XP\system32\msxml4.dll
Could not Self-Register: C:\XP\system32\msxml3a.dll
Self-Register: C:\XP\system32\msvbvm60.dll
Self-Register: C:\XP\system32\msvbvm50.dll
Self-Register: C:\XP\system32\MSINET.OCX
Self-Register: C:\XP\system32\MSCOMCTL.OCX
Could not Self-Register: C:\XP\system32\mfc70u.dll
Could not Self-Register: C:\XP\system32\mfc70.dll
Self-Register: C:\XP\system32\MCI32.OCX
Self-Register: C:\XP\system32\Comdlg32.ocx
Self-Register: C:\XP\system32\Camiseta.ocx
Self-Register: C:\XP\system32\AniGIF.ocx



За такое надо бить по рукам! Наивные попытки зарегистрировать сишный рантайм, копирование никому не нужного декодера VP6 (в игре он встроенный), а также абсолютно не нужных дельфийному авторану Camiseta.ocx и шароварного AniGIF.ocx. Автором последнего является жадный китайский программист Jin Hui. Это не говоря, про то, что тот же авторан настойчиво предлагает установить кодеки Intel Indeo, а на диске валяется подборка Windows Media кодеков и что,самое интересное, драйвера для PhysX! А вот для видеокарт драйверов почему-то нет ... Явный недосмотр.

Двигаемся дальше. Игра установлена, sfc /scannow , для восстановления баланса dll в системе успешно отработала и можно приступать к самому интересному - собственно игре.

Как и все игры серии NFS (начиная с Hot Pursuit 2) эта разрабатывается одновременно на несколько платформ (PC, XBox, PlayStation), что накладывает на неё определенный отпечаток. В частности в коде встречаются упоминания PS3 и XBOX360, работы с геймпадами и картами памяти. Кстати, распространенное мнение, о том, что игры с 6 по 10 части разрабатываются на одном движке, не совсем соответствует действительности. На самом деле движок 6 части это нечто промежуточное между 5 и 7 и стоит особняком, а вот уже начиная с 7 части (NFS: Underground) движок менялся слабо. Из заметных глазом различий, в 8 части разработчики ушли от видео в проприетарном формате mad и стали использовать прогрессивный mpeg4 кодек vp6 от ON2. Не то, что бы mad сильно плох, но как и большинство старых игровых видеоформатов он гораздо более заточен под скорость воспроизведения, чем под качество картинки.

Не вдаваясь в подробности, первое, что меня огорчило - это отсутствие субтитров в видеовставках, о наличии в игре которых недвусмысленно говорила папка SUBTITLES. Правда позже выяснилось, что собственно сами файлы лежащие там,субтитрами не являются, но это несущественно. Достаточно продолжительные поиски в различных форумах выявили, что в природе существуют русификаторы, в которых субтитры есть. Отбросив сумасшедшую мысль, что русифекализаторы пережали все vp6 с наложенными субтитрами, я скачал русификатор от ENPY Studio и установил. После этого все стало предельно ясно. Субтитры в игре действительно есть, но лишь в любой локали, отличной от английской, где они тоже имеют место быть, но не отображаются. Изначально NFS: Carbon поддерживает (в имеющейся у меня версии) 16 языков, языковые файлы для котрых лежат в папке LANGUAGES. Язык используемый игрой, определяется ключом в реестре:

HKLM\Software\Electronic Arts\Need for Speed Carbon\Language

Все остальные упоминания о локали в реестре самой игрой игнорируются и возможно нужны для работы EA support tools (их я не смотрел и могу ошибаться)

Русификаторы всего-лишь установили немецкую локаль, поправили соответствующие файлы немецкой локали и перерисовали шрифты. Субтитры включились автоматически. Отсюда у меня родился следующий метод включения субтитров:

Берем из папки LANGUAGES файлы

English_Frontend.bin
English_Global.bin
English_InGame.bin


Переименовываем их в соответственно в:

German_Frontend.bin
German_Global.bin
German_InGame.bin


и прописываем в реестре "Language"="German"., Сработало. Однако красивым такое решение не назовешь. Плюс ко всему кое-где проглядывает немецкий текст, например сообщение о удачной загрузке после показа вступительных роликов. Также для показа видео, необходимо будет переименовать в папке VIDEO все файлы по маске, заменив english на german. Поняв, что классическим методом тыка дальше не продвинуться я решил зайти с тыла.

Засовываем nfsc.exe в IDA и ждем. Наконец, IDA сообщает, что автоматический анализ файла закончен и мы можем приступать непосредственно к изучению внутренностей игры. Первым делом меня интересуют ссылки в коде на различные строки. По прошлому опыту я знаю, что в Need for Speed интерфейс игры базируется на системе скриптов. Попробуем найти их и здесь: В этой версии игры скрипты имеют расширение fng. Вот, что мне удалось получить:


DEMO_SPLASH.fng
FeOnlinePlayerStats.fng
FeOnlineLeaderboard.fng
FeGameRoomEditSettings.fng
FeGameRoomPlayerDetails.fng
FeOnlineGameRoom.fng
FeOnlineGameType.fng
FEOnlineTOS.fng
FeOnlineDisconnect.fng
FeOnlineFeedback.fng
FeOnlineMessengerInvitePopup.fng
FeOnlineMessengerChatPopup.fng
FeOnlineMessengerUserPopup.fng
FeOnlineMessenger.fng
FeOnlineChatDialog.fng
FEPCOnlineForgotAccount.fng
FEPCOnlineAccountTaken.fng
FEPCOnlineCDKey.fng
FEPCOnlineCreateAccount.fng
FEPCOnlineLogin.fng
MC_List.fng
FeSaveGhostDialog.fng
BUSTED_OVERLAY.fng
FeBusted.fng
FEPostPursuitRewards.fng
FePostStages.fng
FePostRaceResults.fng
Loading.fng
LS_LangSelect.fng
loading_boot.fng
Loading_Tips.fng
DEMO_PSA.fng
WS_LS_Splash.fng
LS_Splash.fng
FeBackdrop.fng
FeBlackScreen.fng
FeChyron.fng
FeQuickRaceWingman.fng
FeCarSelect.fng
FeRewardCard.fng
FESubtitler.fng
FEAnyMovie.fng
FeComingSoonM3.fng
FePhotoMode.fng
FeComingSoonM2.fng
ScreenPrintf.fng
Keyboard_PS3.fng
Keyboard.fng
InGameDialog.fng
Chyron_IG.fng
EA_Trax.fng
FeDialog.fng
DiscError.fng
FeGarageMain.fng
FeChallengeSeries.fng
FeRaceStatistics.fng
FeStatisticsStatsListing.fng
FePressStart.fng
FeQuickRaceOptions.fng
Options_PC_Controller.fng
FEJukebox.fng
FeOptionsScreen.fng
FeCustomizeAutozone.fng
FeVinylTransform.fng
FeCrewLogoColourChooser.fng
FeColourChooser.fng
FeVinylSelection.fng
FeLayerManagement.fng
FeShowcase.fng
FeMyCarsManager.fng
UI_DebugCarCustomize.fng
FeVisualRideHeight.fng
FeVisualWindowTint.fng
FEAutosculptTop.fng
FEAutosculptWheel.fng
FEAutosculptSpoiler.fng
FEAutosculptRoof.fng
FEAutosculptHood.fng
FEAutosculptExhaust.fng
FEAutosculptSkirt.fng
FEAutosculptRearBumper.fng
FEAutosculptFrontBumper.fng
FePerformanceSlider.fng
FeCustomizePerformance.fng
FeCustomizeParts.fng
FeCustomizeVisuals.fng
FeCustomizeMain.fng
FeCrewCar.fng
FeGameWon.fng
FeGameOver.fng
FeBonusCards.fng
FeCrewManagement.fng
FeCarClassSelect.fng
FeCrewLogo.fng
ControllerUnplugged.fng
FeSmsMessage.fng
FeSmsMailbox.fng
HUD_SingleRace.fng
Fe_WorldMap_RandomEncounter.fng
Fe_WorldMap_DefenceRace.fng
Fe_WorldMap_World_View.fng
FeWorldMapQuickList.fng
WorldMapMain.fng
Credits.fng
FePauseOptionsMain.fng
FePauseMain.fng
FeWidgetScroller.fng
FeTextScroller.fng
FeWidgetMenu.fng
FeMenuScreen.fng
FeArrayScroller.fng
FeIconScroller.fng
FeMainMenu_Sub.fng
FeMainMenu.fng
Fe_WorldMap_Acquisitions.fng


Как видите, названия вполне говорящие. особенно меня заинтересовали эти: LS_LangSelect.fng и FESubtitler.fng. Сразу скажу, что FESubtitler.fng меня ни к чему не привел, а вот с LS_LangSelect.fng всё гораздо интереснее. Вот кусок кода из IDA, интересные места выделены жирным, неинтересные поскипаны:



.text:005BD26E ; ---------------------------------------------------------------------------
.text:005BD271 align 10h
.text:005BD280
.text:005BD280 ; --------------- S U B R O U T I N E ---------------------------------------
.text:005BD280
.text:005BD280
.text:005BD280 sub_5BD280 proc near ; DATA XREF: .rdata:009D2654 o
.text:005BD280 ; .rdata:009E8C64 o
.text:005BD280
.text:005BD280 var_4= dword ptr -4
.text:005BD280
.text:005BD280 push ecx
.text:005BD281 push esi
.text:005BD282 mov esi, ecx
.text:005BD284 mov eax, [esi+4]
.text:005BD287 inc eax
.text:005BD288 cmp eax, 0Bh ; switch 12 cases
.text:005BD28B ja near ptr unk_5BD423
.text:005BD291 jmp ds:off_5BD428[eax*4] ; switch jump
.text:005BD298
.text:005BD298 loc_5BD298: ; DATA XREF: .text:005BD428 o
.text:005BD298 mov eax, [esi+0D4h] ; case 0x1
.text:005BD29E push 1
.text:005BD2A0 push 12h
.text:005BD2A2 push offset aAttract ; "Attract"
.text:005BD2A7 mov ecx, esi
.text:005BD2A9 mov [esi+0D0h], eax
.text:005BD2AF call sub_593730
.text:005BD2B4 pop esi
.text:005BD2B5 pop ecx
.text:005BD2B6 retn

.text:005BD2D4 ; ---------------------------------------------------------------------------
.text:005BD2D4
.text:005BD2D4 loc_5BD2D4: ; CODE XREF: sub_5BD280+11 j
.text:005BD2D4 ; DATA XREF: .text:005BD428 o
.text:005BD2D4 push 0Dh ; case 0x3
.text:005BD2D6 push offset aFeblackscreen_ ; "FeBlackScreen.fng"
.text:005BD2DB mov ecx, esi
.text:005BD2DD call sub_5936B0
.text:005BD2E2 pop esi
.text:005BD2E3 pop ecx
.text:005BD2E4 retn
.text:005BD2E5 ; ---------------------------------------------------------------------------

.text:005BD323 ; ---------------------------------------------------------------------------
.text:005BD323
.text:005BD323 loc_5BD323: ; CODE XREF: sub_5BD280+11 j
.text:005BD323 ; DATA XREF: .text:005BD428 o
.text:005BD323 push 0FFFFFFFFh ; case 0x6
.text:005BD325 push 0FFFFFFFFh
.text:005BD327 push 0FFFFFFFFh
.text:005BD329 lea ecx, [esp+14h+var_4]
.text:005BD32D push ecx
.text:005BD32E push 13BEh
.text:005BD333 mov ecx, offset unk_A8AD30
.text:005BD338 mov [esp+1Ch+var_4], 0
.text:005BD340 call sub_4A0490
.text:005BD345 mov eax, [esp+8+var_4]
.text:005BD349 test eax, eax
.text:005BD34B push 1
.text:005BD34D mov ecx, esi
.text:005BD34F push 13h
.text:005BD351 jz short loc_5BD360
.text:005BD353 push offset aEa_bumper_ws ; "EA_Bumper_WS"
.text:005BD358 call sub_593730
.text:005BD35D pop esi
.text:005BD35E pop ecx
.text:005BD35F retn
.text:005BD360 ; ---------------------------------------------------------------------------
.text:005BD360
.text:005BD360 loc_5BD360: ; CODE XREF: sub_5BD280+D1 j
.text:005BD360 push offset aEa_bumper ; "EA_Bumper"
.text:005BD365 call sub_593730
.text:005BD36A pop esi
.text:005BD36B pop ecx
.text:005BD36C retn
.text:005BD36D ; ---------------------------------------------------------------------------
.text:005BD36D
.text:005BD36D loc_5BD36D: ; CODE XREF: sub_5BD280+11 j
.text:005BD36D ; DATA XREF: .text:005BD428 o
.text:005BD36D push 1 ; case 0x7
.text:005BD36F push 14h
.text:005BD371 push offset aEahd_bumper ; "EAHD_Bumper"
.text:005BD376 mov ecx, esi
.text:005BD378 call sub_593730
.text:005BD37D pop esi
.text:005BD37E pop ecx
.text:005BD37F retn
.text:005BD380 ; ---------------------------------------------------------------------------
.text:005BD380
.text:005BD380 loc_5BD380: ; CODE XREF: sub_5BD280+11 j
.text:005BD380 ; DATA XREF: .text:005BD428 o
.text:005BD380 mov eax, dword_A99C60 ; case 0x9
.text:005BD385 push 10h
.text:005BD387 push offset aLs_langselect_ ; "LS_LangSelect.fng"
.text:005BD38C mov ecx, esi
.text:005BD38E mov [esi+0C4h], eax
.text:005BD394 call sub_5936B0
.text:005BD399 pop esi
.text:005BD399 ; ---------------------------------------------------------------------------

.text:005BD425
.text:005BD426 align 4
.text:005BD428 off_5BD428 dd offset unk_5BD41A ; DATA XREF: sub_5BD280+11 r
.text:005BD428 dd offset loc_5BD298 ; jump table for switch statement
.text:005BD428 dd offset loc_5BD2B7
.text:005BD428 dd offset loc_5BD2D4
.text:005BD428 dd offset loc_5BD2E5
.text:005BD428 dd offset loc_5BD2FD
.text:005BD428 dd offset loc_5BD323
.text:005BD428 dd offset loc_5BD36D
.text:005BD428 dd offset loc_5BD2C1
.text:005BD428 dd offset loc_5BD380
.text:005BD428 dd offset unk_5BD39C
.text:005BD428 dd offset unk_5BD3D1


В привычном виде эта конструкция выглядела бы так:

Select Case X
Case 1
Call Attract
Case 2
Call FeBlackScreen.fng


etc..

С Attract и EA_Bumper всё ясно. Это ролики, лежащие в папке VIDEO. А вот скрипты FeBlackScreen.fng и LS_LangSelect.fng интригуют. Запустив NFS под отладчиком, встроенным, в IDA я увидел, что первым выполняется FeBlackScreen.fng. Название свое он оправдывает, экран действительно черный. Далее идут EA_Bumper'ы, собствено загрузка UI игры. До LS_LangSelect.fng дело не доходит. Что ж попытаемся это исправить. Опять запускаем отладку, и в момент перехода на FeBlackScreen.fng меняем EIP, так, чтобы он указывал на код выполняющий LS_LangSelect.fng. Удача улыбается нам и мы видим следующую картину:

NFSC built-in language selector aka LS_LangSelect.fng

Однако наше счастье неполно. Во первых доступны всего два языка, английский и испанский, а во вторых, в английском нет долгожданных субтитров :( ... Ситуацию с недостающими языками можно было бы исправить редактированием LS_LangSelect.fng. В Hot Pursuit 2, скрипты были в текстовом виде и легко подвергались модификации. Вот например скрипт, рисующий одно из диалоговых окон настроек:

[01jump.ToggleButton]
ToggleButton.mDataEnum=kOptionsJumpCam
CHILDREN=pc\pc.cnt.toggle
GUI.mTabOrder=2
GUI.mStyle=GS_TAB|GS_MOUSEFOCUS|GS_NOTIFY
GUI.mBounds=[300, 57] 233, 20
GUI.mFont=Pmedium
GUI.mPalette=P_TOGGLE
GUI.mColor=[255, 255, 255, 88]
GUI.mText=kTxtJumpCam
GUI.mZOrder=5
ToggleButton.mListName=<ON_OFF>


[02360.ToggleButton]
ToggleButton.mDataEnum=kOptions360Cam
CHILDREN=pc\pc.cnt.toggle
GUI.mZOrder=4
GUI.mTabOrder=3
GUI.mStyle=GS_TAB|GS_MOUSEFOCUS|GS_NOTIFY
GUI.mBounds=[300, 87] 233, 20
GUI.mFont=Pmedium
GUI.mPalette=P_TOGGLE
GUI.mColor=[255, 255, 255, 88]
GUI.mText=kTxt360Cam
ToggleButton.mListName=<ON_OFF>


[03asav.ToggleButton]
ToggleButton.mDataEnum=kOptionsAutoSave
CHILDREN=pc\pc.cnt.toggle
GUI.mZOrder=7
GUI.mTabOrder=4
GUI.mStyle=GS_TAB|GS_MOUSEFOCUS|GS_NOTIFY
GUI.mBounds=[300, 117] 233, 20
GUI.mFont=Pmedium
GUI.mPalette=P_TOGGLE
GUI.mColor=[255, 255, 255, 88]
GUI.mText=kTxtAutoSave
ToggleButton.mListName=<ON_OFF>


Как видите все вполне понятно. Однако с 7 части формат скриптов стал бинарным и модифицировать его практически невозможно. Да и формат игровых архивов изменился значительно. Единственная утилита, работающая с ним это плагин для Total Commander - Game Archive UnPacker, но в случае с бинарными скриптами и от неё немного толку.

К сожалению, дальнейшие мои изыскания, так и не помогли мне найти, где именно включаются\отключаются субтитры. Однако нет худа без добра. В процессе отладки я нашел пару мест, в которых игра ищет оригинальный DVD. Делается это путем перебора всех доступных системе дисков через GetDriveTypeA, что в моем случае приводило к дребезжанию флоппи-дисковода при запуске игры. Огорченный невозможносью включить субтитры, я решил сделать хоть что-то полезное :) ... В итоге по результатам моего исследования, я сделал два патча, один из которых включает селектор языков, а второй отключает поиск дисков.  Забираем тут.

З.Ы. Английские субтитры всё таки возможны :) ... Для этого необходимо использовать no-DVD exe от японской версии, найти который можно на gamecopyworld.com. Однако его исследование затруднено из-за Securom'овского фарша внтури. Такое впечатление, что он был не снят, а заинлайнен.

З.З.Ы. Мои патчи поддерживают no-DVD для версии 1.2 от RAZOR1911 и для верcии 1.3 от V!TAL!TY. Японский exe не поддерживается, по причинам, указанным выше ...

From:
Anonymous
OpenID
Identity URL: 
User
Account name:
Password:
If you don't have an account you can create one now.
Subject:
HTML doesn't work in the subject.

Message:

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org


 
Notice: This account is set to log the IP addresses of people who comment anonymously.
Links will be displayed as unclickable URLs to help prevent spam.

October 2017

M T W T F S S
      1
234 5 67 8
910 11 1213 1415
161718 19202122
23242526272829
3031     

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Monday, 23 October 2017 11:47
Powered by Dreamwidth Studios