Question Working on Football Manager, help tracking variable/data

Hexui Undetected CSGO Cheats Sinkicheat PUBG Cheat

mizmar

Newbie
Apr 23, 2017
2
12
0
Hello everyone,

I am hoping someone can help me with a question or two.

Essentially I used to be a computer programmer who always wanted to get into a bit of game hacking, having not done any serious programming for a few years I had an itch for a technical endevour. I decided on football (soccer) manager and wanted to do two things.

1. Decipher their file format for tactics. Essentially this has changed from tac to fmf in the last version or so
2. When a game is being played hook into the DirectX calls to essentially record a match, or figure out the format of their saved matches which can be shown to others

Now as I have no experience of DirectX I went to do number 1 first and have made good progress, but I am at the point where I need a bit of help and pointing in the right direction. Here's what I have deciphered so far with screenshots.

The start of the fmf file is wrtten (always 02 01 61 66 65 afe) to start, so essentially the file header



Then actually the old TAC format is written to disk though the user never sees it unless you breakpoint it, as it puts the tactic on the file, reads it back in and then deletes it again





The TAC file is read back in

A new section of the fmf is written



Now this looks similar in size to the previous tac file and is written after the tac file is read back in by the application, it also seems to have section separators in the FMF file so it is its own section.



If you look carefully you can see that this section is what was written after it read the tac file back in, now this section appears to be compressed/encrypted but I would guess that this is the tac, and you can clearly see distinct sections in the file separated by

10 00 00 00 10 00 00 00

So it is easy to break the file up. Now my question is, this section is the area of interest.



The actual data always seems to be around rcx+8 which points to an address with a QWORD pointer which points to the data. I tried decompiling this function and got the following:

C++:
struct s0 {
    uint32_t f0;
    int8_t[4] pad8;
    uint32_t f8;
    int8_t[4] pad16;
    uint32_t f16;
    uint32_t f20;
};

int32_t fun_146da5dd0();

/* function-which-calls-write */
uint32_t function_which_calls_write(int64_t rcx, uint32_t rdx, int64_t r8);

/* unknown 1 */
int64_t unknown_1(struct s0* rcx) {
    uint32_t eax2;
    uint32_t eax3;
    uint32_t edi4;
    uint32_t rsi5;
    int64_t rax6;
    int32_t eax7;
    int64_t rcx8;
    int64_t r8_9;
    uint32_t eax10;
    uint32_t eax11;

    eax2 = rcx->f20;
    if ((*(uint8_t*)&eax2 & 3) != 2 || ((eax3 = rcx->f20, (*(uint8_t*)&eax3 & 0xc0) == 0) || (edi4 = rcx->f0 - rcx->f8, rcx->f16 = 0, rsi5 = rcx->f8, rcx->f0 = rsi5, (uint1_t)((int32_t)edi4 < (int32_t)0) | (uint1_t)(edi4 == 0)))) {
        addr_0x146d9e917_2:
        *(uint32_t*)&rax6 = 0;
        *(int32_t*)((int64_t)&rax6 + 4) = 0;
    } else {
        eax7 = fun_146da5dd0();
        *(int32_t*)&rcx8 = eax7;
        *(int32_t*)((int64_t)&rcx8 + 4) = 0;
        *(uint32_t*)&r8_9 = edi4;
        *(int32_t*)((int64_t)&r8_9 + 4) = 0;
        eax10 = function_which_calls_write(rcx8, rsi5, r8_9);
        if (edi4 == eax10) {
            eax11 = rcx->f20 >> 2;
            if (*(uint8_t*)&eax11 & 1) {
                rcx->f20 = rcx->f20 & 0xfffffffd;
                goto addr_0x146d9e917_2;
            }
        } else {
            rcx->f20 = rcx->f20 | 16;
            *(uint32_t*)&rax6 = 0xffffffff;
            *(int32_t*)((int64_t)&rax6 + 4) = 0;
        }
    }
    return rax6;
}
So obvious it seems like a struct, especially with the +number on the registers.

Another useful thing to note is that these sections in the fmf file are always different, ALWAYS, so if I make a tactic, save it, load in the tactic again (exact same one) and resave it is totally different content in between the constant separators 10 00 00 00 and the signature at the start of the file. So that leads me to believe it is some form of compression/encryption but with additional seed, such as the time added.

My question is I have located this data in the function I showed above, but obviously there is data loaded in before this place in the function or in a previous function in the call stack. Is there any quick way of following where this data comes from? Once I find the exact point it originates I should obviously be able to conclude that is the encryption/compression function which produces it.

Thanks a lot.
 

Rake

Cesspool Admin
Administrator
Jan 21, 2014
12,073
78,998
2,371
nice job reversing what you've done so far, I guess it is possible that it's not encrypted but that this is just how the data is stored
 

mizmar

Newbie
Apr 23, 2017
2
12
0
Rake;48882 said:
nice job reversing what you've done so far, I guess it is possible that it's not encrypted but that this is just how the data is stored
Hey Rake, thanks a lot for approving the thread and reply!

I just considered that and did some testing around the theory unfortunately I don't think it can be the case now as if I have the file, load it in it will load in, then re-save as a different file name and the content will be completely different, bar the actual file structure, so I considered there has to be some form of seed somewhere and it has to be compressed or encrypted otherwise the raw data would be the same as the tactics are identical.

I am trying to think of techniques to narrow down the space where this data is processed but not quite sure how at the moment, especially if the fmf data is different each time, that adds an element of difficulty. I was thinking about just setting a breakpoint in each place in the call stack and then searching the memory for 10 00 00 00 10 00 00 00 which is their separator in the file, maybe that would yield some results. I will give it a try tomorrow I think, but any more suggestions from anyone much more experienced in RE such as yourself or others on the forum are welcome.

Thanks!
 
Attention! Before you post:

Read the How to Ask Questions Guide
99% of questions are answered in the Beginner's Guide, do it before asking a question.

No Hack Requests. Post in the correct section.  Search the forum first. Read the rules.

How to make a good post:

  • Fill out the form correctly
  • Tell us the game name & coding language
  • Post everything we need to know to help you
  • Ask specific questions, be descriptive
  • Post errors, line numbers & screenshots
  • Post code snippets using code tags
  • If it's a large project, zip it up and attach it

If you do not comply, your post may be deleted.  We want to help, please make a good post and we will do our best to help you.

Community Mods