Marvel's Avengers

Add topics here with methods, analysis, code snippets, mods etc. for a certain game that normally won't make it in the Tables or Requests sections.
Post Reply
User avatar
SunBeam
Administration
Administration
Posts: 3158
Joined: Sun Feb 04, 2018 7:16 pm
Reputation: 2327

Marvel's Avengers

Post by SunBeam »

Game Name: Marvel's Avengers
Game Vendor: Steam
Game Version: 1.0
Game Process: avengers.exe
Game File Version: 1.3.13.18



Hello folks. Yet another new game with a different engine. This time around: Foundation Engine.

I'll be posting my discoveries in this topic, as I progress. Should help those of you who actively work on the game, while for others it may prove a decent read.. or an annoying mouse scroll of walls of text :) Whichever your reaction, both I will enjoy :)

What I first like to do is find a means to get to the version of the game. That helps me use the formatted way in which developers store this internally, somewhere in the .exe, or just computed in some structure that gets initialized at game start. And I got this:

Code: Select all

00000001412C4316 | E8 95ABDBFF   | CALL avengers.14107EEB0    | <-- this gets a base pointer
00000001412C431B | 48:8B13       | MOV RDX,QWORD PTR DS:[RBX] |
00000001412C431E | 48:8BCB       | MOV RCX,RBX                |
00000001412C4321 | 48:8BF8       | MOV RDI,RAX                |
00000001412C4324 | FF92 C0000000 | CALL QWORD PTR DS:[RDX+C0] | <-- GetVersion
The CALL @ 14107EEB0 does this:

Code: Select all

000000014107EEB0 | 48:8B05 B978FF01 | MOV RAX,QWORD PTR DS:[143076770]
000000014107EEB7 | 48:8B00          | MOV RAX,QWORD PTR DS:[RAX]
000000014107EEBA | C3               | RET
The memory data of what's being read looks like this:

Code: Select all

000000014107EEB0 | 48:8B05 B978FF01 | MOV RAX,QWORD PTR DS:[143076770] | 000000015E9BBA60
000000014107EEB7 | 48:8B00          | MOV RAX,QWORD PTR DS:[RAX]       | 000000015E9BBB30
000000014107EEBA | C3               | RET                              |

