View previous topic :: View next topic |
Author |
Message |
Mr. Starman Newbie cheater
Reputation: 0
Joined: 09 Oct 2012 Posts: 16
|
Posted: Mon Feb 15, 2016 10:35 am Post subject: How To Halve/Double Value in Float Stack |
|
|
I've been trying to make a code for AOE2 HD that either doubles the damage you deal to your opponent or halves the damage dealt to yourself.
Turns out the game uses float stack to store its damage value and I don't know how to manipulate that.
Code: | AoK HD.exe+14CC08 - F3 0F11 04 24 - movss [esp],xmm0
AoK HD.exe+14CC0D - 51 - push ecx
AoK HD.exe+14CC0E - FF 75 08 - push [ebp+08]
AoK HD.exe+14CC11 - 8B 42 7C - mov eax,[edx+7C]
AoK HD.exe+14CC14 - 8B CE - mov ecx,esi
AoK HD.exe+14CC16 - FF D0 - call eax
AoK HD.exe+14CC18 - D8 6E 30 - fsubr dword ptr [esi+30]
AoK HD.exe+14CC1B - 83 CB FF - or ebx,-01
AoK HD.exe+14CC1E - D9 5D F0 - fstp dword ptr [ebp-10]
AoK HD.exe+14CC21 - F3 0F10 45 F0 - movss xmm0,[ebp-10]
AoK HD.exe+14CC26 - F3 0F11 46 30 - movss [esi+30],xmm0
|
It starts from fsubr, where it calls the damage value in stack and then uses it to sub the HP value inside esi+30 and then puts it back to the stack.
Said stack then gets copied as the value for ebp-10, value for ebp-10 gets copied for register xmm0, and then value of xmm0 gets copied to the final destination of value esi+30.
I need to insert an instruction that doubles (since this is tested on an enemy) the damage value in stack. Problem with using stack instead of register is that I can't just copy the original code again since stack is gone once used.
Any help here? I'm just starting to learn all this assembly code injection thing.
|
|
Back to top |
|
 |
hhhuut Grandmaster Cheater
Reputation: 6
Joined: 08 Feb 2015 Posts: 607
|
Posted: Mon Feb 15, 2016 11:02 am Post subject: |
|
|
The instruction "fmul" (or "fmulp") might help you here. With that you can multiply two fpu-stack values
Code: | fld dword ptr [eax+04]
mov dword ptr [eax+04],(float)2
fld dword ptr [eax+04]
fmulp st(1),st(0)
fstp dword ptr [eax+04] |
|
|
Back to top |
|
 |
Mr. Starman Newbie cheater
Reputation: 0
Joined: 09 Oct 2012 Posts: 16
|
Posted: Mon Feb 15, 2016 11:12 am Post subject: |
|
|
hhhuut wrote: | The instruction "fmul" (or "fmulp") might help you here. With that you can multiply two fpu-stack values
Code: | fld dword ptr [eax+04]
mov dword ptr [eax+04],(float)2
fld dword ptr [eax+04]
fmulp st(1),st(0)
fstp dword ptr [eax+04] |
|
Let me get this straight.
Line 1 sends the original damage value to the st(0) stack.
Line 2 inserts the value 2 into the register.
Line 3 sends the value in the register to the st (1) stack.
Line 4 multiplies them and puts the result back to the stack (st (0), I assume)
Line 5 gets the value from the stack and puts it into the register, then it pops it out back to the stack (st (0) again, I guess)
So how do you know why you should use the register eax+04?
|
|
Back to top |
|
 |
