Alright, after some debugging and tracing, I figured out the relationship between the damage you see in character inventory and the real one actually transformed/calculated when performing an Attack or WeaponTypeAttack. Here goes, big post.. elevated language.. for semi-connoisseurs
Continued from the
previous post, where I said that I started debugging the
ACEFightSettings structure to see what accesses its memory when a) doing nothing; b) hovering the mouse over an enemy to display the stealth-type attack options; c) actually performing the attack. Updated view below for 1.0.6:
I am basically doing this now:
Then hitting F to start the attack (while debugging the ACEFightSettings structure's memory with an exception breakpoint - - change that in CE Settings > Debugger Options - - ranging from 0x0 till 0x690 offset or so):
ACEFightSettings can be acquired from here:
In my case, as you can see from the second picture above, it's
0x7AF24890. Cleaning up the code, this would be the logic:
Code: Select all
mov rax,[ACOdyssey.exe+5829710]
mov r10,[rax+F38]
mov rax,[r10+8]
shl rax,20
sar rax,3F
and rax,[r10]
rax == read ptr
mov r10,[rax+28]
mov rcx,[r10+8]
shl rcx,20
sar rcx,3F
and rcx,[r10]
rcx == read ptr
What I noticed in Anvil (or maybe I've not studied x64 that much) is that Ubi uses this ASM-format a lot:
Code: Select all
mov rax,[ACOdyssey.exe+5829710]
mov r10,[rax+F38]
mov rax,[r10+8]
shl rax,20
sar rax,3F
and rax,[r10]
Which would be the equivalent of:
Code: Select all
mov rax,[ACOdyssey.exe+5829710]
mov r10,[rax+F38]
mov rax,[r10]
Anyway, back to our analysis. I started tracing that exact location:
Code: Select all
ACOdyssey.exe+21B26F4 - 48 8B 05 15706703 - mov rax,[ACOdyssey.exe+5829710] { [15542C9A0] }
Set break and stop at:
Code: Select all
ACOdyssey.exe+21B2741 - FF 90 00010000 - call qword ptr [rax+00000100]
Check FPU window to see the values of the MMX registers:
Then F8 over the call and check again:
Continue tracing till here:
Code: Select all
ACOdyssey.exe+21B2762 - F3 0F59 FE - mulss xmm7,xmm6
Check FPU window again:
As you can see, the next instruction to be executed is xmm7 * xmm6 (69743.00 * 1.00), which gives exactly
69743.00. But what is this value? Well..
Touché, pussycat!
So, sometime before the location we stopped at, there's some reading done which returns that damage amount of ours. Could it be in that CALL above?
Code: Select all
ACOdyssey.exe+21B274E - 0F28 F0 - movaps xmm6,xmm0
ACOdyssey.exe+21B2751 - E8 FAEDC900 - call ACOdyssey.exe+2E51550 <-- here
ACOdyssey.exe+21B2756 - 8B C0 - mov eax,eax
ACOdyssey.exe+21B2758 - 0F57 FF - xorps xmm7,xmm7
ACOdyssey.exe+21B275B - 8B CB - mov ecx,ebx
ACOdyssey.exe+21B275D - F3 48 0F2A F8 - cvtsi2ss xmm7,rax
ACOdyssey.exe+21B2762 - F3 0F59 FE - mulss xmm7,xmm6
But of course. Let's see what happens inside:
Code: Select all
ACOdyssey.exe+2E51550 - 8B 81 8C010000 - mov eax,[rcx+0000018C]
ACOdyssey.exe+2E51556 - C3 - ret
Well.. that was fast. And who is RCX, might I ask?
Code: Select all
IStruct: 0x167302290
IName: 0x1450BBDD0
ObjStr: PlayerProgressionManager
ObjHash: 0x9713A15F
So..
PlayerProgressionManager + 0x18C == Assassin Damage
Neat. This would be the address I heard of in some posts around pages 16-20. Someone found the assassin damage value by swapping items and scanning for the on-screen values. Think I saw
this table containing some of these offsets.
You can get
PlayerProgressionManager from the MOV above the CALL:
Code: Select all
ACOdyssey.exe+21B2747 - 48 8B 0D 1ABC6703 - mov rcx,[ACOdyssey.exe+582E368] // PlayerProgressionManager
ACOdyssey.exe+21B274E - 0F28 F0 - movaps xmm6,xmm0
ACOdyssey.exe+21B2751 - E8 FAEDC900 - call ACOdyssey.exe+2E51550
Add this to your list as such:
If you now swap weapons, you'll see the value changes.
This value is read in real time in damage calculations; so let's do some testing:
a) as it is, I see this while hovering over an enemy:
b) changing value to 10000 from 69473 shows this:
So the white/red bar changes display as I change the value
Well, that's the calculated damage you'll do. Of course that if you set it to > 69743 you'll instantly kill the guard. Question would be: you want to change the Assassin Damage value.. or fiddle with the multiplier past the CALL?
I think the multiplier is a better choice, as you can always change weapons.. which would affect the value in the PlayerProgressionManager. But yeah, that can be hooked as well to return the amount you want. Choices, choices..
Let's take a look at PlayerProgressionManager structure and find
Health,
Hunter Damage,
Warrior Damage and
Armor. Simply swapping an item will reveal its offset:
So there you have it
+0x148 = Health
+0x150 = Armor
+0x180 = Second Slot damage
+0x184 = First Slot damage
+0x188 = Hunter Damage
+0x18C = Assassin Damage
BR,
Sun