Quote:
Originally Posted by Chrissy
The in the case I supplied, CCSPlayerResource is a class and m_bAlive is a property within the class. And to get m_bAlive, you apply a specific offset to the memory address of the object that points to the memory address of the required property?
|
That's pretty much what needs to be done. Also going from an entity index to its actual address, usually.
In the case of CCSPlayerResource, in a script you should probably just do
GetEntProp(GetPlayerResourceEntity(), Prop_Send, "m_bAlive", _, client).
Quote:
Originally Posted by Chrissy
And in regards to gamedata files, is there a page I can read to learn more about how to utilise them? I read the wiki page but I didn't really understand where you're meant to find offsets/signatures/functions to put into a file.
|
The gamedata system itself is just meant to be a way to lookup things based on the game/engine/OS. You could just use it as like a general config file, too, I guess. The data can represent anything.
If you look at
https://github.com/alliedmodders/sou...ngine.csgo.txt for CSGO versus
https://github.com/alliedmodders/sou.../game.l4d2.txt for L4D2, you can see the structure is similar. The point is basically that if you looked up "Blocked", then you get back the right value depending on if your server is L4D2 on Windows versus 64-bit CSGO on Linux.
What that number actually represents is a vtable offset. The only actual requirement is that an "offset" is an integer. You'd really have to go look at sdkhooks to see what it's doing with the value to know.
To find the vtable offset for "Blocked", you'd want to know how inheritance and virtual functions work in C++, then also how virtual function lookup
actually works (via vtables in practice, but in theory the C++ standard doesn't require they work that way), then also how to poke around the server binary to locate the right function. If you have a non-stripped server binary (like if your game's Linux server isn't stripped or you have an old copy of the Linux CSGO server binary from before they stripped and the function existed then, this can be much easier).
But there are some tools like the vtable dumping script for IDA (somewhere in the SM repo) that will take a class name and will then spit out all the virtual functions of the class and their offsets if run on a non-stripped server binary.
Another random example might be the director in the L4D games. It's a game system that handles things like spawning zombies and game flow (difficulty/intensity and items). You might look through the function names in the Linux server and see there's one you want to try calling.
You need to get the actual instance of the director, but it's not an entity, so you can't look it up with an index or class name. Additionally, the address can potentially change every time you launch the server, so you can't directly hard code anything.
So you might find some other function in the server that uses the director, since it will also need to know the address. Then, you look at the assembly to see how it gets it. If you're lucky, basically somewhere in the server code there's a global variable pointing to the director (i.e.
Director** g_Director maybe) and the function you found is simply using it. At some point, the function must load the global and dereference it, so you find that specific load instruction. Then, you do some arithmetic to get an offset from the beginning of the function to the address that instruction loads.
With a signature to find the function, and the offset, then at runtime you can locate the director: look up the function, add the offset, read that resulting address, then finally dereference it.
In general, though, this kind of thing usually involves using a debugger or something more aimed at reverse engineering or static analysis (like IDA) to investigate.