000000015E9BBA60  000000015E9BBB30  <-- (MOV RAX,QWORD PTR DS:[143076770])
000000015E9BBA68  000000015E9B84D0
000000015E9BBA70  000000015E9BE0C0
000000015E9BBA78  000000015E9BC6E0
000000015E9BBA80  0000000000000000
000000015E9BBA88  000000015E9C4720
000000015E9BBA90  000000015E9BC710
000000015E9BBA98  000000015E9BD6F0
000000015E9BBAA0  000000015E9BDC00
000000015E9BBAA8  000000015E9BD710
000000015E9BBAB0  000000015E9BD810
000000015E9BBAB8  000000015E9BD960
000000015E9BBAC0  000000015E9BD930
000000015E9BBAC8  000000015E9BDA30
000000015E9BBAD0  000000015E9BDE90
000000015E9BBAD8  000000015E9BDFE0
000000015E9BBAE0  000000015E9BE000
000000015E9BBAE8  000000015E9BE0F0
000000015E9BBAF0  000000015E9BCDB0
000000015E9BBAF8  000000015E9BD650
000000015E9BBB00  000000015E9BE1E0
000000015E9BBB08  000000015E9BE6F0
000000015E9BBB10  000000015E9BEB10
000000015E9BBB18  000000015E9BE2B0
000000015E9BBB20  000000015E9BADC0
000000015E9BBB28  0000000000000AD3
000000015E9BBB30  00000001428E9858  <-- pBase (MOV RAX,QWORD PTR DS:[RAX])
000000015E9BBB38  0000000001000100
000000015E9BBB40  000000015E9BFA90  "Marvel's Avengers" == (LEA RAX,[RAX+10])
So 0x10 holds the p->str (I'll mark like this a pointer-to-string) to the game's name: "Marvel's Avengers".

Then the CALL @ 1412C4324 (CALL QWORD PTR DS:[RDX+C0]) does this:

Code: Select all

0000000141081B00 | 48:8D81 38020000 | LEA RAX,QWORD PTR DS:[RCX+238] | [rcx+238]:"v1.3 build 13.18"
0000000141081B07 | 48:8378 18 10    | CMP QWORD PTR DS:[RAX+18],10   | <-- engine does a check for a flag here; if not below 0x10, then
0000000141081B0C | 72 03            | JB avengers.141081B11          |
0000000141081B0E | 48:8B00          | MOV RAX,QWORD PTR DS:[RAX]     | reads the Version p->str here
0000000141081B11 | C3               | RET                            |
Engine loads up the offset to p->str for Version. Then checks if a certain flag 0x18 away from that address (rcx+0x238) holds a value that should be > 0x10. In our case, the value is 0x1F. Not sure exactly at this point in time what it stands for, but maybe I'll find out later. So the function overall retrieves the p->str to Version, on the condition the flag it checks is > 0x10. I called it GetVersion.

So you'll see me use this method to get the game's version compared to the version for which my table is created. If the 2 versions match, then the table will just enable main script. If they don't match, you'll see a warning and some comments. Just like I did in the table for Serious Sam 4:

Image

Now you know the reason and logic behind the version check in my tables :P

As far as the names of the structures, who they are and what they do.. If you can't use RTTI ([Link]) to get the information you need, I usually look at the member-functions (or virtual table; short, vtable) for "bread-crumbs" :) And in this case, looking at that "pBase" pointer's member-functions I found several things.

Most standard Engine types will have the first member-function a destructor. The rest of them will do other things. Among them I usually look for either a "GetClass" (name) function or leads to a name in any function. The list I got for that 'pBase' is shown below:

Code: Select all

00000001428E9858:
$ ==>             0000000141081030  
$+8               0000000141E744C0  
$+10              0000000141084390  
$+18              00000001410841F0  
$+20              0000000141082380  
$+28              0000000141082E00  
$+30              0000000141085460  
$+38              0000000141081710  
$+40              0000000141083630  
$+48              0000000141085B70  
$+50              00000001410842E0  
$+58              00000001410836D0  
$+60              0000000141081A10  
$+68              00000001410819F0  
$+70              00000001410844E0  
$+78              0000000141081490  
$+80              0000000141081810  
$+88              0000000141085D30  
$+90              0000000141085D30  
$+98              0000000141081EF0  
$+A0              0000000141081C40  
$+A8              0000000141081C30  
..
So I started checking out each of those functions and found this in function at 0x10 in the list above:

Code: Select all

0000000141084390 | 48:895C24 08                        | MOV QWORD PTR SS:[RSP+8],RBX                                       | prologue
..
000000014108441B | 4C:8D05 DE5D8601                    | LEA R8,QWORD PTR DS:[1428EA200]                                    | 00000001428EA200:"PreInit"
0000000141084422 | 48:8BC8                             | MOV RCX,RAX                                                        |
0000000141084425 | 48:8D15 784C8601                    | LEA RDX,QWORD PTR DS:[1428E90A4]                                   | 00000001428E90A4:"NxApp"
See that "NxApp"? Welp, I continued looking at the rest of the functions and saw this in the function at 0x20:

Code: Select all

0000000141082380 | 48:8BC4                             | MOV RAX,RSP                                                        | prologue
..
000000014108291A | 4C:8D05 D7798601                    | LEA R8,QWORD PTR DS:[1428EA2F8]                                    | 00000001428EA2F8:"Old Driver detected. Driver version: %s"
0000000141082921 | 48:8D15 7C678601                    | LEA RDX,QWORD PTR DS:[1428E90A4]                                   | 00000001428E90A4:"NxApp"
Again, "NxApp". Checked another one, the function at 0x28:

Code: Select all

0000000141082E00 | 48:895C24 10                        | MOV QWORD PTR SS:[RSP+10],RBX                                      | prologue
..
0000000141082E1D | 4C:8D05 8C758601                    | LEA R8,QWORD PTR DS:[1428EA3B0]                                    | 00000001428EA3B0:"Creating window..."
0000000141082E24 | 48:8BC8                             | MOV RCX,RAX                                                        |
0000000141082E27 | 48:8D15 76628601                    | LEA RDX,QWORD PTR DS:[1428E90A4]                                   | 00000001428E90A4:"NxApp"
Again "NxApp". Then the function at 0xD8 offset:

Code: Select all

00000001410856B0 | 40:53                               | PUSH RBX                                                           | prologue
..
00000001410857B2 | 4C:8D05 D74C8601                    | LEA R8,QWORD PTR DS:[1428EA490]                                    | 00000001428EA490:"Finished enforcing display settings"
00000001410857B9 | 48:8BC8                             | MOV RCX,RAX                                                        |
00000001410857BC | 48:8D15 F54C8601                    | LEA RDX,QWORD PTR DS:[1428EA4B8]                                   | 00000001428EA4B8:"NxApp (Render Thread)"
So I guess it's safe to say our 'pBase' is actually "NxApp" or Application. So the function @ 14107EEB0 can be called GetApplication. That's how I do it. And now you know (since I've been asked about this several times).

BR,
Sun

User avatar
SunBeam
Administration
Administration
Posts: 3158
Joined: Sun Feb 04, 2018 7:16 pm
Reputation: 2327

Re: Marvel's Avengers

Post by SunBeam »

I've managed to figure out how to obtain Perfect God Mode (no staggering; enemies just hit through you).

As a starting point you have 2 options: a) normal scan for unknown/changed/unchanged till you find the address (that's if you start hacking the game from scratch); b) make use of already existing progress and continue on your path.

Today I'm gonna show you how to actually make use of someone's work to achieve more progress or improved results. Just in case you wondered "how" this is done. Keep in mind the starting point here is obtaining a lead to the HP structure and not impersonating or claiming someone else's full work on the game. That being said, I'll be using this table (credits fly out to ArmY of 0n3).

Note that the table is quite outdated, 22nd of August 2020, made for the Beta v1.0 build 26.1. Even so, I could use the Inf.Health script, but didn't quite like the outcome. Your health bar would drop for a split second then stay frozen, but you do get hit and the blood effect filling the HUD plus push-back on each interaction is very annoying. Not to mention the constant screaming and yelling as you take hits..

So.. the aob ArmY used is still working:

Code: Select all

aobscanmodule( _AobHp, avengers.exe, 66 41 0F 6E B0 8C 04 00 00 )
It would get you to this location (in v1.3 build 13.18):

Code: Select all

avengers.exe+1EE6126 - 66 41 0F6E B0 8C040000  - movd xmm6,[r8+0000048C]
avengers.exe+1EE612F - 45 8B 88 98040000     - mov r9d,[r8+00000498]
So what we want from this spot is determining who is R8. Our starting pointer (I'm not going to call it "base") for HP.

What I did next was to add to the address appointed by r8+48C to CE's list and check out the value. I noticed it's a DWORD. Then I looked at [r8+488] and noticed it's a FLOAT. Same value as the 0x48C DWORD, but of FLOAT type.

What I wanted to see next is WHO writes to it when you get hit. So I've set a breakpoint on either of them and got into a fight. And got these addresses popping up:

For 0x48C:

Code: Select all

141382148 - 89 87 8C040000  - mov [rdi+0000048C],eax
141381FE5 - 41 89 87 8C040000  - mov [r15+0000048C],eax
1413B74AA - 89 8B 8C040000  - mov [rbx+0000048C],ecx
For 0x488:

Code: Select all

141382155 - F3 0F11 87 88040000  - movss [rdi+00000488],xmm0
141381FC1 - F3 45 0F11 87 88040000  - movss [r15+00000488],xmm8
1413B74A2 - F3 0F11 8B 88040000  - movss [rbx+00000488],xmm1
Then I wanted to know EXACTLY which of the 3 above, if NOP-ed, would not write to my HP. So I went to the prologue of each of the 3 0x48C functions and put a RET there, testing each of them. I found the last one to be the culprit:

Code: Select all

1413B74AA - 89 8B 8C040000  - mov [rbx+0000048C],ecx
The prologue of the function:

Code: Select all

avengers.exe+13B7460 - 40 53                 - push rbx
avengers.exe+13B7462 - 48 83 EC 20           - sub rsp,20
avengers.exe+13B7466 - 48 8B D9              - mov rbx,rcx
avengers.exe+13B7469 - F3 0F2C C9            - cvttss2si ecx,xmm1
Now.. this spot you'll find it's shared. So not only do we need to figure out what the pointer to HP stands for, but also a way to filter this stuff. The first thing I wanted to do was to backtrace as far as possible, till RET-ing function prologues would disable getting hit. To do that, I went to the epilogue of the above function:

Code: Select all

avengers.exe+13B7560 - 48 83 C4 20           - add rsp,20
avengers.exe+13B7564 - 5B                    - pop rbx
avengers.exe+13B7565 - C3                    - ret <-- here
Right-clicked the RET, choose "Break and trace instructions" then tick the below:

Image

Once you get hit, game will freeze for a few seconds then resume. Back out in CE you will see this:

Image

Then right-click top node and choose "Expand all" and this is what you'll see:

Image

Then what you'd do next is double-click the last line in each node, scroll up to function's prologue and set a RET there. Then go back in-game and see if you get hit (if you see any HUD effects when someone shoots or hits you). If you do, go back, restore the prologue and double-click the next last line from the Tracer tree.

I tested these:

- double-clicked on "avengers.exe+137E212 - E9 C4000000 - jmp avengers.exe+137E2DB"
- scrolled up and put a RET @ "avengers.exe+137E160 - 48 89 5C 24 18 - mov [rsp+18],rbx"
- I noticed I did still get hit, no damage whatsoever, but still getting pushed back on hit and sound-reacting to hits

- double-clicked on "avengers.exe+137E666 - 85 FF - test edi,edi"
- scrolled up and put a RET @ "avengers.exe+137E3A0 - 4C 8B DC - mov r11,rsp"
- I noticed I didn't get hit anymore, no damage, no push-back and no sound reactions; AI would hit through me, as if my body model was non-solid

So this is where I stopped and considered this to be a nice Perfect God Mode spot, on the condition I manage to filter out the player. Remember everything in the chain is shared.

And this is where the confusing part starts, as most of you will be like WTF is up. So was I, but pulled it through eventually. Problem is this is tricky to explain, as I too don't understand it perfectly.

We're here now:

Code: Select all

avengers.exe+137E3A0 - 4C 8B DC              - mov r11,rsp
avengers.exe+137E3A3 - 53                    - push rbx
avengers.exe+137E3A4 - 48 81 EC 50010000     - sub rsp,00000150 { 336 }
avengers.exe+137E3AB - 41 0F29 7B A8         - movaps [r11-58],xmm7
avengers.exe+137E3B0 - 48 8B 05 09AEC501     - mov rax,[avengers.exe+2FD91C0] { (194456160) }
avengers.exe+137E3B7 - 48 33 C4              - xor rax,rsp
avengers.exe+137E3BA - 48 89 84 24 C0000000  - mov [rsp+000000C0],rax
avengers.exe+137E3C2 - 49 89 73 E8           - mov [r11-18],rsi
avengers.exe+137E3C6 - 48 8B D9              - mov rbx,rcx <--
We want to snoop around the RCX pointer, which is usually the first thing you should look at in x64 ASM when dealing with functions and prologues. In my case, it looked like this, while getting hit by a robot:

Image

So I started looking at the member-functions table from RCX. To get there, just browse in memory the x64 pointer at 0x00 offset in your RCX's memory space. I used x64dbg for this, as it better displays the content:

Image

Image

I checked each of the functions to make sense what we're dealing with here. And got this by looking at the function at 0x28 offset:

Image

So what's being processed here is our HealthComponent ;) Alright, one down, we know what's this RCX we're looking at. OK, now.. how to filter this out of the various being processed by this function? You have several options:

a) back-trace out of this function and determine how RCX is retrieved (where from)
b) debug the RCX section using exception breakpoints and find out a function that's checking (accessing) ONLY your RCX memory space

The latter one would be a lot simpler, though I prefer challenges. So I went with option a). And found this logic:

Code: Select all

avengers.exe+1A0B52B - 8B 05 6FFC6601        - mov eax,[avengers.exe+307B1A0] { (25) } // 0x19
avengers.exe+1A0B531 - 39 87 E8000000        - cmp [rdi+000000E8],eax
avengers.exe+1A0B537 - 76 4E                 - jna avengers.exe+1A0B587
avengers.exe+1A0B539 - 8B C8                 - mov ecx,eax
avengers.exe+1A0B53B - 48 8B 87 F0000000     - mov rax,[rdi+000000F0] // 00000001437F2880
avengers.exe+1A0B542 - 48 8B 1C C8           - mov rbx,[rax+rcx*8]    // HealthComponent
avengers.exe+1A0B546 - 48 85 DB              - test rbx,rbx
avengers.exe+1A0B549 - 74 3C                 - je avengers.exe+1A0B587
avengers.exe+1A0B54B - 4C 8D 4D 80           - lea r9,[rbp-80]
avengers.exe+1A0B54F - 45 8B C5              - mov r8d,r13d
avengers.exe+1A0B552 - 48 8B CB              - mov rcx,rbx
avengers.exe+1A0B555 - E8 763E97FF           - call avengers.exe+137F3D0 // DoDamage
From what I could gather in the above.. 0x19 is the offset for the HealthComponent structure in the player's Components table. To get to that table, you'd check offset 0xF0. Apparently, this offset can't be above a fixed value stored at 0xE8 offset. Confusing, right? Especially since you're probably used with simple ASM operations and nothing like the above.. :)

