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 endeavour. I decided on football (soccer) manager and wanted to do two things.
- Decipher their file format for tactics. Essentially this has changed from tac to fmf in the last version or so
- 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 written (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 and 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:
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.