got a problem while set up damage reduction, please take a look

Memory scanning, code injection, debugger internals and other gamemodding related discussion
Post Reply
tesfileview
Noobzor
Noobzor
Posts: 7
Joined: Sat Sep 03, 2022 7:52 am
Reputation: 0

got a problem while set up damage reduction, please take a look

Post by tesfileview »

code:
////////////////////////////////

original:
movss [old value] , [new value]

damage reduction:
subss [new value] , [old value]
divss [new value] (damage) , 2
addss [new value] , [old value]
movss [old value] , [new value]

*[new value] — [old value] = [damage]
////////////////////////////////

the way of getting [damage] is subtract [old value] with [new value], but I found out in some game [new value] won't drop below zero, then I can't get the real [damage] by subtract old value.

because [new value] need to be negative number and subtract [old value] become [damage] divide it then add [old value] back, finally check [new value] is below zero or not.

but now [new value] won't below zero, that will be dead loop if you run above code because [damage] only get negative of [old value], after divides add [old value] back then [new value] always become half of [old value], it means hp won't goes below zero.

is there another to get damage value especially this case.

panraven
Table Makers
Table Makers
Posts: 121
Joined: Fri Mar 03, 2017 12:03 am
Reputation: 108

Re: got a problem while set up damage reduction, please take a look

Post by panraven »

Give it a minimum threshold to mean zero or below?

Code: Select all

cmp   dword ptr[old value],(float)0.99
jg    short @f
  mov dword ptr[old value],(float)0
@@:
or make the modified damage has a minimum 1 dmg after div (the code is left as an exercise :-] )

tesfileview
Noobzor
Noobzor
Posts: 7
Joined: Sat Sep 03, 2022 7:52 am
Reputation: 0

Re: got a problem while set up damage reduction, please take a look

Post by tesfileview »

panraven wrote:
Mon Sep 05, 2022 11:34 am
Give it a minimum threshold to mean zero or below?

Code: Select all

cmp   dword ptr[old value],(float)0.99
jg    short @f
  mov dword ptr[old value],(float)0
@@:
or make the modified damage has a minimum 1 dmg after div (the code is left as an exercise :-] )
thanks for help, I am thinking about replace damage value by compare is [new value] zero or not, but that mean I can't use div to reduce damage when the hp take its last hit. I want to confirm is there any way to get the exact damage value when the register won't below negative value?

amorrow28
Expert Cheater
Expert Cheater
Posts: 81
Joined: Mon Jul 04, 2022 9:42 pm
Reputation: 46

Re: got a problem while set up damage reduction, please take a look

Post by amorrow28 »

I would not try to infer damage from that move instruction, since as you noted the new health already has accounted for damage being more than old health. Instead, go back a few instructions and look for the real damage value.

If I had to guess, it might be a comiss instruction followed by a jump. Something like:

comiss [health],[damage] - see if damage is more than health
jump if health is above or equal to damage to next
movss damage, health
next:
the movss instruction you found

In this case, you would want to inject before the compare instruction, so that the damage can still equal health regardless of how close to death you are.

The real code will not look like my example above BTW as the compare instruction cannot compare two values in memory. At least one of them will have been loaded into a register first. We also don't know what architecture is involved here, my example above is using x64/SSE registers, it will look different if the game uses the FPU instead, etc.

tesfileview
Noobzor
Noobzor
Posts: 7
Joined: Sat Sep 03, 2022 7:52 am
Reputation: 0

Re: got a problem while set up damage reduction, please take a look

Post by tesfileview »

amorrow28 wrote:
Mon Sep 05, 2022 6:56 pm
I would not try to infer damage from that move instruction, since as you noted the new health already has accounted for damage being more than old health. Instead, go back a few instructions and look for the real damage value.

If I had to guess, it might be a comiss instruction followed by a jump. Something like:

comiss [health],[damage] - see if damage is more than health
jump if health is above or equal to damage to next
movss damage, health
next:
the movss instruction you found

In this case, you would want to inject before the compare instruction, so that the damage can still equal health regardless of how close to death you are.

The real code will not look like my example above BTW as the compare instruction cannot compare two values in memory. At least one of them will have been loaded into a register first. We also don't know what architecture is involved here, my example above is using x64/SSE registers, it will look different if the game uses the FPU instead, etc.
amorrow28 wrote:
Mon Sep 05, 2022 6:56 pm
I would not try to infer damage from that move instruction, since as you noted the new health already has accounted for damage being more than old health. Instead, go back a few instructions and look for the real damage value.

If I had to guess, it might be a comiss instruction followed by a jump. Something like:

comiss [health],[damage] - see if damage is more than health
jump if health is above or equal to damage to next
movss damage, health
next:
the movss instruction you found

In this case, you would want to inject before the compare instruction, so that the damage can still equal health regardless of how close to death you are.

The real code will not look like my example above BTW as the compare instruction cannot compare two values in memory. At least one of them will have been loaded into a register first. We also don't know what architecture is involved here, my example above is using x64/SSE registers, it will look different if the game uses the FPU instead, etc.
I had find something on the way you told me but can't still a way to get damage value.
above the movss instruction, there has two comiss instruction is connecting with xmm0 register.

