Skip to content

SecuROM

widberg edited this page Jul 1, 2024 · 21 revisions

FUEL uses SecuROM DRM.

Active Security Checks

FUEL verifies that the game was launched using SecuLauncher.exe by checking for a memory-mapped file that SecuLauncher.exe creates before launching the FUEL.exe process.

Upon launching, the game attempts to OpenFileMappingW the file -=[SMS_%s_SMS]=- where %s is replaced with the game executable name FUEL.exe to yield the final name -=[SMS_FUEL.exe_SMS]=-. It will then MapViewOfFile and read 0x4C bytes from this memory mapped file into the beginning of a buffer containing a struct. The members of this struct are later used as arguments to SendMessageA in several places. This behavior is known as a "spot check." The Tron: Evolution Mod Documentation on SecuROM has more information about spot checks.

In this buffer, the DWORD at offset 0x4 represents a hWnd, the DWORD at offset 0x10 represents a Msg, and the DWORD at offset 0x4C represents an lParam. Notably the lParam member is not copied from the memory-mapped file; instead, it is set to 0x0 before the calls to SendMessageA. Following the lParam member of the buffer, there are two additional members that are not used as arguments to SendMessageA but are set before each call to the function. The DWORD immediately following the lParam member is always set to 100. Following that is another DWORD which is always set to a pointer to a byte allocated on the stack. Neither of these two members are ever accessed outside of this. No other data in the structure is accessed. The return value of SendMessageA is always ignored.

SendMessageA Call Location
WinPopup_Z Setup
Registry/config.opt Access
WinSound_Z Setup
D3D_Renderer_Z Setup
WinInput_Z Setup
Registry Setup
SDX Setup - No References
WinMovie_Z Setup

Patching this check out of the game will trigger Games for Windows Live's integrity check and exit the game with an error message. This can be circumvented by also patching the integrity check out of xlive.dll, see the XLive entry.

It is surprisingly easy to launch the game without SecuLauncher.exe by returning from the function in the game that does this memory-mapped file check with a value of 1. One might expect more stringent copy protection that is less easily defeated. It's odd how the game is seemingly doing everything except actually running the spot checks.

Anti-Disassembly

An anti-disassembly byte pattern appears after the prologue and before the epilogue of some functions called early in the game from WinMain. This pattern is { 0x4D, 0x61, 0x30, 0x57, 0x79, 0x47, 0x31, 0x6B, 0x6D, x, y, 0x00, 0x00, 0x00 } which disassembles to

dec     ebp
popa
xor     [edi+79h], dl
inc     edi
xor     [ebx+6Dh], ebp
db    x
db    y
db    0
db    0
db    0

Where x is 0x21 for the prologue junk and 0x22 for the epilogue junk and y is unique per function, 0 through 9 inclusive are used in the game although 8 is missing the epilogue junk and 6 is missing completely. This variance makes it slightly harder to search for the pattern in the disassembly.

This junk code is meant to throw off liner disassembler state tracking by messing with the base pointer, changing register states, doing weird memory access, and including invalid instructions. Before the pattern, there is always a jump instruction that lands directly after the pattern, so the junk never runs. This trick incurs a minor performance cost due to the extra jump instruction and filling up instruction cache space with junk which is why it is used sparingly in functions that only run once at startup.

I assume SecuROM provides a macro to use in "important" functions to provide an extra layer of protection against linear disassembly. I am not certain that this comes from SecuROM, but it is DRM related so I'll include it here. A point in favor of this being from SecuROM is that earlier games like Ratatouille and WALL-E do not include this pattern.

I have created an equivalent macro

#define INSERT_JUNK(x, y)                     \
    __asm {_emit 0xEB} /*jmp $+0x10*/         \
    __asm {_emit 0x0E}                        \
    __asm {_emit 0x4D} /*dec ebp*/            \
    __asm {_emit 0x61} /*popa*/               \
    __asm {_emit 0x30} /*xor [edi+79h], dl*/  \
    __asm {_emit 0x57}                        \
    __asm {_emit 0x79}                        \
    __asm {_emit 0x47} /*inc edi*/            \
    __asm {_emit 0x31} /*xor [ebx+6Dh], ebp*/ \
    __asm {_emit 0x6B}                        \
    __asm {_emit 0x6D}                        \
    __asm {_emit x}    /*db x*/               \
    __asm {_emit y}    /*db y*/               \
    __asm {_emit 0x00} /*db 0*/               \
    __asm {_emit 0x00} /*db 0*/               \
    __asm {_emit 0x00} /*db 0*/
#define INSERT_JUNK_PROLOGUE(y) INSERT_JUNK(0x21, y)
#define INSERT_JUNK_EPILOGUE(y) INSERT_JUNK(0x22, y)

and put together a playground on godbolt.org to experiment. And an IDA Python script to locate, comment, and log all occurrences of this pattern. You can read more about anti-disassembly in the Anti-Disassembly chapter of Practical Malware Analysis.

SecuROM Version

Detect It Easy claims "Protector: SecuROM(pre-8.03.03)[-]" on SecuLauncher.exe. The PE/SecuROM.2.sg signature file says that this version is attributed to PE's with a .securom section. Some strings that could hint at the version number are "securom_v7_01datasecu", "securom_v7_01rkeysecu", "UserData\securom_v7_01.tmp", "UserData\securom_v7_01.dat", "UserData\securom_v7_01.bak", "E:\vfdev-SecuROM-DRM_7_40\SecuROM_DRM\Wrapper\wrapper.pdb", and "SecuROM User Access Service (V7)". So it's clearly SecuROM 7.xx, where xx is either 01 or 40, I'm leaning 40 because of the pdb path.

SecuROM 7.xx complete crack manual

SecuROM has a support FAQ for FUEL: https://support.securom.com/pop_fuel.html

See also: dfe

Home
FAQ

For FMTK Users and Mod Developers

Read the Docs

For FMTK Developers

Asobo BigFile Format Specification
Asobo Classes
      Animation_Z
      Binary_Z
      Bitmap_Z
      Camera_Z
      CollisionVol_Z
      Fonts_Z
      GameObj_Z
      GenWorld_Z
      GwRoad_Z
      Keyframer*_Z
      Light_Z
      LightData_Z
      Lod_Z
      LodData_Z
      Material_Z
      MaterialAnim_Z
      MaterialObj_Z
      Mesh_Z
      MeshData_Z
      Node_Z
      Omni_Z
      Particles_Z
      ParticlesData_Z
      RotShape_Z
      RotShapeData_Z
      Rtc_Z
      Skel_Z
      Skin_Z
      Sound_Z
      Spline_Z
      SplineGraph_Z
      Surface_Z
      SurfaceDatas_Z
      UserDefine_Z
      Warp_Z
      World_Z
      WorldRef_Z
Asobo File Format Idioms
Asobo CRC32
Asobo LZ Compression
Asobo Arithmetic Coding Compression
Asobo Save Game File Format Specification
Asobo Audio Formats
TotemTech/ToonTech/Zouna/ACE/BSSTech/Opal Timeline
Zouna Modding Resources
Miscellaneous

Clone this wiki locally