Difference between revisions of "Tutorial:CodeInjection Floats"

From Cheat Engine
Jump to navigation Jump to search
(Working with packed instructions)
m (Reverted edits by This content is not available (Talk) to last revision by TheyCallMeTim13)
 
(3 intermediate revisions by 2 users not shown)
Line 156: Line 156:
  
 
<br>
 
<br>
 
 
== Calculate a value for packed instruction ==
 
== Calculate a value for packed instruction ==
 
Let's say we just can't find an [[Assembler:Commands:ADDPS|ADDPS]] or a [[Assembler:Commands:SUBPS|SUBPS]], and all we have is a [[Assembler:Commands:MOVUPS|MOVUPS]] or a [[Assembler:Commands:MOVAPS|MOVAPS]].
 
Let's say we just can't find an [[Assembler:Commands:ADDPS|ADDPS]] or a [[Assembler:Commands:SUBPS|SUBPS]], and all we have is a [[Assembler:Commands:MOVUPS|MOVUPS]] or a [[Assembler:Commands:MOVAPS|MOVAPS]].
Line 190: Line 189:
 
We could use the [[Auto_Assembler:align|align]] command and then be able to use aligned instructions. So if the injection point looks like this.
 
We could use the [[Auto_Assembler:align|align]] command and then be able to use aligned instructions. So if the injection point looks like this.
 
<pre>
 
<pre>
movaps [eax+10],xmm0
+
movups [eax+10],xmm0
 
</pre>
 
</pre>
  
Line 219: Line 218:
 
</pre>
 
</pre>
  
 +
<br>
 +
== Working with the FPU registry ==
 +
Some times you'll find some opcode that uses the [https://en.wikibooks.org/wiki/X86_Assembly/Floating_Point FPU] registry. These include [[Assembler:Commands:FLD|FLD]], [[Assembler:Commands:FMUL|FMUL]], [[Assembler:Commands:FADD|FADD]], [[Assembler:Commands:FSUB|FSUB]], [[Assembler:Commands:FST|FST]], [[Assembler:Commands:FSTP|FSTP]].
 +
 +
So with singles it might look like this.
 +
<pre>
 +
fld dword ptr [ebp+20]
 +
fmul dword ptr [ebp+40]
 +
fadd dword ptr [eax+10]
 +
fstp dword ptr [eax+10]
 +
</pre>
 +
 +
And if it was with doubles it might look like this.
 +
<pre>
 +
fld qword ptr [ebp+20]
 +
fmul qword ptr [ebp+40]
 +
fadd qword ptr [eax+10]
 +
fstp qword ptr [eax+10]
 +
</pre>
 +
 +
So say we have some opcode that decreases health that looks like this.
 +
<pre>
 +
fld dword ptr [eax+10]
 +
fsub dword ptr [ebp+20]
 +
fstp dword ptr [eax+10]
 +
</pre>
 +
 +
So the add a multiplier to this we could make a script like this.
 +
<pre>
 +
//...
 +
alloc(someMem, 0x400)
 +
//...
 +
label(someSymbol)
 +
registerSymbol(someSymbol)
 +
//...
 +
someMem:
 +
  //...
 +
  fld dword ptr [ebp+20]
 +
  fmul dword ptr [someSymbol]
 +
  fld dword ptr [eax+10]
 +
  fsub st(0),st(1)
 +
  fstp dword ptr [eax+10]
 +
  fstp st(0)
 +
  //...
 +
  jmp return
 +
  //...
 +
  someSymbol:
 +
    dd (float)0.25
 +
//...
 +
</pre>
  
 
<br>
 
<br>

Latest revision as of 19:10, 18 March 2019


This tutorial builds on the topic of Code Injection:


Let's say you have a float and some code that increases the value.

addss [eax+10],xmm0
Note: SS is for singles and SD is for doubles.

What if what writes to the value is only a MOVSS. Try to find a spot above the write instruction that has an ADDSS (or a SUBSS depending on what you want to do).

addss xmm0,xmm1
//...
movss [eax+10],xmm0


Editable value[edit]

We could use a label, giving it some memory. And optionally register it so the label can be used on the table as an address.

//...
alloc(someMem, 0x400)
//...
label(someSymbol)
registerSymbol(someSymbol)
//...
someMem:
  //...
  movss xmm0,[someSymbol]
  addss [eax+10],xmm0
  //...
  jmp return
  //...
  someSymbol:
    dd (float)100
//...


Adding a Multiplier[edit]

We could add an editable value like above but use MULSS to add a multiplier to the script.

