Difference between revisions of "Tutorial:CodeInjection Floats"
 (Replaced content with '<span style="font-size:25px;color:red">Sorry! Content not available.</span>')  | 
				m (Reverted edits by This content is not available (Talk) to last revision by TheyCallMeTim13)  | 
				||
| Line 1: | Line 1: | ||
| − | <  | + | <!-- Tutorial:CodeInjection_Floats -->  | 
| + | [[Category:Tutorial]]  | ||
| + | [[Category:Auto Assembler]]  | ||
| + | {{DISPLAYTITLE:Code Injection - Working with Floats}}  | ||
| + | This tutorial builds on the topic of Code Injection:  | ||
| + | {{TutorialsCodeInjection}}  | ||
| + | |||
| + | <br>  | ||
| + | Let's say you have a float and some code that increases the value.  | ||
| + | <pre>  | ||
| + | addss [eax+10],xmm0  | ||
| + | </pre>  | ||
| + | :Note: '''SS''' is for singles and '''SD''' is for doubles.  | ||
| + | <blockquote>  | ||
| + | What if what writes to the value is only a [[Assembler:Commands:MOVSS|MOVSS]]. Try to find a spot above the write instruction that has an [[Assembler:Commands:ADDSS|ADDSS]] (or a [[Assembler:Commands:SUBSS|SUBSS]] depending on what you want to do).  | ||
| + | <pre>  | ||
| + | addss xmm0,xmm1  | ||
| + | //...  | ||
| + | movss [eax+10],xmm0  | ||
| + | </pre>  | ||
| + | </blockquote>  | ||
| + | |||
| + | <br>  | ||
| + | == Editable value ==  | ||
| + | We could use a [[Auto Assembler:label|label]], giving it some memory. And optionally [[Auto_Assembler:registerSymbol|register]] it so the label can be used on the table as an address.  | ||
| + | <pre>  | ||
| + | //...  | ||
| + | alloc(someMem, 0x400)  | ||
| + | //...  | ||
| + | label(someSymbol)  | ||
| + | registerSymbol(someSymbol)  | ||
| + | //...  | ||
| + | someMem:  | ||
| + |   //...  | ||
| + |   movss xmm0,[someSymbol]  | ||
| + |   addss [eax+10],xmm0  | ||
| + |   //...  | ||
| + |   jmp return  | ||
| + |   //...  | ||
| + |   someSymbol:  | ||
| + |     dd (float)100  | ||
| + | //...  | ||
| + | </pre>  | ||
| + | |||
| + | <br>  | ||
| + | == Adding a Multiplier ==  | ||
| + | We could add an editable value like above but use [[Assembler:Commands:MULSS|MULSS]] to add a multiplier to the script.  | ||
| + | <pre>  | ||
| + | //...  | ||
| + | alloc(someMem, 0x400)  | ||
| + | //...  | ||
| + | label(someSymbol)  | ||
| + | registerSymbol(someSymbol)  | ||
| + | //...  | ||
| + | someMem:  | ||
| + |   //...  | ||
| + |   mulss xmm0,[someSymbol]  | ||
| + |   addss [eax+10],xmm0  | ||
| + |   //...  | ||
| + |   jmp return  | ||
| + |   //...  | ||
| + |   someSymbol:  | ||
| + |     dd (float)100  | ||
| + | //...  | ||
| + | </pre>  | ||
| + | |||
| + | <br>  | ||
| + | == Calculate a value for a Multiplier ==  | ||
| + | Let's say we just can't find an [[Assembler:Commands:ADDSS|ADDSS]] or a [[Assembler:Commands:SUBSS|SUBSS]], and all we have is a [[Assembler:Commands:MOVSS|MOVSS]].  | ||
| + | <pre>  | ||
| + | movss [eax+10],xmm0  | ||
| + | </pre>  | ||
| + | |||
| + | We can just do some math in the script, to calculate a value for a multiplier.  | ||
| + | <pre>  | ||
| + | //...  | ||
| + | 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  | ||
| + | //...  | ||
| + | </pre>  | ||
| + | |||
| + | <br>  | ||
| + | == Working with doubles ==  | ||
| + | Let's say the game use doubles, we can use [[Assembler:Commands:ADDSD|ADDSD]], [[Assembler:Commands:SUBSD|SUBSD]], [[Assembler:Commands:MULSD|MULSD]], and [[Assembler:Commands:MOVSD|MOVSD]] instead. We just need to also make our scripts value a double.  | ||
| + | <pre>  | ||
| + | movsd [eax+10],xmm0  | ||
| + | </pre>  | ||
| + | |||
| + | So to calculate a value for a multiplier.  | ||
| + | <pre>  | ||
| + | //...  | ||
| + | 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  | ||
| + | //...  | ||
| + | </pre>  | ||
| + | |||
| + | <br>  | ||
| + | == Working with packed instructions ==  | ||
| + | Some times (especially with vectors) you'll see packed instructions, like [[Assembler:Commands:MOVAPS|MOVAPS]], [[Assembler:Commands:MOVUPS|MOVUPS]], [[Assembler:Commands:ADDPS|ADDPS]], [[Assembler:Commands:SUBPS|SUBPS]], [[Assembler:Commands:MULPS|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.  | ||
| + | <pre>  | ||
| + | addps [eax+10],xmm0  | ||
| + | </pre>  | ||
| + | |||
| + | So let's add a multiplier for this.  | ||
| + | <pre>  | ||
| + | //...  | ||
| + | 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  | ||
| + | //...  | ||
| + | </pre>  | ||
| + | |||
| + | <br>  | ||
| + | == 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]].  | ||
| + | <pre>  | ||
| + | movups [eax+10],xmm0  | ||
| + | </pre>  | ||
| + | |||
| + | We can just do some math in the script, to calculate a value for a multiplier.  | ||
| + | <pre>  | ||
| + | //...  | ||
| + | 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  | ||
| + | //...  | ||
| + | </pre>  | ||
| + | |||
| + | 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>  | ||
| + | movups [eax+10],xmm0  | ||
| + | </pre>  | ||
| + | |||
| + | Then we could make a script like this.  | ||
| + | <pre>  | ||
| + | //...  | ||
| + | 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  | ||
| + | //...  | ||
| + | </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>  | ||
| + | |||
| + | == See Also ==  | ||
| + | {{TutorialsAA}}  | ||
Latest revision as of 19:10, 18 March 2019
This tutorial builds on the topic of Code Injection:
- Code Injection - Basic injection
 - Code Injection - Full injection
 - Code Injection - Adding Editable Values
 - Code Injection - Working with Integers
 - Code Injection - Working with Floats
 
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
Contents
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
//...