Difference between revisions of "Tutorial:CodeInjection Floats"
| Line 122: | Line 122: | ||
//... | //... | ||
</pre> | </pre> | ||
| + | |||
| + | <br> | ||
| + | == Working with packed instructions == | ||
| + | So 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> | <br> | ||
== See Also == | == See Also == | ||
{{TutorialsAA}} | {{TutorialsAA}} | ||
Revision as of 02:16, 12 May 2018
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
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
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
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
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
So 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
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
//...