////////////////////////////////////////////////
Address Opcode
1 comiss xmm1, xmm0
2 jna 5
3 movaps xmm0, xmm1
4 jmp 8
5 comiss xmm2, xmm0
6 ja 8
7 movaps xmm0, xmm2
8 movss [esi+6c] (health address), xmm0
////////////////////////////////////////////////
after a few tests, I may say the value of xmm1 always below 1 and xmm2 same as max health. I try to disable address 1-3 instruction because I thought this is the code which does not allow xmm0 goes negative, but the script still act like before. I also disable address 5-7 still nothing changes in fight. What should I do from these two instructions or keep look up code on above?

amorrow28
Expert Cheater
Expert Cheater
Posts: 81
Joined: Mon Jul 04, 2022 9:42 pm
Reputation: 46

Re: got a problem while set up damage reduction, please take a look

Post by amorrow28 »

You haven’t gone back far enough, you only have code that sets upper and lower bounds. If I’m reading the code above correctly (the order of instructions always confuse me), final health (xmm0 at the end) must be between the values of xmm1 and xmm2. If it’s above xmm1, it’ll be lowered to xmm1. If it’s below xmm2, it’ll be raised to xmm2. (Think of them as max and min.) Therefore you still don’t have enough information to deduce damage dealt.

Keep going backwards. My suggestion is to take your memory address and find what accesses it (not just write). Then sort by memory address, and find the read instruction right above the read instruction. The code you need will be somewhere between the read and the write.

EDIT: Actually, I take it back, you might have enough information. xmm0 prior to line 1 should be the final health before any bounds are applied. So if you read your current health and subtract xmm0 prior to line 0, you should have your damage (I think). Btw, I think you have a shared instruction that might also handle healing, so you’ll need to filter a bit to make sure your injection only changes the values when you want them to.
One possible solution
newmem:
subss xmm0, [health]
mulss xmm0, [dmgfraction]
addss xmm0, [health]

code:
comiss xmm1,xmm0
jmp return

dmgfraction:
dd (float)0.5

INJECT:
jmp newmem
return:

My solution should work because it’s actually storing the inverse of damage in xmm0 temporarily. But it might not, you may need to mess with it.

tesfileview
Noobzor
Noobzor
Posts: 7
Joined: Sat Sep 03, 2022 7:52 am
Reputation: 0

Re: got a problem while set up damage reduction, please take a look

Post by tesfileview »

i want to tidy up the topic. I can get damage value by first script I had send here except hit point take its last hit (xmm0 goes to zero then mov to health address), let me describe the issue completely.

/////////////////////////////////////////////////////////////
assume xmm0 value -500f, health value 1000f
in this case, damage reduction can be executed perfectly.

subss xmm0, [health value]
(Damage value = -1500f)

mulss xmm0, [0.5f]
(Makes damage value to half, now damage value = -750f)

addss xmm0, [health value]
(Add [health address] back to xmm0(damage value), now xmm0 is 250f)
/////////////////////////////////////////////////////////////

when xmm0 move to [health address] the character supposed to die but after the damage reduction there has 250 hp left and character back to live.
now the issue is the value of xmm0 won't below zero, that means when hp take its last hit, the subtraction btw xmm0 and [health value] is pointless.
///////////////////////////////////////////
assume xmm0 value 0f, health value 1000f

subss xmm0, [health value]
(Damage value = -1000f)

mulss xmm0, [0.5f]
(Damage value = -500f)

addss xmm0, [health value]
(-500f + 1000f = 500f)
///////////////////////////////////////////
this is the problem, after the damage reduction xmm0 always become half of [health value] over and over, so xmm0 needs to be negative when damage enough to take character down, then the script will reduce damage value put it back and check is it still could make character died.
right now, I am looking for where's the code which limit xmm0 not below zero and I can't think out other way to shove this problem.

by the way, I already set up damage reduction in some game and works fine, each game only needs one script, and all scripts writes by same way as we are talking about. that's why I'm so anxious to find a way to fix issue because I haven't met a register that won't store negative value before.

this question takes too much time, if we both are the first time met this issue, I would better to explore a lot more in the game, Thanks for the ideas.

amorrow28
Expert Cheater
Expert Cheater
Posts: 81
Joined: Mon Jul 04, 2022 9:42 pm
Reputation: 46

Re: got a problem while set up damage reduction, please take a look

Post by amorrow28 »

Did you inject above the first comiss as I indicated? (Above line 1). If you did, the you are still dealing with numbers after bounds-checking has already occurred.

I suggest a full trace of the function, follow the registers from the most recent health read to the final health write. My guess in this case is that you won’t be looking at more than 100 lines of code (even even close to that). But sometimes I find myself tracing 15000 lines of code between value read to value write to find the one spot where a value is conditionally modified.

Post Reply

Who is online

Users browsing this forum: No registered users