Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detecting GameMaker #40

Open
YellowAfterlife opened this issue Aug 9, 2021 · 13 comments
Open

Detecting GameMaker #40

YellowAfterlife opened this issue Aug 9, 2021 · 13 comments

Comments

@YellowAfterlife
Copy link

YellowAfterlife commented Aug 9, 2021

Currently there are plenty of false negatives for GM games, which is attributed to the following factors:

  • GMS1..GMS2.2 (or so) games compiled with YYC would embed data.win file into the executable as a resource instead of keeping it external.
  • snd_* naming convention is non-obligatory - mus_ is also common, as is camelCase/PascalCase. And some games might not have external audio at all! (it's a thing you tick a checkbox for on sounds)
    In a way I also personally made the matters worse due to releasing a tool that rewrites audio file paths and moves them to a sub-directory
  • GMS1 had an option to use a compressor (cabinet extractor IIRC) to pack everything into one large executable.
  • Pre-GMS1 games are hard to detect since there was always a single executable.
    Since almost all games would resort to using at least one DLL for specific features, collecting legacy DLL names from GMToolbox could help, but would take a while.
    Binary signature detection is also problematic.
  • options.ini is not required for the game to run so some people would delete it

Suggestions:

  • game.unx and game.ios are Linux/Mac versions of data.win
  • Furthermore, OSX builds will contain libYoYoGamepad.dylib for concrete results.
  • runner (+x) + run.sh + lib/libsteam_api.so + assets is a good tell of a GM Linux build that has not been customized
  • audiogroup<index>.dat are packages of audio files to be loaded on-demand and can be a good tell.
    These are always labelled sequentially starting at 1, so audiogroup1.dat, audiogroup2.dat, and so on.
  • D3DX9_43.dll without D3DCompiler_43.dll can be a good hint of GMS1 YYC game given presence of other evidence.
  • If you can afford to: see if the depot contains a single executable and try extracting it via 7z e that.exe.
    This would also fix some other false negatives with games that used self-extracting executables.
  • If you can afford to, scan the executable bytes for FORM <any 4 bytes> GEN8 - this is a tell of a data.win file embedded into the executable.
    image
    (pictured: Cavern Kings' executable)
  • Checking for GameMaker-specific DLLs could help:
    • CleanMem.dll: this thing.
    • Steamworks.gmk.dll: my Steamworks wrapper for pre-GMS1 GameMaker versions (as far as I can tell, adds a couple games)
    • Steamworks.gml.dll: my Steamworks helper for current GameMaker versions
    • GOG.gml.dll: my GOG wrapper
    • joydll.dll + SDL.dll: a DLL for SDL-based gamepad support
    • GMS-WinDev.dll: an ancient DLL of mine with Windows-specific curiosities.
    • Apollo.dll: my Lua wrapper. Might be worth combining with other evidence since the name is generic enough.
    • gmlive-server.exe: the local server from my live-coding extension. You are not supposed to ship it to the end user, but people sometimes forget.
    • geon_fx: a folder with bits from Geon FX particle editor. Similarly, you are not supposed to distribute it to the end user, but guess what
    • display_mouse_lock.dll: a native mouselock extension of mine.
    • window_set_cursor.dll: an extension for native cursors by me.
    • rousrDissonance.dll: a Discord Rich Presence wrapper extension.
    • window_frame.dll: an extension of mine that prevents the game from getting frozen in an event loop while resized... and causes a handful
    • catch_error.dll: an extension of mine that monkey-patches exception handling and crash reports into versions of GameMaker that didn't have those.

Some false-negatives:

  • Caveblazers: no .win, no options, camelCase sounds - needs .exe scan
  • Circuit Breakers: self-extracting executable on Windows, but Mac version is easily detectable
  • Witchinour: no .win, no sounds, but has display_mouse_lock.
  • Cavern Kings: self-extracting executable, no .win, music_-prefixed OGGs
  • Devolver Bootleg: no options, no sounds - needs .exe scan
  • Downwell: self-extracting executable
  • Duke of Defense: no options, no sounds, has rousrDissonance.dll
  • Ghost Croquet: no .win, custom sound names, Steamworks.gml.dll
  • Gun Done: also a self-extracting executable
  • Heat Signature: no .win, custom sound names - needs .exe scan
  • INK: a self-extracting executable
  • Last Horizon: a self-extracting executable, no .win, no options, custom sound names - needs .exe scan
  • Momodora III: no .win, no options, but has CleanMem.dll
  • Momodora RUtM: same author, same deal
  • Nidhogg 2: no .win, custom sound names, Steamworks.gml.dll, audio groups.
  • Nuclear Throne: no .win, custom sound names, a whole lot of my DLLs (because I extensively worked on this game)
  • Pilot Unknown: no options, no sounds, window_set_cursor.dll
  • Pixel Beef Battle: no options, no sounds, geon_fx folder
  • Prime Mover: no .win, no options, no sounds, window_set_cursor.dll
  • Samurai Gunn: no options, custom sound names, joydll.dll
  • ROFLNAUTS in Awesomenauts: the mini-game is made in GameMaker and spots joydll.dll... but what should SteamDB do if a game uses multiple engines as result?
  • Super Mutant Alien Assault: a self-extracting executable
  • Taco Gun: no options or sounds, but has audiogroup#.dat
  • Wild Glory: no .win or options, but has audiogroup#.dat.
@larsiusprime
Copy link
Collaborator

Thanks very much for these suggestions!

@larsiusprime
Copy link
Collaborator

For context -- our limitations is that we've only got filenames to operate off of, so we can't scan for file content. We can check file counts and do some complex logic if necessary, but we prefer to do keep things simple if we can. We also prefer to accept some amount of false negatives if it means avoiding false positives, but the ideal is of course identifying as many games as possible correctly.

I will be mining this helpful comment for some time to see if we can improve GameMaker detection.

@larsiusprime
Copy link
Collaborator

What does this mean?

runner (+x) + run.sh + lib/libsteam_api.so + assets is a good tell of a GM Linux build that has not been customized

@larsiusprime
Copy link
Collaborator

Is gm7zip.dll a common game maker file?

@larsiusprime
Copy link
Collaborator

And what about GMXInput.dll? I found it in Hotline: Miami, but I don't know if that game has been rewritten to not be in Game Maker any more or not.

@larsiusprime
Copy link
Collaborator

Also .gmspr and .gmbck, you seen these before? They seem to appear in some Game Maker games in my test set.

@larsiusprime
Copy link
Collaborator

I added some new rules based on your suggestions. I am unable to scan executables, and we had to remove folder names because of lots of false positives and other ambiguity in other areas, but hopefully this catches a whole lot more of them. The ones I remain unable to detect seem to be standalone executables with extremely generic files.

mus_ and music_ prefix on ogg files turns out to be too generic to take as a sign of game maker games, because it's used all over the place, though snd_ along with other hints can be narrowed down to game maker games.

@YellowAfterlife
Copy link
Author

YellowAfterlife commented Aug 11, 2021

What does this mean?

runner (+x) + run.sh + lib/libsteam_api.so + assets is a good tell of a GM Linux build that has not been customized

A common Linux build of a GameMaker game will contain the following:

  • runner (extension-less binary with "can execute" permission)
  • run.sh (shell script to run the said binary)
  • assets (directory containing the game assets)

For context -- our limitations is that we've only got filenames to operate off of, so we can't scan for file content. We can check file counts and do some complex logic if necessary, but we prefer to do keep things simple if we can. We also prefer to accept some amount of false negatives if it means avoiding false positives, but the ideal is of course identifying as many games as possible correctly.

That makes sense. I think this would mostly yield a small number of false-negatives for games that only have a single Windows depot with a self-extracting executable.

Is gm7zip.dll a common game maker file?

That's a very old (2008?) 7-zip wrapper for GameMaker, yeah.

And what about GMXInput.dll? I found it in Hotline: Miami, but I don't know if that game has been rewritten to not be in Game Maker any more or not.

I'm not aware of this one, might be custom for it - the rewrite had a lot of tricks.

Also .gmspr and .gmbck, you seen these before? They seem to appear in some Game Maker games in my test set.

In old versions of GameMaker you used to be able to export sprites and backgrounds to these, which are essentially just zlib-compressed metadata + RBGA bytes, and load them in-game. They would be a sign of GM as well.

@larsiusprime
Copy link
Collaborator

Okay, so I added a few more tests. Let's see how many false negatives we're left with after this and then we'll reevaluate. Thanks for your help, as always.

@larsiusprime
Copy link
Collaborator

joydll.dll causes a false positive match for Awesomenauts and likely others, so I'm going to remove that rule.

@YellowAfterlife
Copy link
Author

As per my comment, it causes a false positive match for Awesomenauts since the (non-GameMaker) game contains a GameMaker mini-game in one of the subdirectories.

@larsiusprime
Copy link
Collaborator

oh, gotcha! Then that's acceptable, actually. Because that's valid in our eyes. The app contains a gamemaker game.

@larsiusprime
Copy link
Collaborator

When we have multiple game engines in one app we just list all the technologies we detected. It only gets ambiguous when you have a game with a custom engine (and thus no other obvious engine) that also matches like a minigame or something, it can falsely imply the whole game is made in that engine.... hmmm. I'll think about this but for now I'll allow it until I have a better idea.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants