Conversation

hey if any Fedi beings know about Windows #ReverseEngineering I’d love some advice or help!

I’m trying to figure out how the anti-save-scumming system for a game called Teleglitch works. here’s what I’ve figured out so far:

  • when you make a save, the game also secretly hides information about the save somewhere (the information seems to only consist of “the next save that the user loads should be for level XYZ” or “there should be no savefile. if there’s a savefile, it’s invalid”. all other edits to the savefile are accepted by the game as correct - including edits that instantly freeze the game)
  • when you try to load the save, the game compares the secret information with the information in the savefile. if the information doesn’t match, the savefile is considered invalid and the game refuses to load it
  • the savefile is stored in a Steam Cloud directory called C:\Program Files (x86)\Steam\userdata\«some numbers»\«more numbers»\remote
  • the secret information is definitely not stored in this directory (I made the whole thing into a git repo and used that to “rewind time” to make 100% sure)
  • the secret information is also not stored in the game’s directory (C:\Program Files (x86)\Steam\steamapps\common\TeleglitchDME) (same thing - I made it into a git repo)
  • I’ve checked every registry operation and every file I/O operation using Process Monitor but I’m 90% sure that Process Monitor is missing certain important things that Teleglitch is doing - maybe because it’s delegating tasks to {another process / a subprocess}? but Process Monitor can’t even see Teleglitch write to the Steam Cloud save directory mentioned above
  • I tried looking through the executable in Ghidra and the savefile code is definitely in there somewhere, and I’ve been able to kinda make sense of some of it, but I’m not very good with disassembly / decompilation. I’d love some help with this if anyone is interested. it looks like it was probably written in C++ and I’ve found some very good places in the executable to start looking for savefile behavior but I’m baffled by a lot of what I’m seeing - I think a lot of it was automatically added by the C++ compiler

anyway I would love some advice on what to try next. I’ve tried to summarize just the most important parts of what I know about Teleglitch’s behavior, but I can explain more if anyone is interested!

1
10
10

@kasdeya it's possible all save read/writes are going through steam using the ISteamRemoteStorage interface.

You may want to log steamworks API calls, this can be done by opening the console at steam://open/console then telling it to log IPC from there. iirc the command is something like log_ipc verbose but idk, see the help page and try some stuff.

2
0
1

@kasdeya if you want to see what data is actually sent to valve the main way of doing this is NetHook2 and NetHookAnalyzer2, both part of SteamKit. That probably won't actually be necessary for you though.

1
0
1

@kasdeya The steamworks SDK is a bit annoying, since it's all virtual C++ functions. There's two ways of getting an ISteamRemoteStorage instance: One involves the string STEAMREMOTESTORAGE_INTERFACE_VERSION, and the other calls a function on an ISteamClient instance, which will involve the string SteamClient0

If you search for those version strings you can figure out which version of the SDK it uses and therefore the struct layout. All the public versions of the SDK headers are in the Proton repo

0
0
1

@artemist omg thank you! this helped so much. this was actually the last piece of the puzzle that I needed. I was able to figure out exactly what’s going on, and I added the details to the savefile section of the PCGW article for Teleglitch if anyone is interested

0
0
0