I've then managed to find a static location where I'd read a pointer, which, at 0x8 would contain the Components table. I'm sure it's related to our Player because the computations lead exactly to OUR HealthComponent:

Code: Select all

avengers.exe+1DA6180 - 40 53                 - push rbx
avengers.exe+1DA6182 - 48 83 EC 40           - sub rsp,40 { 64 }
avengers.exe+1DA6186 - 48 8B 0D 5B26A102     - mov rcx,[avengers.exe+47B87E8] { (162DE2BA0) }
avengers.exe+1DA618D - 48 81 C1 98010000     - add rcx,00000198 { 408 }
avengers.exe+1DA6194 - E8 D7760000           - call avengers.exe+1DAD870
avengers.exe+1DA6199 - 48 8B 1D 4031A102     - mov rbx,[avengers.exe+47B92E0] { (128) } // <-- this 
avengers.exe+1DA61A0 - 48 85 DB              - test rbx,rbx
avengers.exe+1DA61A3 - 0F84 AA010000         - je avengers.exe+1DA6353
In my case "[avengers.exe+47B92E0]" points to 1AB021A40. Same drill, check member-functions and find a lead to the CLASS name:

Image

Image

So.. MeleeMoveComponent.

Now.. piecing it all together, we get this:

avengers.exe+1DA6199 - mov rbx,[avengers.exe+47B92E0] // rbx holds the pointer to MeleeMoveComponent structure; it's ours, not enemy's
-> rbx = 1AB021A40 // in my case

