Hi everybody,

I just started to reverse engineer Mafia 3 and wanted to share all information of myself with you guys. Also if you want you can also post your information and reversed stuff.

So far Mafia 3 seems to be based on Mafia 2’s codebase. A lot of Strings, Functions, Function calls (hierachy) and xrefs are equal to Mafia2’s (except Mafia3’s running on x64, not like Mafia 2 on x86).

I’m currently trying to port Gibbets Mafia 2 tool (http://svn.gib.me/public/illusion/trunk/) to Mafia 3, so far it’s looking good (and promising), it seems that the SDS base structure (platform, version, XML etc.) hasn’t really changed. The version got incremented from 19 to 20. I’m current reversing the TEA keys of Mafia 3 at the moment.

In case you also want to reverse engineer Mafia 3, you need to dump the executable. From my point of view Denuvo got used in the shipped executable (A lot of jumps inside the codebase, my experience tells me that it’s Denuvo because the same structure appeared on previous reverse engineering projects (e.g. GTA5)). So in order to dump it, open the executable, as soon as you’re in singleplayer (spawned), go to Desktop and run Scylla x64 (https://github.com/NtQuery/Scylla/releases). Simply press dump and you get a (nearly) decrypted executable which is ready to be loaded into IDA.

Update

Used libraries(dependencies): Havok, wWise

Used LUA versions seems to be 5.2.1 (at least in havok)

Weather Sets: “SUNNY”, “PARTLY_CLOUDY”, “CLOUDY”, “LIGHT_RAINY”, “RAINY”, “LIGHT_WINDY”, “WINDY”

Still they seem to be using LUA for scripting (same as in Mafia 2).

When looking deeper into scripting (let’s take SetTime function), we can see that the function itself has lua calls inside.

Looking even deeper, you can see that Mafia 2 and Mafia 3’s script engine system has some similarities. (Don’t mind the //get top , the compiler just inlined the function (compile config, compiler version etc. caused this))

Update 8.10

If you want to patch loading screens, simply patch these bytes on the following address:

Bytes: 0xB000C3 (ASM code: mov al(B0), 0(00); retn(C3);) Note: If you patch the address directly, don't forget to write bytecode in reverse order, so it's 0xC300B0

Address: 0x0000000143850B30 (Imagebase 0x140000000, so ImgBase + 0x3850B30)

Furthermore here is a list of class instances (Imagebase is 0x140000000)

Name Address Description VAR_C_GameScriptModule 0x00000001462F5ED8 To be done. VAR_C_GameCamera 0x000000014608C120 To be done. VAR_C_Game 0x00000001461E5828 To be done. VAR_C_FlowNodeLogicQuestEvaluateImpl 0x00000001461E6968 To be done. VAR_C_CityOwnersManager 0x00000001461E5A38 VAR_C_CharacterTable 0x00000001461E5898 VAR_C_ActorSubdivObj 0x00000001461E6008 M3Malloc 0x000000014293D770 Thread safe malloc inside Mafia 3

About hashing:

Mafia 3 is using the same hashing methods as Mafia 2. Used hash methods are fnv32 and fnv64. Screenshot attached below. (The reason the function body is inside the parent function is caused by the compiler (optimisations), who inline the function to improve performance (optimizations at compiletime))

About SDS structure:

In previous SDS version (Mafia 2, version 19), the SDS archive header contained a XML offset (also the XML content was not encrypted/encoded). In SDS version 20 (Mafia 3), XML offset seem to no longer exist (always 0), also the content seems to be encrypted / compressed.

At the time being, I’ m reversing the script engine in order we can create a scripthook and run own lua content. Instead of just hooking loadbuffer function, I’m reversing the whole Script Engine (so we can adjust everything). This are the base structure at the moment:

http://pastebin.com/xCfq7H94

Also here are the LUA function addresses (these are not the ones from HavokScript hksi, these are the plain Lua functions)