hhhuut Grandmaster Cheater
Reputation: 6
Joined: 08 Feb 2015 Posts: 607
|
Posted: Mon Feb 15, 2016 11:35 am Post subject: |
|
|
Explanation of my code:
st(0) is always the first value on the stack!
Imagine that before any of our instructions is executed the fpu-stack looks like this:
st(0): value1
st(1): value2
st(2): value3
...
So in line 1 I put the original damage value (eax+04 is just an example here) onto the fpu-stack, so that it looks like that:
st(0): original damage vlue
st(1): value1
st(2): value2
st(3): value3
...
In Line 2 I move the multiplier (in this case 2 to double the value, otherwise you've to put "0.5" here) into the address and put it onto the fpu-stack in line 3 once more. The FPU-Stack now looks like this:
st(0): 2
st(1): original damage value
st(2): value1
st(3): value2
st(4): value3
...
In line 4 now, I'm doing the actual multipilcation. A basic math equation would look like that:
st(1) = st(1) * st(0)
I hope you noticed that the instruction is "fmulp", not just "fmul". The "p" stands for "pop" and removes the topmost value from the fpu-stack. So after the multiplication instruction the fpu-stack looks like that:
st(0): original damage value multiplied with 2
st(1): value1
st(2): value2
st(3): value3
...
The last instruction now stores the multiplied value into the source address once more and removes it from the fpu-stack. After that, our fpu-stack looks like before:
st(0): value1
st(1): value2
st(2): value3
...
Usually you should make sure, that after your own code got executed, the stack (no matter if fpu or normal stack) looks exactly like it has been before your code got executed. Otherwise you may cause the game to crash or bug ...
|
|
Back to top |
|
 |
Mr. Starman Newbie cheater
Reputation: 0
Joined: 09 Oct 2012 Posts: 16
|
Posted: Mon Feb 15, 2016 7:36 pm Post subject: |
|
|
Tried it and it instantly kills the enemy and then the game crashes
Code: | alloc(newmem,2048)
label(returnhere)
label(originalcode)
label(exit)
newmem: //this is allocated memory, you have read,write,execute access
//place your code here
mov dword ptr [esi+30],(float)2
fld dword ptr [esi+30]
fmulp st(1),st(0)
originalcode:
fsubr dword ptr [esi+30]
or ebx,-01
exit:
jmp returnhere
"AoK HD.exe"+14CC18:
jmp newmem
nop
returnhere: |
Should you use the register used by fsubr dword ptr or should you use an unused one? (I don't know how to find that).
And I omitted the first line since the value is already at the stack. The problem is I don't know which instruction sends the damage value to the stack. If I know, I should be able to use the register there with the same value safely.
And I somehow corrupt the game data by injecting the above code. Gotta recheck the integrity at Steam first for it to run.
|
|
Back to top |
|
 |
Zanzer I post too much
Reputation: 126
Joined: 09 Jun 2013 Posts: 3278
|
Posted: Mon Feb 15, 2016 8:11 pm Post subject: |
|
|
Code: | alloc(newmem,2048)
label(returnhere)
label(originalcode)
label(exit)
label(myvar1)
label(myvar2)
newmem:
fld [myvar1]
fmulp
originalcode:
fsubr dword ptr [esi+30]
or ebx,-01
exit:
jmp returnhere
myvar1:
dd (float)0.5
myvar2:
dd (float)2.0
"AoK HD.exe"+14CC18:
jmp newmem
nop
returnhere: |
|
|
Back to top |
|
 |
Mr. Starman Newbie cheater
Reputation: 0
Joined: 09 Oct 2012 Posts: 16
|
Posted: Mon Feb 15, 2016 8:22 pm Post subject: |
|
|
dd puts the value inside the variable, right? So why is it executed after the fld instruction?
|
|
Back to top |
|
 |
Zanzer I post too much
Reputation: 126
Joined: 09 Jun 2013 Posts: 3278
|
Posted: Mon Feb 15, 2016 8:30 pm Post subject: |
|
|
The DDs initialize the two variables. This executes immediately when you enable the script.
The FLD is used to load either 2.0 or 0.5 on to the stack.
Then FMULP simply multiplies that value with the one already there.
This will double or halve the value that was previously present.
|
|
Back to top |
|
 |
Mr. Starman Newbie cheater
Reputation: 0
Joined: 09 Oct 2012 Posts: 16
|
Posted: Mon Feb 15, 2016 11:10 pm Post subject: |
|
|
Thanks, it works!
Now to differentiate it between player and enemy since they both use the same code.
Now how do I look at the register at fsubr instead of movss since the debugger said its eax is not 3 even though it passed my eax=3 comparison check (since eax=3 for my player units)
Edit: Nevermind. Just had to use the dissect data structure instead of doing it manually like with the resource code.
Edit 2:
Welp, the identification value changed when the game restarted. Dunno what to do now.
|
|
Back to top |
|
 |
Mr. Starman Newbie cheater
Reputation: 0
Joined: 09 Oct 2012 Posts: 16
|
Posted: Tue Feb 16, 2016 6:34 pm Post subject: |
|
|
Help please?
|
|
Back to top |
|
 |
++METHOS I post too much
Reputation: 92
Joined: 29 Oct 2010 Posts: 4197
|
Posted: Tue Feb 16, 2016 7:15 pm Post subject: |
|
|
Keep looking. More methods can be found here.
|
|
Back to top |
|
 |
Mr. Starman Newbie cheater
Reputation: 0
Joined: 09 Oct 2012 Posts: 16
|
Posted: Wed Feb 17, 2016 5:26 am Post subject: |
|
|
So, I got this promising pointer imgur. com / Cooxe9v (sorry, can't post link yet) that leads to a promising address but I don't know how I would write that in the assembly code. Any help please?
Edit:
Nevermind, I did it by borrowing eax, pushing and popping its original value. It seems the code is stable this time since it still works after I restarted the game.
Still crashes the game when a scenario ends though. Gotta turn that shit off first. And it somehow made it so that you gotta verify the game on Steam again.
|
|
Back to top |
|
 |
|