//...
alloc(someMem, 0x400)
//...
label(someSymbol)
registerSymbol(someSymbol)
//...
someMem:
  //...
  mulss xmm0,[someSymbol]
  addss [eax+10],xmm0
  //...
  jmp return
  //...
  someSymbol:
    dd (float)100
//...


Calculate a value for a Multiplier[edit]

Let's say we just can't find an ADDSS or a SUBSS, and all we have is a MOVSS.

movss [eax+10],xmm0

We can just do some math in the script, to calculate a value for a multiplier.

//...
alloc(someMem, 0x400)
//...
label(someSymbol)
registerSymbol(someSymbol)
//...
someMem:
  //...
  subss xmm0,[eax+10]
  mulss xmm0,[someSymbol]
  addss xmm0,[eax+10]
  movss [eax+10],xmm0
  //...
  jmp return
  //...
  someSymbol:
    dd (float)10
//...


Working with doubles[edit]

Let's say the game use doubles, we can use ADDSD, SUBSD, MULSD, and MOVSD instead. We just need to also make our scripts value a double.

movsd [eax+10],xmm0

So to calculate a value for a multiplier.

//...
alloc(someMem, 0x400)
//...
label(someSymbol)
registerSymbol(someSymbol)
//...
someMem:
  //...
  subsd xmm0,[eax+10]
  mulsd xmm0,[someSymbol]
  addsd xmm0,[eax+10]
  movsd [eax+10],xmm0
  //...
  jmp return
  //...
  someSymbol:
    dq (double)10
//...


Working with packed instructions[edit]

Some times (especially with vectors) you'll see packed instructions, like MOVAPS, MOVUPS, ADDPS, SUBPS, MULPS. These type of instructions work on 16 bytes at a time.

So let's say you have some code accessing the player coordinate deltas, and it's using packed instructions.

addps [eax+10],xmm0

So let's add a multiplier for this.

//...
alloc(someMem, 0x400)
//...
label(someSymbol)
registerSymbol(someSymbol)
//...
someMem:
  //...
  mulps xmm0,[someSymbol]
  addps [eax+10],xmm0
  //...
  jmp return
  //...
  someSymbol:
    dd (float)1.75
    dd (float)1.75
    dd (float)1.25
    dd (float)1
//...


Calculate a value for packed instruction[edit]

Let's say we just can't find an ADDPS or a SUBPS, and all we have is a MOVUPS or a MOVAPS.

movups [eax+10],xmm0

We can just do some math in the script, to calculate a value for a multiplier.

//...
alloc(someMem, 0x400)
//...
label(someSymbol)
registerSymbol(someSymbol)
//...
someMem:
  //...
  subps xmm0,[eax+10]
  mulps xmm0,[someSymbol]
  addps xmm0,[eax+10]
  movups [eax+10],xmm0
  //...
  jmp return
  //...
  someSymbol:
    dd (float)1.75
    dd (float)1.75
    dd (float)1.25
    dd (float)1
//...

We could use the align command and then be able to use aligned instructions. So if the injection point looks like this.

movups [eax+10],xmm0

Then we could make a script like this.

//...
alloc(someMem, 0x400)
//...
label(someSymbol)
registerSymbol(someSymbol)
//...
someMem:
  //...
  subps xmm0,[eax+10]
  mulps xmm0,[someSymbol]
  addps xmm0,[eax+10]
  movaps [eax+10],xmm0
  //...
  jmp return
  //...
  align 10 CC
  someSymbol:
    dd (float)1.75
    dd (float)1.75
    dd (float)1.25
    dd (float)1
//...


Working with the FPU registry[edit]

Some times you'll find some opcode that uses the FPU registry. These include FLD, FMUL, FADD, FSUB, FST, FSTP.

So with singles it might look like this.

fld dword ptr [ebp+20]
fmul dword ptr [ebp+40]
fadd dword ptr [eax+10]
fstp dword ptr [eax+10]

And if it was with doubles it might look like this.

fld qword ptr [ebp+20]
fmul qword ptr [ebp+40]
fadd qword ptr [eax+10]
fstp qword ptr [eax+10]

So say we have some opcode that decreases health that looks like this.

fld dword ptr [eax+10]
fsub dword ptr [ebp+20]
fstp dword ptr [eax+10]

So the add a multiplier to this we could make a script like this.

//...
alloc(someMem, 0x400)
//...
label(someSymbol)
registerSymbol(someSymbol)
//...
someMem:
  //...
  fld dword ptr [ebp+20]
  fmul dword ptr [someSymbol]
  fld dword ptr [eax+10]
  fsub st(0),st(1)
  fstp dword ptr [eax+10]
  fstp st(0)
  //...
  jmp return
  //...
  someSymbol:
    dd (float)0.25
//...


See Also[edit]