ThanosSiopoudis/FMScoutFramework

Latest version offsets/addresses

joshlit opened this issue · 26 comments

Hey, thanks for this project.

The other day SI updated the game which means this framework no longer works, is there an easy way to find the new addresses?

Mac or Windows Josh?

Hi @joshlatimer,
I can help with Mac & Linux offsets.

@jaymarvels would you be able to add the Windows offsets?

@ThanosSiopoudis how much has changed, main offsets or a lot?.Think you mention a lot has changed?

@jaymarvels That would be the main offset, main date offset, Player object length, Player/Staff object length, Player offsets, all encryption algorithms, ClubInfoOne offsets, ClubInfoTwo offsets..

I can go on :)
But at least if you manage to get the main offset and the main date offset, the rest should be more or less the same.

@ThanosSiopoudis Lol...yuk...those are the ones I hate the most ;-)

Loads has changed...grr

Windows, thanks guys.

What tools are used for finding them? I'd love to learn how to do this so I can contribute to the project in the future.

@joshlatimer
Some tools to look into are things like Cheat Engine and a good hex editor, I use HxD and 010.

What apps have you made off the back off the framework?

Okay I'll look into a hex editor, thanks. I tried using Cheat Engine and could find a few basic things but I couldn't find the address of a team array etc.. my knowledge of Cheat Engine is basic though.

I found this framework a few days ago (the same day a new update was released :() so I haven't made anything yet... a few months ago I was trying to create my own framework to read real time data from the game but I couldn't figure out how to find the address of every team etc..

I remember using a FM Scout Framework which Thanos was involved with about 6 years ago, I'm glad it's still around! I thought it went closed source as originally I could only find the google code project.

Yeah, to be honest, after I moved away from Windows it was no use to me, but I thought I'd just give it an update for 2014 and 2015 and put it up here in case people are still interested in it.

I think I might write up a little guide at some point with a few tips on how to go about looking for addresses in the memory and explaining what a few structures look like in the process memory.

That would be amazing, thank you :)

I hope it's going well :)

Is there any way I can downgrade my FM to the previous version so I can start creating applications using this framework? I'm so excited! Thanks

Hi,

I was really looking forward to use this, it looks great.
Is there a timeline for when this issue might be fixed?

Thanks in advance, kind regards

@jaymarvels and @ThanosSiopoudis is there any chance you can give some tips on how to find the MainAddress offset? I'm doing fine with other offsets but I just can't work out how to find this one.

Thanks.

hey @joshlatimer
do you need instructions for Mac, Windows or Linux?

@joshlatimer I can only give you generic instructions/advise for Windows, as I'm only working with OS X and Linux myself.

Yes please :) I really want to learn how to do this myself, I've been spending the past few days on it but haven't been able to understand how to find certain things like the MainAddress and when/why to xor (like the framework does in FM14 for the memory addresses of objects)

Right, ok, here it goes:

You will need a few tools first:

