Raised This Month: $12 Target: $400
 3% 

Offsets and signatures


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Chrissy
Member
Join Date: May 2013
Old 12-12-2019 , 13:45   Offsets and signatures
Reply With Quote #1

Good day,

I found this in one of my plugins and is something I'm unfamiliar with:

Code:
FindSendPropInfo("CCSPlayerResource", "m_bAlive")
I understand that server side properties are "netprops" and client side being "datamaps" but some of the property such as the above are used differently than just getting a value from the property using "GetEntProp".

Furthermore, I'm eager to learn the purpose of gamedata .txt files and their contents including offsets and signatures. I see some plugins come with their own gamedata files, so I believe I must be missing out somewhat.

Many thanks.
Chrissy is offline
Fyren
FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren
Join Date: Feb 2106
Old 12-12-2019 , 17:39   Re: Offsets and signatures
Reply With Quote #2

Quote:
Originally Posted by Chrissy View Post
I understand that server side properties are "netprops" and client side being "datamaps"
A simplified explanation of netprops is they're properties of C++ objects on the server that, when changed, get transmitted to clients so that the values stay in sync.

A simplified explanation of datamaps is they're properties of C++ objects on the server that get written/read when saves and loads happen.

Perhaps more relevant to people writing SM scripts is these properties end up being easily enumerated and accessed. For example, you only need to know the name of the class and property to get the value or modify it.

Quote:
Originally Posted by Chrissy View Post
but some of the property such as the above are used differently than just getting a value from the property using "GetEntProp".

Furthermore, I'm eager to learn the purpose of gamedata .txt files and their contents including offsets and signatures. I see some plugins come with their own gamedata files, so I believe I must be missing out somewhat.
As the docs for FindSendPropInfo say, it returns the offset of the property. If you know where the object is in memory, then adding the offset to it gets you the address of that particular property. A SM scripter should rarely actually need to use FindSendPropInfo, though. If the offset is being passed through to like GetEntData*, it's likely just GetEntProp* is the better choice.

To get a non-simplified/superficial/shortcut understanding of offets and signatures (what they are, how to find them, what SM is actually doing with them), the path is probably first learning C++, then some basic assembly, then some basic reverse engineering.
Fyren is offline
Chrissy
Member
Join Date: May 2013
Old 12-12-2019 , 18:19   Re: Offsets and signatures
Reply With Quote #3

Quote:
Originally Posted by Fyren View Post
A simplified explanation of netprops is they're properties of C++ objects on the server that, when changed, get transmitted to clients so that the values stay in sync.

A simplified explanation of datamaps is they're properties of C++ objects on the server that get written/read when saves and loads happen.

Perhaps more relevant to people writing SM scripts is these properties end up being easily enumerated and accessed. For example, you only need to know the name of the class and property to get the value or modify it.



As the docs for FindSendPropInfo say, it returns the offset of the property. If you know where the object is in memory, then adding the offset to it gets you the address of that particular property. A SM scripter should rarely actually need to use FindSendPropInfo, though. If the offset is being passed through to like GetEntData*, it's likely just GetEntProp* is the better choice.

To get a non-simplified/superficial/shortcut understanding of offets and signatures (what they are, how to find them, what SM is actually doing with them), the path is probably first learning C++, then some basic assembly, then some basic reverse engineering.
Amazing explanation, thank you! I just have a few questions, if that's cool.

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?

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.

Many thanks
Chrissy is offline
Fyren
FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren
Join Date: Feb 2106
Old 12-13-2019 , 16:09   Re: Offsets and signatures
Reply With Quote #4

Quote:
Originally Posted by Chrissy View Post
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 View Post
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.
Fyren is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 01:46.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode