Transformers: War for Cybertron [Engine:Unreal 3 v3428]

Upload your cheat tables here (No requests)
Post Reply
User avatar
SunBeam
Administration
Administration
Posts: 4932
Joined: Sun Feb 04, 2018 7:16 pm
Reputation: 4630

Transformers: War for Cybertron [Engine:Unreal 3 v3428]

Post by SunBeam »

Kindly DO NOT POST this table on other forums/communities (e.g.: Nexus, OCD) without explicit approval. Same as you prefer those places, I prefer FRF and I have created these tools specifically for this community. If you want to spread the news and let others enjoy all of this, then please link them to this topic. I'd also appreciate if you didn't merge my table with other people's without asking for permission up front. Crediting the author does not account for approval. Thank you for respecting my choice!

Game Name: Transformers: War for Cybertron
Game Vendor: Steam [delisted/unavailable]
Game Variant: MULTi6-PROPHET [ovagames.com]
Game Process: TWFC.exe

Image
(I've designed the above widget myself based on Steam's model; e.g.: [Link])

Hello folks.

Been busy studying and learning more about Unreal Engine 3 and its internals. While at it, a patron of mine asked whether or not I'd be interested in looking into this game. Since I was busy with Styx: Master of Shadows (table to be posted later), yet another UE3 title, I decided to give this one too a go.

I've learned quite a lot, this game being the FIRST one I've seen that uses UE3 without UnrealScript-ing :) All of the UE3 UFunctions are streamlined in the executable, exactly as it happens in UE4 today (e.g.: UCheatManager::God -- the function run when you type 'god' in the console -- in UE3 is an UnrealScript executed bytecode stream; not in UE4 and definitely not in this game). So all of it is static cpp code, no bytecode VM running of any compiled UnrealScript.

- - - - - - -

FNames/UObjects Dumper

Took me a bit to understand the UObject model to be able to properly build a dumper, so without any further ado, here it is:

TWFC_Dumper.zip
password: sunbeam
(68.59 KiB) Downloaded 128 times

Extract xinput1_3.dll to your Binaries folder (e.g.: F:\Games\Transformers - War for Cybertron\Binaries). Once in-game, press >> Numpad / << key and two text files will be created in same folder: NamesDump.txt and ObjectsDump.txt. They look like this:

Image

And they contain this kind of information:

Image

I've explained in quite a few topics now, both UE3 and UE4 oriented, how one can make use of these dumps.

A few details about this UE3 version's internals:
  • UObjects -> the Index is located at offset 0x4 and it's read like this:

    Code: Select all

    char *UObject::GetName()
    {
        int idx = this->Name.Index >> 0xE;              <<-- here
        if( idx > 0 || idx < FName::Names()->Count )
        {
            return FName::Names()->Data[idx]->ToAnsiString();
        }
    
        return "INVALID NAME INDEX";
    }
    
  • xProperty UObjects (x = Bool, Int, Float, Object, etc.) -> the position offset of the property in an UObject is stored at offset 0x30 in the xProperty memory block; and it's read like this:

    Code: Select all

    116C7F5F | 8B41 30    | MOV EAX,DWORD PTR DS:[ECX+30] <<
    116C7F62 | C1E8 14    | SHR EAX,14                    <<
    
    function getOffset( p )
      return readInteger( p + 0x30 ) >> 0x14
    end
    
    Similarly, the toggle flag (for BoolProperty, for example) is stored at offset 0x40:

    Code: Select all

    116C1062 | 8B57 40    | MOV EDX,DWORD PTR DS:[EDI+40] <<
    116C1065 | 8511       | TEST DWORD PTR DS:[ECX],EDX
    
    function getFlags( p )
      return readInteger( p + 0x40 )
    end
    
  • UFunctions -> the exec function is stored at 0x68 offset in the UFunction memory block
  • FNames -> are stored as UNICODE
- - - - - - -

Special K

Looks like the concept of "borderless window" didn't exist at the time this game was released. Or if it did, either devs didn't implement it or UE3 didn't support it natively. You can play the game in a window if you press Alt+Enter keys, but the game doesn't remember this state and it will always start in exclusive full-screen, after which you will have to press the keys. Every. Damn. Time.

