World is what you look in to find your local player, tables of entities, etc.
NetworkManager is what you look into find the scoreboard.
We’re going to take a look at some script functions in order to find those ‘base’ offsets for the two data structures everyone uses most.
Frequently Asked Questions:
|why don’t u just gief us offsets?|
Because then I get a million PMs every time there’s an update asking for them, and ain’t nobody got time for that.
|how come u not give us signature 2 find offsets|
Because then if a sig breaks guess what, I get a million PMs. And you won’t learn anything by putting a signature into IDA or some sig finding function you copied from the beginners section. This ain’t MPFag, hopefully everyone is here to LEARN so they can make their own stuff, not just copy pasta and leech.
OK so I did that because IDA was still analyzing the new beta patch executable and I didn’t just want to sit here. It’s done now so we can start.
You can get world in a LOT of places. You can just pop open the WinMain function and find it very easily by eye if you know where to look. I’m assuming you DON’T know where to look, so I’m using the most obvious place to look as an example. We’re going to look at the ‘player’ script function to find it. Do a text search for ‘This is the person controlled by’. That’s a portion of the description text of the ‘player’ script function. You will end up here:
|This image has been resized. Click this bar to view the full image. The original image is sized 941×434.|
So you see the script function name, ‘player’, the description, and an example. You see where it pushes the address of a function onto the stack (push offset sub_7a4d85)? That’s our script function. This function is building a structure that represents that script function to allow the script engine to find the script function and call it. So let’s look inside that function:
See DFCDD8? That’s the world pointer. It hasn’t changed. I said that but for some reason no one listened to me.
If you go to the function that the world pointer is passed to:
You can see the offset for realPlayer, 13B0.
|wtf BS why isnt it 13a8????/1|
13A8 is cameraOn. If you’re in a vehicle, cameraOn points to the vehicle. realPlayer always points to your…real player. So when you issue the ‘player’ script command, you get the realPlayer, not cameraOn.
|but my 7 pointer long offset chain returns 0 now so obviously this is wrong|
Open up Reclass and have a look at the data structures you are trying to read. To port my hack to the latest beta patch all I had to do was update the location of two functions I don’t sig scan for, and it worked fine IIRC. The reason your item spawners aren’t working is because the vtable for the magazine instance class you are building manually is in a different place now. Data section offsets haven’t changed that I’ve seen, and I also haven’t noticed any structure differences, but vtable/function offsets have definitely shifted.
Now, let’s get the networkManager. I always use selectPlayer for this, but any script function that sends information to the server will have the function to get the network manager in it. So let’s search for selectPlayer:
|This image has been resized. Click this bar to view the full image. The original image is sized 718×595.|
And let’s have a look inside
|This image has been resized. Click this bar to view the full image. The original image is sized 728×598.|
|oh crap this is freakin long how do i even x86 asm|
If you have hex rays, use it. If not, look for calls to registers (function pointer calls) and find one that comes from a VTable that is returned by a function that takes no parameters. Spoiler alert it’s this guy right here:
|This image has been resized. Click this bar to view the full image. The original image is sized 930×514.|
And what’s inside that function?
Your NetworkManager pointer, which has a pointer to the class with the scoreboard in it. And holy shit, the offset hasn’t changed omg!