Difference between revisions of "Tutorial:CodeInjection Floats"
(Created page with '<!-- Tutorial:CodeInjection_Floats --> Category:Tutorial Category:Auto Assembler {{DISPLAYTITLE:Code Injection - Working with Floats}} This tutorial builds on the topic o…') |
m (Reverted edits by This content is not available (Talk) to last revision by TheyCallMeTim13) |
||
(7 intermediate revisions by 2 users not shown) | |||
Line 33: | Line 33: | ||
someMem: | someMem: | ||
//... | //... | ||
− | + | movss xmm0,[someSymbol] | |
addss [eax+10],xmm0 | addss [eax+10],xmm0 | ||
//... | //... | ||
Line 124: | Line 124: | ||
<br> | <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 == | == See Also == | ||
{{TutorialsAA}} | {{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 //...