Modify value that is constantly re-written

Memory scanning, code injection, debugger internals and other gamemodding related discussion
Post Reply
parittolo
Noobzor
Noobzor
Posts: 8
Joined: Wed Jan 27, 2021 11:53 pm
Reputation: 0

Modify value that is constantly re-written

Post by parittolo »

Hi,
I am trying to modify the a value that controls the camera FoV in Ace Combat: Assault Horizon.
[Link] this is the address which I think holds the fov value in degrees (so 0.55 here is 55 degrees)

I would like to be able to add an offset to this value, but it can't be static as there is a function that is writing to it every frame [Link] so even if I were to add 0.05 it would immediately get overwritten by a new value

What is the correct approach in this situation?

sbryzl
Expert Cheater
Expert Cheater
Posts: 122
Joined: Sat Mar 04, 2017 4:47 am
Reputation: 64

Re: Modify value that is constantly re-written

Post by sbryzl »

It depends. Did you try replacing the move with a bunch of nops? You could make an assembly script and flag variable to switch it on and off. You could just add .05 to the written value each time depending on how the game works if that's what you want to do. If it writes to other addresses too then it might take some work to delineate them.

parittolo
Noobzor
Noobzor
Posts: 8
Joined: Wed Jan 27, 2021 11:53 pm
Reputation: 0

Re: Modify value that is constantly re-written

Post by parittolo »

Thanks for the answer!

I tried nop-ing the move, like this [Link] and it "works" meaning the values I set remain unchanged.

Problem is, this breaks all the instances where the FoV is supposed to change (e.g. when locking onto an enemy, when zooming with a helicopter, during cutscenes etc. etc.)
If it writes to other addresses too then it might take some work to delineate them.
I think that it writes to this one address, which in turn is written to only by this opcode (and another one a single time when one changes the resolution of the game)


