Page 1 of 1

Is my multiply script correct?

Posted: Fri Sep 13, 2019 2:51 pm
by Mister Modification
Hi again! :)

This time I am working on some kind of super jump script.

I am using IDA to generate pseudo .c code for better understanding.

Can someone tell me if that script multiplies a value with my value and stores the output again?

The original function multiplies x, y and z with 0.5 while jumping and stores results.

My goal is to multiply z with a value I like to define.

Examples:

z * 0.4
z * 0.9
z * 0.2

I will comment everything. :wink:

--------------------------------------------------------------------------------

Code: Select all

[ENABLE]

aobscanmodule(INJECT,game.exe,bla bla bla) // should be unique
alloc(newmem,$1000)

label(code)
label(return)

alloc(multi,4) // allocs memory for a double

multi:
dq (double)0.3 // defines multi's type and value 

newmem:

code:
  fld dword ptr [esp+28] // load z related value
  fld qword ptr [multi] // load my 0.3 
  fmul [esp+28] // Multiply [mutli] with [esp+28] ???
  fstp dword ptr [esp+08] // stores my output where normal output would be stored
  jmp return

INJECT:
  jmp newmem
  nop 3
return:
registersymbol(INJECT)

[DISABLE]

INJECT:
  db D9 44 24 28 D8 4C 24 30

unregistersymbol(INJECT)
dealloc(newmem)
dealloc(multi)
--------------------------------------------------------------------------------

Thanks for any help! :lol:

Re: Is my multiply script correct?

Posted: Sat Oct 05, 2019 8:41 pm
by HenryEx
You're allocating 4 bytes for a double, that's sort of an issue :p

First, if you want to know more about how the FPU works (though it's been superceded by the SSE instructions and the XMM registers), read up on this site. It has commentary, in-depth detail and usage examples for all instructions, it's helpful, easy to understand and what i used when i first tried to do that:
[Link]

If you're loading the z value first and then your multiplier, the multiplier will be at the top of the stack ( ST(0) ), and the z value at position 1 under it ( ST(1) ).

If you do

Code: Select all

 fmul [esp+28]
That means you multiply the value of the top register ST(0) with the value at the memory location you specified, in this case whatever is at [esp+28].

If you load both values into the FPU, you should multiplay them like this:

Code: Select all

 fmulp st(1),st(0)
This will multiply value 1 with value 0, store the result in value 1, then pop the first value off the stack (value 0), so value 1 becomes the new value 0. Then you store (and pop) said new value with fstp.

Given that your load address and your store address seem to be different though, you can just cut one of these out and do like this:

Code: Select all

code:
  fld qword ptr [multi] // load multiplier from allocated address
  fmul dword ptr [esp+28]  // Multiply with z value stored at [esp+28]
  fstp dword ptr [esp+08]  // store and pop new value from the floating stack to [esp+08]
  jmp return
Note that you need to specify address length for fmul too, if you want to multiply with a memory location, just like with fstp. I assumed it's a dword ptr here, you'll have to adjust that if it's not.