mov rdi,[rbx+8] // this then points to the Components structure I mentioned earlier
-> rdi = 143A82640 // in my case

Then from here, we have this calculus that we need to do:

mov eax,[avengers.exe+307B1A0] // this will always be 0x19
cmp [rdi+000000E8],eax // if the offset is above a static value at 143A82640+E8
jna short @f // skip and jump to @@ label
mov ecx,eax // ecx becomes 0x19
mov rax,[rdi+000000F0] // rax becomes [143A82640+F0] == 0000000170E38570 (in my case!)
mov rbx,[rax+rcx*8] // rbx == 16D87A210 (which is MY HealthComponent)
@@:
..
..

So the final script looks like this:

Code: Select all

[ENABLE]

aobscanmodule( ProcessDamage, avengers.exe, ??????534881EC????????410F297B??488B05????????4833C448898424????????49 )
registersymbol( ProcessDamage )
label( ProcessDamage_o )
registersymbol( ProcessDamage_o )

alloc( Hook, 0x1000, avengers.exe )

Hook:
push rax
push rdx
mov edx,[avengers.exe+307B1A0] // 0x19 == offset to HealthComponent
mov rax,[avengers.exe+47B92E0] // MeleeMoveComponent
mov rax,[rax+8]                // p
cmp [rax+E8],edx
jna short @f
  mov rax,[rax+F0]             // Components table
  mov rax,[rax+rdx*8]          // HealthComponent
@@:
cmp rax,rcx
pop rdx
pop rax
jne short @f
  ret
ProcessDamage_o:
readmem( ProcessDamage, 11 )
jmp ProcessDamage+B

ProcessDamage:
jmp Hook
nop 6

[DISABLE]

ProcessDamage:
readmem( ProcessDamage_o, 11 )

dealloc( Hook )
unregistersymbol( ProcessDamage_o )
unregistersymbol( ProcessDamage )
What the script does:

- hooks the spot I've found out to work fine skipping damage processing (avengers.exe+137E3A0 - 4C 8B DC - mov r11,rsp)
- filters the Player's HealthComponent out of the many being processed by that function
- if our Player HealthComponent, function exits (you see the "ret")

Give it a go :P

BR,
Sun

Maryrangel
What is cheating?
What is cheating?
Posts: 1
Joined: Mon Sep 28, 2020 11:25 am
Reputation: 0

Re: Marvel's Avengers

Post by Maryrangel »