I looked more into the assembly, if I understand correctly "movss [eax+0240],xmm0" copies the first 4 bits of xmm0 into this eax (I do not understand what the offset is for. Perhaps the first operand is an address? It should be the address I am trying to modify... I don't know)

I tried modifying the register value at that opcode with CE and wrote directly 0.85 into the first part of xmm0, and it seems to work, the address gets updated with my value.

But I think this is a permanent change, because then the fov is fixed ingame, I get the same behaviour as nop-ing the function.

Could some code be injected above that movss to change the add/subtract from the value of xmm0? I don't know how.

User avatar
GreenHouse
GreenHouse!
GreenHouse!
Posts: 601
Joined: Fri Oct 12, 2018 10:25 pm
Reputation: 450

Re: Modify value that is constantly re-written

Post by GreenHouse »

If that instruction just writes what you want to change, then just change it to:
mov [eax+240],(float)45
Change that 45 to whatever you want the value to be set to.

sbryzl
Expert Cheater
Expert Cheater
Posts: 122
Joined: Sat Mar 04, 2017 4:47 am
Reputation: 64

Re: Modify value that is constantly re-written

Post by sbryzl »

If you want it to change automatically you need to make an autoassembler script. Compare the xmm value to .55 or .5 or .6 then jump if equal, above or below depending on what you want so you only change the value if it's in a certain range.

parittolo
Noobzor
Noobzor
Posts: 8
Joined: Wed Jan 27, 2021 11:53 pm
Reputation: 0

Re: Modify value that is constantly re-written

Post by parittolo »

If that instruction just writes what you want to change, then just change it to:
mov [eax+240],(float)45
Change that 45 to whatever you want the value to be set to.
Like this? [Link]
I changed it with "mov [eax+00000240],(float)0.6", CE asked me if I wanted to nop the following code because of a lenght mismatch, clicked yes.
The value gets written with 0.6 but it is fixed like that and I would like to preserve the way the game changes the FoV, just with higher values.

If you want it to change automatically you need to make an autoassembler script. Compare the xmm value to .55 or .5 or .6 then jump if equal, above or below depending on what you want so you only change the value if it's in a certain range.
I don't really know where to start.

I think this is what I intended
You could just add .05 to the written value each time depending on how the game works if that's what you want to do.
What I understand is at the point where the opcode runs, xmm0 has been changed by the game to hold the fov value.
I tried tracing back how but quickly got lost, but I guess it does not really matter how it gets to the value.

[Link] so if I inject some code just above, like in the previous opcode, that adds something 0.2 (20 degrees) to xmm0 before the next opcode writes it to the FoV address I should get the game value plus 20 degrees.
So it changes as normal as the game wants to and I get higher FoV.

I don't know how to implement something like that, but would this be viable?
Can the value I add be changed at will, by binding the keys f5 to +0.05 and f6 to -0.05 and change the fov like that when the game is running?


EDIT:

I tried something like this [Link] by injecting in the instruction just above the one I'm interested in.
As I understand addss can't take a float as an argument, but doing addss xmm0,xmm0 is effectively xmm0*2, and it works, the FoV changes when it is supposed to, it is just doubled.

Now, double the FoV is too much so I need finer control over it, I think 5 degrees steps bound to two keys would be good.
(Also the game adds a strange vingette effect, it looks like watching through a tube or a telescope when the FoV is more than 85 degrees, I would like to fix that as well but I fear it's a much much harder problem)

Is this a step in the right direction?

sbryzl
Expert Cheater
Expert Cheater
Posts: 122
Joined: Sat Mar 04, 2017 4:47 am
Reputation: 64

Re: Modify value that is constantly re-written

Post by sbryzl »

You are using code injection template? Before selecting code injection, select cheat table framework template so it has an enable and disable section. Then select code injection to fill in the enable and disable sections. You can put the template here in text format and I will fix it.

parittolo
Noobzor
Noobzor
Posts: 8
Joined: Wed Jan 27, 2021 11:53 pm
Reputation: 0

Re: Modify value that is constantly re-written

Post by parittolo »

Thanks for the reply!

Yes, I used the code injection template (I don't really know how to do it myself).
Before reading your post I kept trying and sort of achieved the end goal.

I read that the "addss" opcode can accept a memory address, I know how to directly change the value of an address using CE
So I found one that looked unused [Link]
Added it to the address list and wrote this in the injection script [Link]
with hotkeys [Link]

Now I can change that address, via hotkey for example, and add/subtract what I want to the in-game FoV which is still managed by the game before my offset, made a little video to show [Link]

Having said that, having now read your message, thank you so much for offering your help, tell me what I can provide
I did the "cheat table from framework code" result is: [Link]
Spoiler
[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat

alloc(newmem,2048)
label(returnhere)
label(originalcode)
label(exit)

newmem: //this is allocated memory, you have read,write,execute access
//place your code here
addss xmm0,["Ace Combat_AH.exe"+502D7E]

originalcode:
mov eax,["Ace Combat_AH.exe"+7EA0E0]

exit:
jmp returnhere

"Ace Combat_AH.exe"+5028F0:
jmp newmem
returnhere:




[DISABLE]
//code from here till the end of the code will be used to disable the cheat
Saved it to the table, closed the game and CE, launched both again, loaded the table and it seems to be working.

Is the address I choose, almost randomly, a good choice? doesn't seem like anything is writing/reading to it, but I don't know how to say

sbryzl
Expert Cheater
Expert Cheater
Posts: 122
Joined: Sat Mar 04, 2017 4:47 am
Reputation: 64

Re: Modify value that is constantly re-written

Post by sbryzl »

When you create the code injection template you need to have the code you are working on highlighted. The one that says

Code: Select all

movss [eax+240],xmm0
that is what to highlight when creating the code injection template.

Might be able to work with the location you used though.

parittolo
Noobzor
Noobzor
Posts: 8
Joined: Wed Jan 27, 2021 11:53 pm
Reputation: 0

Re: Modify value that is constantly re-written

Post by parittolo »

Right, I went for the instruction above it because I made the program crash while trying, forgive the noob mistakes.

so this should be it?

Code: Select all

[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(newmem,2048)
label(returnhere)
label(originalcode)
label(exit)

newmem: //this is allocated memory, you have read,write,execute access
//place your code here
addss xmm0,["Ace Combat_AH.exe"+502D7E]

originalcode:
movss [eax+00000240],xmm0

exit:
jmp returnhere

"Ace Combat_AH.exe"+5028F5:
jmp newmem
nop 3
returnhere:


 
 
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
"Ace Combat_AH.exe"+5028F5:
movss [eax+00000240],xmm0
//Alt: db F3 0F 11 80 40 02 00 00
Just to make sure I'm not fooling myselft, this is the default max fov in the plane customization view (I use this because ingame the fov varies wildly)
[Link] it shows 0.85, which I am almost sure is 85 degrees
[Link] I then add 0.2 to the "empty" address, the FoV one goes to 1.05, 105 degrees

It's a pity about the black circle, it is weird how it comes more into focus the higher the FoV is [Link] 1.3
[Link] 1.5

sbryzl
Expert Cheater
Expert Cheater
Posts: 122
Joined: Sat Mar 04, 2017 4:47 am
Reputation: 64

Re: Modify value that is constantly re-written

Post by sbryzl »

To be honest the more I look at it I think the first injection point might have been better. Here is a table to try. You can edit the values under testfoval to adjust the original range to change and the new value to change it to.

Code: Select all

[ENABLE]

alloc(newmem,1000,"Ace Combat_AH.exe"+5028F0)
label(returnhere)
label(originalcode)

label(testfoval)
registersymbol(testfoval)

newmem:
mov rax,testfoval
comiss xmm0,[rax]
ja short originalcode
comiss xmm0,[rax+4]
jb short originalcode
movss xmm0,[rax+8]
originalcode:
mov eax,["Ace Combat_AH.exe"+7EA0E0]
jmp returnhere

align 4
testfoval:
dd (float).6                        // upper range of field of view
dd (float).5                        // lower range of field of view
dd (float).85                       // change to this value


"Ace Combat_AH.exe"+5028F0:
jmp newmem
returnhere:




[DISABLE]

dealloc(newmem)
unregistersymbol(testfoval)

"Ace Combat_AH.exe"+5028F0:
mov eax,["Ace Combat_AH.exe"+7EA0E0]

parittolo
Noobzor
Noobzor
Posts: 8
Joined: Wed Jan 27, 2021 11:53 pm
Reputation: 0

Re: Modify value that is constantly re-written

Post by parittolo »

Interesting, why would the other place be better?

To use your script, should I just overwrite mine? I don't really understand how it works, most likely I botched it.

So, I can see it doing its thing, if I set a lower bound of .3 and upper of 0.9 (all the range the game uses natively in the plane customization mode) then it is locked to 0.85 or whatever I input in the script.

If I specify a narrower range then it locks the fov only when the game sets it in that range, is that right?

It seems to me like when it is in the specified range it is overwriting the game FoV, so I lose the native zoom functions if it falls within the range.

For example, same specified range in the script, helicopter mission, when I zoom the FoV stays locked to 85, then jumps to 18 (well as soon as it goes lower then 30 it changes, but it is very fast) and then goes back directly to 85 (again from 18 to 30 is very fast) when I release the zoom.
(natively, not zoomed, it should be aroung 47 if I recall correctly)

[Link]

sbryzl
Expert Cheater
Expert Cheater
Posts: 122
Joined: Sat Mar 04, 2017 4:47 am
Reputation: 64

Re: Modify value that is constantly re-written

Post by sbryzl »

I preferred the other location because the eax register was available to use there.

To use a script just open an auto assemble window (ctrl-alt-a), paste the script then under File, assign to cheat table.

If the native zoom is .47 and that's what you want to change then you might want to keep the range tight around it.
testfoval:
dd (float).48 // upper range of field of view
dd (float).46 // lower range of field of view
dd (float).85 // change to this value

parittolo
Noobzor
Noobzor
Posts: 8
Joined: Wed Jan 27, 2021 11:53 pm
Reputation: 0

Re: Modify value that is constantly re-written

Post by parittolo »

Oh ok I get it now.
That is a more elegant solution, sadly the game's camera is "erratic", so the FoV value is always jumping around, it's different between planes, between first/third/cockpit view, when doing many other actions.

This means every time it crosses the boundary of the range that I define in the script I would see a jump from the fixed value to the edge value and then a (usually) very fast transition to the final value written by the game.

Let's take an attack fighter, flying level in third person the FoV is around 47, if I define a narrow 46-48 range and a FoV of 85.
I track an enemy, the game sets the FoV to 33, so I get a huge jump as soon as the value is below 46, then it gets to 33, action ends and the game writes back 47, when it reaches 46 I get the jump to 85.

If I define a more broad range then I lose these camera zoom movements, because the FoV stays fixed to the value defined in the script.
This is not ideal, the game is made with this... cinematic style in mind, also this second case behaviour is similar to just nuking the opcodes and hardcoding a value in myself.


What do you say about the script I have posted? it may be crude, but it works on my machine (lol famous last words)
I admit I have not played extensively with it enabled, or tried different modes or levels, or used it on another PC.
I do have doubts about the "empty" address I have chosen to hold the offset, like what if it used by something else?

But putting aside these considerations, it seems to be working as I want it to, using hotkeys I can add an arbitrary value (>,< or = 0, which I can change at anytime) to the FoV calculated by the game so I get all the native functions, no jumps, no fixed fov, just wider (or narrower, or same) view.

sbryzl
Expert Cheater
Expert Cheater
Posts: 122
Joined: Sat Mar 04, 2017 4:47 am
Reputation: 64

Re: Modify value that is constantly re-written

Post by sbryzl »

If adding a value works better you can do that too. You can widen the range or you can comment out the jumps so that the value is always added regardless of range. You can make a table entry to the value added with a pointer [testfoval+8].

Code: Select all

[ENABLE]

alloc(newmem,1000,"Ace Combat_AH.exe"+5028F0)
label(returnhere)
label(originalcode)

label(testfoval)
registersymbol(testfoval)

newmem:
mov rax,testfoval
comiss xmm0,[rax]
//ja short originalcode
comiss xmm0,[rax+4]
//jb short originalcode
addss xmm0,[rax+8]
originalcode:
mov eax,["Ace Combat_AH.exe"+7EA0E0]
jmp returnhere

align 4
testfoval:
dd (float).8                        // upper range of field of view
dd (float).01                     // lower range of field of view
dd (float).3                       // change to this value


"Ace Combat_AH.exe"+5028F0:
jmp newmem
returnhere:




[DISABLE]

dealloc(newmem)
unregistersymbol(testfoval)

"Ace Combat_AH.exe"+5028F0:
mov eax,["Ace Combat_AH.exe"+7EA0E0]

Post Reply

Who is online

Users browsing this forum: Neqsil