Wouldn't it be great if there was a way to filter through functions that have been called vs. ones that haven't, such that you could weed out the thousands of useless function calls and hone in on one of interest? Lucky for us, you can do such a thing!
Buried in Cheat Engine is an incredibly powerful tool called Ultimap (as well as its successor, Ultimap 2). It's CPU-dependent, unfortunately, so if you're not running an Intel processor, then you're out of luck (but don't stop reading if that's the case; I mention a few other things in this answer).
Ultimap and Ultimap 2 (in Cheat Engine's main window, click the Memory view
button -> Tools
-> Ultimap
or Ultimap 2
) are functionally the same, but operate in very different ways. I made a video on Ultimap awhile back, so I encourage you to watch it since there's a lot to it. There's another video by someone else that does a great job of explaining Ultimap as well, which you may find of use.
Ultimap 2 doesn't need DBVM to work (which is fantastic), but you do need to be on a current-gen Intel CPU since Intel PT is the crux of Ultimap 2 working.
That aside, CDA (aka FunctionHacker), goes about filtering function calls in a different (and awesome, timeline-based) way, but only works with 32-bit applications. Here is an excellent video on how to use it, made by the guy who created the program.
I suspect there's also a way to use Frida to discover and filter function calls, but I'm not well-versed enough with it yet to know if it's feasible or not, so this may or may not be worth the mention.
Past that, you can try enumerating DLLs/symbols via Cheat Engine to find meaningful symbol names with which to explore. In Cheat Engine's main window, click the Memory view
button -> View
-> Enumerate DLL's and Symbols
, and then see what you see. I've also done a video on that topic which you can find here if you'd like to see it in action.
Lastly, there's the direction it sounds like you were headed in, except you may now need to now utilize back-tracing. Click here to read my answer to another question, in which I detail exactly what can do to trace your way up through the CALL
chain, of which you can try brute-forcing your way up through to find the primary caller (after you do a trace, go to each caller up the chain, NOP the CALL
and possibly anything pushed to the stack that might unbalance it farther down, see what happens; rinse and repeat). Also consider what I mention in that answer about utilizing the Dissect Code
feature of Cheat Engine, by which you can find xrefs, strings, functions, etc. to explore!
Some games can be a bear with what you're trying to do, as pausing can be controlled by many different mechanisms (functions, threads, etc.). If you can find a boolean within a byte that completely controls pausing, great! If you can find a string from the menu, then back-trace from there to ultimately find when/where the menu is drawn and game is paused, awesome! But just be aware that you might be going down a rabbit hole that requires you to handle multiple function calls, memory addresses, and much more. Good luck!