fdh

How about those video games am I rite

Chrome Engine Games + Information

Last Updated: 16 November 2020

Contents


Early Chrome Engine

Nikita Tajemnica Skarbu Piratów (gonna be Nikita from now on) is the earliest Chrome Engine game that I own / care to own.
I imagine that its close enough to CE2 since according to Wikipedia, CE2 just added DX9 support

The .scr files follow a fairly simple format, its basically just a modifiable text file
Anything like !AddEndLevelMusic(...) or other function names declare a function, later on using the same functions to repeatedly declare certain variables etc
The .pak (with the exception of code.pak) are all just zip files, containing more files in themselves.
The code.pak file is actually a Java JAR (which in practice are just zips with compiled code but ssh)

Nikita Tajemnica Skarbu Piratów

This game uses Chrome Engine 2 which is basically just Chrome Engine 1 + DX9 support because technology

It more or less just has every asset you could ever want out in the open (ie the music is in Data/MUSIC)
The .scr files follow a fairly simple format, its basically just a modifiable text file
Anything like !AddEndLevelMusic(...) or other function names declare a function, later on using the same functions to repeatedly declare certain variables etc

Random Info:

Save Format (please don’t ask I was bored):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- 20 bytes: ???

- chunkID: little endian int32 
- chunkLength: le int32 (excluding size of int32)

- randomBool: bool (has to be True unless name = null)
- nameLength: short
- Player (Profile) Name [length of nameLength]

- Completed Levels: int32
- # of Hints (60): int32
	- # of Hints amount of bools (hint values in index): bool (byte)
- m_bMustCreateStartProfile: bool [always true]

- chunk2ID: le endian int32
- chunk2Length: le int32
	- subchunk1ID: le int32
	- subchunk1Length: le int32
	- inputSettings (until EOF):
		- deviceID: signed 32bit int

Call of Juarez 1

The .scr format is basically unchanged in between Chrome Engine 2 and CE 3 (this game)
There’s not much of a difference really between CE2/CE3, so I’ve got not much to add

As a note in terms of save files, this game uses both *.CoJSave, *.CoJSave.dat, and *.CoJSave.lev for the saves (and *.CoJSave.tga but those are just basic TGAs)

The .lev files are effectively just text files, not sure on their purpose/format
There’s nothing to really distinguish the player from others, its more or less just a serialized version of every property/object that’s being stored at the time of the save

The *.CoJSave and *.CoJSave.dat files are also just zip files, except they have only 1 file inside of them, that being data.

General data Format:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
- 12 bytes (???)

Repeat until EOF:
- Chunk ID: le int32
- Chunk Length: le int32
	ID 136:
		- Save Version Number: int32 (50050)
	ID 154 ("MODULE_TIME"):
		- fReadModuleTime: le float32
		- ???
	ID 151 ("SAVE_ADDINS"):
		- nNextIDValue: le int32
		- Other operations, see the source for more info
	ID 105 ("EXPRESSION_VAR_MAN"):
		- ???
	ID 103 ("Object"):
		- UniqueID: int32
		- ClassName: String (see Nikita)
		- ObjectName: String (^^^)
	ID 102 ("PRECREATE_OBJECT"):
		- ??? (Type of Object, gets pre-loaded?)
	ID 104 ("OBJECTS_REPOSITORY"):
		- sizeOfRepository: le int32
		- serializeableObject:
			- objectID: le int32
			- objectName: String (see Nikita name for how to handle Strings)
	ID 155 ("MARKER_END"):
		- markerPosition: Vector (figure this one out on your own for now)

Modification

This game’s JVM runs under Java version “1.4.2_10”:

1
2
3
java version "1.4.2_10"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_10-b03)
Java HotSpot(TM) Client VM (build 1.4.2_10-b03, mixed mode)

As output from [GAME ROOT]/jre/bin/java.exe -version

Later Chrome Engine

Call of Juarez: Gunslinger

This game (according to Wikipedia) uses Chrome Engine 5, which still basically functions the same way in effect
One of the big differences between this game and the past games is that this one’s *.pak files are encrypted
The *.pak files are still zip files but now they’ve got a password in them (they’re also Level 4 compressed)

Encryption

Luckily it uses the less secure ZIP2.0 form of encryption which has a 96-bit encryption key. Ironically using AES encryption probably would’ve been easier to rip out rather than needing to brute force it due to the tools available for it.

It also seems to have a DLL meant for game scripts, buuut I’ve got no idea how on earth it actually gets loaded
Its got a function called InitializeGameScriptDLL and ShutdownGameScriptDLL but they do some weird code magic that I’m yet to figure out
Annoyingly enough since the game comes with SteamStub based DRM, you’ll want to use Steamless by atom0s.

The password for the encrypted zip (*.pak) files is TN2kTjNmBvn5axaS6tGY

Just some random facts I learned from static analysis:

(I doubt that most of those args like -autostartlevel etc are actually called considering there’s no references to their functions in Ghidra but idk)

Modification

Now that “we” (meaning me but late to the party) can modify files in the “ZIP” files, they use a “custom” CRC for a checksum rather than a normal one that you can just open up into WinRAR etc.
Looking at Gibbed.Chrome by Gibbed you’ll notice that there’s a few errors in their hashing algorithm.
No real idea on what they are, hashing/cryptography kinda just isn’t my jam, but I still want to see how far into it I can get.
(One downside to Gibbed’s approach to modifying the pak files is that it doubles the file size of the .pak files :/)
So I got to setting that code up to be its own standalone class/namespace rather than a single command line program.
Now I’ve got a small program that takes a [original file] argument and a [modified directory] so that way it can get zipped up.

I started messing with the localization files first just because they’re an easier place to test than code modifications (and its just strings). These are stored in DataEn.pak, specifically mainly cotexts.bin


So uhhh it didn’t quite work, buuut the initial Press Any Key To Continue key did become HELP ME PLEASE

As it turns out, when I was saving the files in my code (since I was just writing it to a zip and then using Gibbed’s fix code),
I didn’t write any of it to a data/*.* but instead just *.*

Impressively though, the *.scr in the data/ directory which I was trying to edit, doesn’t actually control any of the text for some reason.
The text that’s localized in game is instead stored in the cotexts.bin (and the other .bin files too)

Pointlessly I created a python script to print them all out to a JSON dict, it’s on a Gist

Footnotes

Here’s your reminder that “western” styled content (ALMOST) always portrays a white washed viewpoint of history.
This is due to the television codes at the time in which westerns had a near monopoly on TV.
If you want more, please watch this video: https://www.youtube.com/watch?v=jzMFoNZeZm0
I’d like to mention the story line of CoJ: Bound in Blood, but I haven’t properly played it so I don’t have enough room to talk.