Nice!! Would you think it’s possible to create a character/mesh swap with CE for this game? (Similar to what we have with Red Dead 2 and GTA through scripthook)?

User avatar
SunBeam
Administration
Administration
Posts: 3158
Joined: Sun Feb 04, 2018 7:16 pm
Reputation: 2327

Re: Marvel's Avengers

Post by SunBeam »

^ I have no interest for such things. Me | | character swapping, free camera, cinematic tools, skins, mods, "change player with another" and any other personal requests people have. The "| |" means I don't intersect with any of those :) (parallel lines).

Chaos5061
Cheater
Cheater
Posts: 39
Joined: Thu Apr 19, 2018 1:03 pm
Reputation: 5

Re: Marvel's Avengers

Post by Chaos5061 »

Hmm user error. After I put the script in it doesn't activate. When I right click it above where it says Delete this record it says

<<Error while scanning for AOB's : ProcessDamage Error: Not all results found>>

User avatar
sebastianyyz
Expert Cheater
Expert Cheater
Posts: 188
Joined: Sun Jul 09, 2017 3:33 am
Reputation: 16

Re: Marvel's Avengers

Post by sebastianyyz »

Great table as usual. Thank you SunBeam

User avatar
SunBeam
Administration
Administration
Posts: 3158
Joined: Sun Feb 04, 2018 7:16 pm
Reputation: 2327

Re: Marvel's Avengers

Post by SunBeam »

Chaos5061 wrote:
Mon Sep 28, 2020 2:07 pm
Hmm user error. After I put the script in it doesn't activate. When I right click it above where it says Delete this record it says

<<Error while scanning for AOB's : ProcessDamage Error: Not all results found>>
Go to "avengers.exe+137E3A0" address in Memory View (copy what's between the "", CE, Memory View, click in top window, Ctrl+G, paste, Enter) and post a screenshot of what you see there. I believe you're not running the latest Steam version 1.3 build 13.18.

Chaos5061
Cheater
Cheater
Posts: 39
Joined: Thu Apr 19, 2018 1:03 pm
Reputation: 5

Re: Marvel's Avengers

Post by Chaos5061 »

Here is the screenshot

Image

Chaos5061
Cheater
Cheater
Posts: 39
Joined: Thu Apr 19, 2018 1:03 pm
Reputation: 5

Re: Marvel's Avengers

Post by Chaos5061 »

Okay I got it to work. It was either the verifying the game files I did or downloading the High Res Texture pack that did it. Not sure which but after doing those two things I did the memory search again and it found something it didn't bring up the Nothing Found box so I tried the script and it worked.

User avatar
SunBeam
Administration
Administration
Posts: 3158
Joined: Sun Feb 04, 2018 7:16 pm
Reputation: 2327

Re: Marvel's Avengers

Post by SunBeam »

BEWARE THAT PERFECT GOD MAY BREAK SCRIPTED EVENTS AND YOUR SAVE GAME IS GOING TO BE BRICKED.

What I mean with the above. The function hooked to filter out the Player's HealthComponent is also executed when a map is initialized. I found at least 2 places where, when you were done defeating all AI, nothing would happen. No cutscene, no nada: a) "Banner's Descent", right after fighting the first set of mobs outside the main lab entrance; b) "House Call" mission wouldn't end after defeating all robots outside with Tony, Hulk and Kamala.

Side-effects (what I mean with "bricked"): "Reload from Checkpoint" won't work properly, you won't be able to exit the campaign mission or restart it (I really applaud the developers for this stupid idea of not providing means to restart a map.. stupid, stupid, stupid!), NPCs being generated under the map (e.g.: pressing V would show Hulk sinking under the map, distance between him and you increasing rapidly, as he goes down). Tarleton's ship would freeze in place and the trailer cutscene wouldn't play. This scene @ 16:50:



So please back-up your shit before you use this God Mode. I will provide some alternative, we'll see.

Save folder is here:

Code: Select all

C:\Users\<your_name>\Documents\Marvel's Avengers

Chaos5061
Cheater
Cheater
Posts: 39
Joined: Thu Apr 19, 2018 1:03 pm
Reputation: 5

Re: Marvel's Avengers

Post by Chaos5061 »

There is a backup save generated even 5 minutes I think in the settings gameplay menu. But also do backup manually. This is one of the few games I've played that has had more issues of deleting your stuff than others in recent memory.

Post Reply

Who is online

Users browsing this forum: No registered users