Now, if you know the way loads data already (and you do for both FM 2014 and FM 2015 as the code is already there and it doesn't change for updates), all you need is to fire up your editor.

Your clue is the way the Framework reads the data. You basically have to work your way backwards.

  1. Fire up Football Manager 2015, and the editor of your choice
  2. Start a brand new game, and switch back to the editor. Attach the editor to the fm process
  3. Convert a Club Name to an FM Hex String. To do this, open your hex editor and create a new document. Write the club's name by adding a space after every character. Now, replace the 20 to 00.

Example:

Chelsea
C h e l s e a
43 00 68 00 65 00 6C 00 73 00 65 00 61 00
  1. Copy the hex string and do a search in the game's process memory. Keep searching until you find something that looks like what you're searching for. The correct match, should be preceded by 01 and the number of actual characters (07): 01 07 00 00 43 00 68 00 65 00 6C 00 73 00 65 00 61 00
  2. Note down the address at the 01 byte. As an example: 0x289DA0B0
  3. Do a search for a pointer to this address. If your editor doesn't give you an option to search for pointers, you need to reverse the address at every byte. (ex. B0 A0 9D 28). Do a new search for that.
  4. You are looking for the club object, so the correct match should be at the right distance to the club's UID. The UID is double-written in the memory. It is always RowID - UID - UID.
  5. You know the UID is at offset 0x8. It always is. So move your pointer to UID - 0x8 and get the address again.
  6. Do a search for a pointer to this address.
  7. The next thing we are looking for, is the array contents. You are basically looking for a bunch of memory pointers next to each other.
  8. Once you find it, start scrolling to find the beginning of the array. An easier way to do this, would be to search for the first club in the database, called Albpetrol Patos something. Write down the address of the first pointer in the array.
  9. Search for a pointer to this address. You are now looking for an array pointer. An array pointer looks like this: 0C F0 9A 30 20 F0 9A 30 20 F0 9A 30. The first part (0C F0 9A 30) is the pointer to the beginning of the array, and the next two parts (20 F0 9A 30 20 F0 9A 30) are two pointers next to each other that both point to the end of the array.
  10. Take a note of the address at the beginning of the first pointer. Do a new search for a pointer to this address.
  11. You shouldn't get too many results, but to make sure you're going the right way, with every search you should be moving backwards in the memory.
  12. Once you find your pointer, take a note of the address, and subtract 0x40.
  13. Take a note of the address, and again, look for a pointer.
  14. Subtract 0x14, and take a note of the address (we know that Clubs are at offset 0x14 from the start of the object pointers)
  15. Search for a new pointer to this address. Take a note, and ...
  16. Search for a pointer to the address.
  17. If everything went well, you are at the MainOffset! Take a note of the address, and subtract the process base address (you can figure this out by debugging the FMScoutFramework, put a breakpoint in file /VirtualMemory/Managers/GameManager.cs, line 171.

That's it! You can fork the project and create a new version file with all required attributes, then please do a pull request and I'll merge it in the main tree.

Another way, which is easier, but more time consuming, is to let the framework figure it out on its own. If it can't find a matching version, it will go in offset search mode, which will read the process and look for good candidates, and dump them in the Debug window of Visual Studio. It doesn't always work, but when it does, it is accurate. I've just pushed an update that makes the offset search compatible with FM15 (untested).

Have fun!

So, I've just added all needed version offsets for FM15.3.2 Windows. The specific entity offsets are probably incorrect for now. Feel free to correct them and send a PR.
These are the only ones pending to close this issue.

Thanks so much for going into detail. I've been stuck on step 5/6 for the last few hours though. Here is a screenshot of the club object (I think) http://i.imgur.com/R0l4Fea.png so I got the address from UID - 0x08 which is 26F557D8 and then I reversed it to D857F526 but that brings up no results when I search.

You mentioned some editors having the ability to search for pointers, can you suggest one? HxD and 010 don't seem to have that ability.

Hey @joshlatimer
I have already commited the version offsets for 15.3.2 Windows, so there's no need to keep looking!

Yeah thanks for that, but I really want to learn how to do this myself so I can update it as soon as a new patch is released in the future

I'll keep learning today :)

@joshlatimer Ok, do a new search for the club "Albpetrol Patos" (the first club in the clubs array) and I'll guide you through it to find the main offset yourself.
Find the Club object. Its row ID is 0 (00 00 00 00) and its UID is 57 (39 00 00 00).
So, to make sure you're at the clubs object, the byte sequence
00 00 00 00 39 00 00 00 39 00 00 00
should be at offset -0x50 from the name address (because the club name offset is at 0x54, and the RowID is at 0x4)

Thank you very much, I was just able to find the main address using your
instructions :)

I was stuck for a while due to Step 5, I got very confused and thought the
UID of the club was actually the address you get from Step 2!

Also, Step 15 and 16 both bring up a lot of results when searching for a
pointer to the addresses, is there an easier way to tell which address is
the right one to use?

On Mon, Jul 13, 2015 at 9:58 AM, Thanos Siopoudis notifications@github.com
wrote:

Ok, do a new search for the club "Albpetrol Patos" (the first club in the
clubs array) and I'll guide you through it to find the main offset
yourself. Find the Club object. Its row ID is 0 (00 00 00 00) and its UID
is 57 (39 00 00 00). So, to make sure you're at the clubs object, the
byte sequence 00 00 00 00 39 00 00 00 39 00 00 00 should be at offset
-0x50 from the name address (because the club name offset is at 0x54, and
the RowID is at 0x4)


Reply to this email directly or view it on GitHub
#1 (comment)
.

Yes, the easier way is to use Ollydbg for this.
If you go back to step 15, do this:

  • Fire up Ollydbg (in administrator mode).
  • Attach to the fm process
  • Now the screen will be split in a few panels, and the process will pause. The top-left panel is the ASM code, and the bottom-left panel is the memory view. These are the ones we are interested in.
  • In the memory view, right click and Go to -> Expression...
  • Enter the address you have found up to this step
  • Left-click on the first byte at the address you're in in the memory panel. Right-click and select Breakpoint -> Memory...
  • Add the breakpoint with read & write access
  • Continue the process from Ollydbg
  • Go in the game, and hit on the continue button. Ollydbg should hit the breakpoint.
  • Now, if you take a look at the ASM code, it should have a line, with a constant address (the one you found).
  • The main offset is the address of this instruction (you can see the instruction address on the left-hand side in the ASM code panel).
  • Keep in mind, that you will need to subtract the process base address from this address (it usually is 0x400000, but not always, because of windows' ASLR)

I forgot to mention, that for step 15, focus on addresses that are relatively close to the previous ones (i.e. around 0x1500000 - 0x2500000) to find the one we're interested in.