Enter Special K -> [Link].

At the time of writing this post the latest version is 22.9.26: [Link].

With the help of this tool you can send the game in borderless windowed mode via hooking. I found it very useful with old DX9 games with zero windowed-mode support.

Image

Note that I have manually added the game to the list and used Set Custom Artwork to set the background (downloaded from [Link]). Just in case it's not clear what DELISTED means: the game is not available on Steam anymore, ergo any information about it stored in some database won't show up in listings.

And this is how it behaves in-game:

Image

Image

- - - - - - -

Cheat Table

With the help of the dumper above, I was able to map quite a bit of game objects in this UE3 version (v3428, by the way):

Image

TWFC.CT
1.0
(127.97 KiB) Downloaded 167 times

The several scripts in the table:
  • God Mode
    Will toggle a 0/1 flag on disable/enable which in turn flips the bGodMode flag in PlayerController UObject ([ Debug ] > GEngine > [0350] GamePlayers > [0000] LocalPlayer > [002C] PlayerController > [01D8] bGodMode). Effect: god mode for your player. Note that some scripted events might still kill you. If you leave the script enabled, you don't need to disable/enable it when transitioning to other maps or reloading. The hook in FViewport::Draw I use -- activated by [ Initialize ] script -- makes sure to re-enable the flag on transitions. Why? The Engine re-initializes UObjects so the default state of bGodMode becomes off.
  • Unlimited Ammo
    Will toggle a 0/1 flag on disable/enable which in turn flips the HasUnlimitedAmmo flag in PlayerController UObject ([ Debug ] > GEngine > [0350] GamePlayers > [0000] LocalPlayer > [002C] PlayerController > [0300] AcknowledgedPawn > [04B8] HasUnlimitedAmmo). Effect: unlimited ammo for your player's weapons. If you leave the script enabled, you don't need to disable/enable it when transitioning to other maps or reloading. The hook in FViewport::Draw I use -- activated by [ Initialize ] script -- makes sure to re-enable the flag on transitions. Why? The Engine re-initializes UObjects so the default state of HasUnlimitedAmmo becomes off.
  • Set Weapon Properties
    Will tamper with several default parameters of the Weapon templates:
    • disable camera recoil [FovAdjustment, PitchAdjustmentDeg, RecoilTime, RecoilDelay]
    • kill camera shake [Intensity, Roll, RollFalloffDuration, ShakeFalloffDuration]
    • eliminate spread [Modifier[], ModifierChangePerShot, Cooldown]
    • adjust shots to fire [NumShotsToFire]
    • turn the weapons into automatic and enable unlimited ammo (you will see the symbol in-game for ammo) [bHasUnlimitedReserveAmmo(1)|bAutoReload(2)|bAutoFire(4)]
    • adjust fire rate [FireIntervalLerper{StartValue, EndValue, RampTime, CurTime}]
    You can always change these elements in the script by right-clicking it > Change script > edit your stuff > OK.

    I've also set a hotkey for it -- Numpad 7 -- which you can use to run the script. This can also be changed by right-clicking the script > Set/Change hotkeys > click the line with my key > Edit Hotkey > set yours > Apply > OK.

    Note that by design the script won't set an [X] in the box next to its name in CE GUI. It's designed to do its stuff and error, so it doesn't become active. Why? Cuz then you would have to disable/re-enable it every time you want to use it, which makes no sense.

    You will have to run the script every time you pick-up a NEW weapon during a level you're playing, every time you swap weapons with others lying on the ground or if you exit game/re-enter it. In general, if you don't see the crosshair reticle collapsed to maximum or your weapon isn't firing automatically (as you keep Mouse 1 down), then you will need to re-press Numpad 7 to re-run the script.
- - - - - - -

Goodies

1) staticFindObjectEx

The cheat table comes with a Lua function which makes use of internal UE3 functions I've found and labeled. Such as this staticFindObjectEx:

Code: Select all

function staticFindObjectEx( sa, sb, sc )
  local StaticFindObject = getAddressSafe( "_StaticFindObject" )
  if StaticFindObject == 0x0 then return 0 end
  local Class, InOuter, UObject = 0, 0, 0
  if sb == nil and sc == nil then
    UObject = executeCodeEx( 1, nil, StaticFindObject, 0, -1, {type=4;value=sa}, 1 )
  elseif sc == nil then
    Class = executeCodeEx( 1, nil, StaticFindObject, 0, -1, {type=4;value=sa}, 1 )
    UObject = executeCodeEx( 1, nil, StaticFindObject, Class, -1, {type=4;value=sb}, 0 )
  else
    Class = executeCodeEx( 1, nil, StaticFindObject, 0, -1, {type=4;value=sa}, 1 )
    InOuter = executeCodeEx( 1, nil, StaticFindObject, 0, -1, {type=4;value=sb}, 1 )
    UObject = executeCodeEx( 1, nil, StaticFindObject, Class, InOuter, {type=4;value=sc}, 0 )
  end
  return UObject
end
What you can do with it is tp search for UObjects' addresses. If you open up the Lua Engine (Ctrl+Alt+Shift+L) and paste this code in:

Code: Select all

local t = staticFindObjectEx( "ObjectProperty", "Engine.Controller", "Pawn" )
if t < 1 then stopExec( "'Pawn' ObjectProperty not found." ) end
printf( "%X", t )
Hit Execute button and you will see it returns an address. If you copy this address and search for it in ObjectsDump.txt, you will see it matches what you looked for. The staticFindObjectEx accepts 1, 2 or 3 string parameters. It unfortunately won't find suffixed UObjects. So, for example, if you wanna find "GameEngine Transient.GameEngine", you won't be able to. Why? Because it's stored like this: "GameEngine Transient.GameEngine_1154". And at the time of your query, you won't know the _xxxx suffix. If you do search with the suffix, it will be found.

Code: Select all

local t = staticFindObjectEx( "Engine.GameEngine", "Transient.GameEngine" )
if t < 1 then stopExec( "'Pawn' ObjectProperty not found." ) end
printf( "%X", t ) --> error

local t = staticFindObjectEx( "Engine.GameEngine", "Transient.GameEngine_1154" )
if t < 1 then stopExec( "'Pawn' ObjectProperty not found." ) end
printf( "%X", t ) --> valid
2) getOffset, getLocalPlayer, getPlayerController, getPlayerPawn

These are used to obtain the UProperty offset of a Bool, Int, Float, etc. Property. The rest are to get the LocalPlayer, PlayerController and PlayerPawn memory addresses. You can see how they're used in Set Weapon Properties script.

3) mapped debug symbols

With the help of some leaked UE3 source code and binaries with debug symbols, I was able to map quite a lot of functions in this game. Wasn't easy, as the compilers are different between the builds (TWFC uses VC8/9 while my binaries were all VS2013+). To be able to use these you will need x64dbg: [Link].

Linked the current .exe/.dll so they stay here for posterity.

TWFC binaries ('Large Address Aware' flag applied): [Link]
(password: sunbeam)

TWFC x32dbg database: [Link]
(no password)

How to use, simple:
  • get [Link]
  • extract/move the .dd32 file to '\x64dbg\x32\db' folder
  • run the game
  • attach to TWFC.exe
  • done
Once attached, open the Labels pane and you'll see over 406 names there:

Image

Note that I can't hold your hand while you learn how to use x32dbg, so "my game crashes", "I can't attach", "I don't understand how to do it" etc. are not my concern. The intention here is to provide a helping hand to people wanting to reverse more of this game, not to teach you how to use a debugger. If you have zero knowledge in this regard, maybe you want to ignore this for now; till you get interested, learn a bit, then return here.

The database contains mappings up to what I've - once more, manually - mapped so far. It's not complete by far, you will find CALLs (functions) that have no names/labels still, but a lot of them should make sense once you start debugging.

Enjoy and best regards,
Sun

How to use this cheat table?
  1. Install Cheat Engine
  2. Double-click the .CT file in order to open it.
  3. Click the PC icon in Cheat Engine in order to select the game process.
  4. Keep the list.
  5. Activate the trainer options by checking boxes or setting values from 0 to 1

Post Reply

Who is online

Users browsing this forum: admantx, AhrefsBot, Google Adsense [Bot], Majestic-12 [Bot], MAKROZ, oracular, sbpham1995