|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
DodgeWolfy Newbie cheater Reputation: 0
Joined: 13 May 2017 Posts: 19
|
Posted: Wed Jan 10, 2018 3:31 pm Post subject: Help Needed with Multiplying Floats and Updating a value. |
|
|
I fully admit i have little to no clue of what i'm doing with the assembler, i want to get to know it better but the information on the wiki while it is really helpful when it comes to understanding what each command does, doesn't have information on how to do specific things. But basically here's the situation.
I'm making a cheat table for a racing game, the game uses ECU tuning / adjustment for power increases and there's a direct correlation between the slider values and the power output of the vehicle, the problem i am having is that you move a slider for each 1000 RPM, so there's 10 values, i don't want to manually enter all of them manually and estimate how a power curve would look like, the idea i had is to make a script that multiplies all of them by a number i chose in a different address. Thus far i have found all the base addresses for the ECU (0-10K RPM) but, i have no clue how to actually multiply them, as all of them are in the type float.
See attached screenshot because of my terrible explanation
Also some of the RPMs are 0, not sure how well that will turn out when they multiplied as 1.0 would = 1000Nm which is quite a bit, but the car "technically" should not use anything past its' rev limit, in this case 8K
I briefly looked around the forums and on google but only found how to multiply normal values.
This is the code i use to make the address, now i want to multiply let's say
Game.exe+4903B0 by ECU_Power_Mult
Also the value updates to the default one with each track, obviously because it's going out of the normal slider value limits so, i will need a way of "freezing it" or at least periodically setting it, not sure if that would be best done in the script that creates the address for what will be the multiplier or standalone if not i can always freeze the addresses manually.
Code: | [Enable]
alloc(ECU_Power_Mult,16)
registersymbol(ECU_Power_Mult)
ECU_Power_Mult:
dd (Float)1
[Disable]
unregistersymbol(ECU_Power_Mult)
dealloc(ECU_Power_Mult)
|
Also ideally i would be able to also use offsets to modify some other values with the same multiplier (they are also float)
But i am not sure how to do that. I know i can do something like this for the pointers
[["Game.exe"+49CDA8]+58]+41c:
but i have no actual idea how to implement that into code.
Thanks in advance guys |
|
Back to top |
|
|
TheyCallMeTim13 Wiki Contributor Reputation: 50
Joined: 24 Feb 2017 Posts: 976 Location: Pluto
|
Posted: Wed Jan 10, 2018 3:40 pm Post subject: |
|
|
For multiplying:
Code: | fld dword ptr [esi+123ABC]
fmul dword ptr [someMultiplier]
fstp dword ptr [esi+123ABC] |
Code: | movss xmm0,[esi+123ABC]
movss xmm1,[someMultiplier]
mulss xmm0,xmm1
movss [esi+123ABC],xmm0 |
for the pointer:
Code: |
mov esi,[Game.exe+49CDA8]
test esi,esi
jz @f
mov esi,[esi+58]
test esi,esi
jz @f
mov [esi+41C],(float)100
@@:
|
But why post in the "Cheat Engine Lua Scripting" section? _________________
|
|
Back to top |
|
|
jobeth213 Newbie cheater Reputation: 0
Joined: 27 Sep 2016 Posts: 22
|
Posted: Wed Jan 10, 2018 3:49 pm Post subject: |
|
|
TheyCallMeTim13 wrote: | For multiplying:
Code: | fld dword ptr [esi+123ABC]
fmul dword ptr [someMultiplier]
fstp dword ptr [esi+123ABC] |
Code: | movss xmm0,[esi+123ABC]
movss xmm1,[someMultiplier]
mulss xmm0,xmm1
movss [esi+123ABC],xmm0 |
for the pointer:
Code: |
mov esi,[Game.exe+49CDA8]
test esi,esi
jz @f
mov esi,[esi+58]
test esi,esi
jz @f
mov [esi+41C],(float)100
@@:
|
But why post in the "Cheat Engine Lua Scripting" section? |
Hi man where did you learn assembly? I kinda have bypass on XTRAP, that is why I didn't bother learning assembly, but now I wanna use it in my lua scripting trainer. _________________
I'm idiot |
|
Back to top |
|
|
FreeER Grandmaster Cheater Supreme Reputation: 53
Joined: 09 Aug 2013 Posts: 1091
|
Posted: Wed Jan 10, 2018 3:50 pm Post subject: |
|
|
With pointers you can use lua to do this pretty trivially, eg.
Code: | {$lua}
[ENABLE]
if syntaxcheck then return end -- do nothing during editing
local multiplier = readFloat('ECU_Power_Mult')
local first = getAddress('[["Game.exe"+49CDA8]+58]+41c')
for i=0,10 in ipairs(pointers) do
local addr = first+i*4
local value = readFloat(addr)
writeFloat(addr, value*multiplier)
end
[DISABLE]
|
should go through and set all of them. As for doing it periodically you can create a timer that'd repeatedly run that code after a delay eg.
Code: | {$lua}
[ENABLE]
if syntaxcheck then return end -- do nothing during editing
sliderMultiplierTimer = createTimer()
sliderMultiplierTimer.Interval = 1000 -- 1000 milliseconds, 1 second
sliderMultiplierTimer.OnTimer = function()
local multiplier = readFloat('ECU_Power_Mult')
local first = getAddress('[["Game.exe"+49CDA8]+58]+41c')
for i=0,10 in ipairs(pointers) do
local addr = first+i*4
local value = readFloat(addr)
writeFloat(addr, value*multiplier)
end
end
[DISABLE]
-- destroy timer so it stops running
sliderMultiplierTimer.destroy()
|
with assembly you'd use either fld+fmul+fstp or movss+mulss (mulss is probably the more intuitive since SSE uses registers while the FPU uses a stack) but you'd have to either find somewhere to inject the code or allocate memory for your own function and call it with createThread. |
|
Back to top |
|
|
DodgeWolfy Newbie cheater Reputation: 0
Joined: 13 May 2017 Posts: 19
|
Posted: Wed Jan 10, 2018 3:52 pm Post subject: |
|
|
TheyCallMeTim13 wrote: | For multiplying:
Code: | fld dword ptr [esi+123ABC]
fmul dword ptr [someMultiplier]
fstp dword ptr [esi+123ABC] |
Code: | movss xmm0,[esi+123ABC]
movss xmm1,[someMultiplier]
mulss xmm0,xmm1
movss [esi+123ABC],xmm0 |
for the pointer:
Code: |
mov esi,[Game.exe+49CDA8]
test esi,esi
jz @f
mov esi,[esi+58]
test esi,esi
jz @f
mov [esi+41C],(float)100
@@:
|
But why post in the "Cheat Engine Lua Scripting" section? |
I mean, i really didn't want to post in the wrong section so on the index page i saw "Want Cheat Engine to do something specific and no idea how to do that, ask here. (From simple scripts to full trainers and extensions)" I wasn't really sure if it should be here or in the general one, apologies :/ |
|
Back to top |
|
|
TheyCallMeTim13 Wiki Contributor Reputation: 50
Joined: 24 Feb 2017 Posts: 976 Location: Pluto
|
Posted: Wed Jan 10, 2018 4:03 pm Post subject: |
|
|
@DodgeWolfy:
No worries, just curious, I guess I never read that part of the forum my self.
Just had me thinking you might be asking about Lua.
@jobeth213
Mostly messing with Cheat Engine, it's my best reason to use assembly, but I like to be well rounded so I looked into "FASM" and "NASM" assemblers, and just played around with them.
If it helps to know, I never even graduated high school.
But stay in school! _________________
|
|
Back to top |
|
|
DodgeWolfy Newbie cheater Reputation: 0
Joined: 13 May 2017 Posts: 19
|
Posted: Wed Jan 10, 2018 4:15 pm Post subject: |
|
|
@TheyCallMeTim13
I tried doing the following:
Code: | [Enable]
alloc(TestScript,$32)
registersymbol(TestScript)
TestScript:
fld dword ptr [Game.exe+4903B4]
fmul dword ptr [3]
fstp dword ptr [Game.exe+4903B4]
[Disable]
dealloc(TestScript)
unregistersymbol(TestScript) |
It compiled the script without saying any errors but it didn't work, it just didn't do anything, do i need to implement this into a AOB injection, because i'm trying to do it standalone, as the value doesn't actually update, as i said only once you load a new track. Initially i tried using
Code: | fmul dword ptr [ECU_Power_Mult] |
I allocated a lot of memory for the test script on purpose, and Yes, i might be retarded and i know i am doing something wrong but really don't know what |
|
Back to top |
|
|
TheyCallMeTim13 Wiki Contributor Reputation: 50
Joined: 24 Feb 2017 Posts: 976 Location: Pluto
|
Posted: Wed Jan 10, 2018 4:25 pm Post subject: |
|
|
Yes you need to use this in an injection, or a thread, but an injection would be easier to start with I think.
So some thing like this:
Code: |
define(bytes, F3 0F 10 8E 8C 05 00 00)
[Enable]
aobScanModule(aobTestScript, Game.exe, F3xxxxxxxxxxxxxxF3xxxxxxxxD9xxxxF3)
define(injTestScript, aobTestScript+6)
assert(injTestScript, bytes)
registerSymbol(injTestScript)
alloc(TestScript,$32)
registersymbol(TestScript)
label(testScriptFloat)
label(testScriptStart)
TestScript:
testScriptFloat:
dd (float)3
testScriptStart:
fld dword ptr [Game.exe+4903B4]
fmul dword ptr [testScriptFloat]
fstp dword ptr [Game.exe+4903B4]
// original code here
jmp return
////
//// ---------- Injection Point ----------
injTestScript:
jmp testScriptStart
nop
nop
nop
return:
////
//// ------------------------------ DISABLE ------------------------------
[DISABLE]
////
//// ---------- Injection Point ----------
injTestScript:
db bytes
unregisterSymbol(injTestScript)
unregisterSymbol(ptrTestScript)
unregisterSymbol(fltTestScript)
dealloc(memTestScript) |
So with your code you where multiplying by the value at the address of "3".
EDIT:
You could also use Lua:
Lua:
Code: | writeFloat('Game.exe+4903B4', 3 * readFloat('Game.exe+4903B4')) |
AA:
Code: | luaCall(writeFloat('Game.exe+4903B4', 3 * readFloat('Game.exe+4903B4'))) |
_________________
|
|
Back to top |
|
|
DodgeWolfy Newbie cheater Reputation: 0
Joined: 13 May 2017 Posts: 19
|
Posted: Wed Jan 10, 2018 4:38 pm Post subject: |
|
|
@TheyCallMeTim13
Thank you!
Just tried with injection on the code when i trigger the nitrous button it multiplies the power by the specified value in ECU_Power_Mult, the thing about that is that each time i trigger the nitrous it goes from 0.5 to 1.5 then to 4.5 you get the point.
If it isn't too much bother, how exactly would i do it with create thread, as the main idea of this table in the first place was to be able to dynamically adjust the power/tune of your car, so for example you do your thing and want to try out a different tune, write in the power multiplier, click a thing once and all of the values update to your desired power output, also i'll have to think of some way of storing the original values because i don't actually want it to go up by 3x each time or with each change because you would really quickly start going to levels of power that don't react happily with the physics
Edit: Figured out the create thread thing! Just need a suggestion on how to remember original values
Last edited by DodgeWolfy on Wed Jan 10, 2018 5:05 pm; edited 2 times in total |
|
Back to top |
|
|
TheyCallMeTim13 Wiki Contributor Reputation: 50
Joined: 24 Feb 2017 Posts: 976 Location: Pluto
|
Posted: Wed Jan 10, 2018 4:52 pm Post subject: |
|
|
Some thing like this:
Code: |
////
//// ------------------------------ ENABLE ------------------------------
[ENABLE]
alloc(memThread, 0x400)
label(threadStart)
label(threadEnd)
label(fltNitrousMultiplier)
memThread:
fltNitrousMultiplier:
dd (float)3
threadStart:
fld dword ptr [Game.exe+4903B4]
fmul dword ptr [fltNitrousMultiplier]
fstp dword ptr [Game.exe+4903B4]
threadEnd:
ret
createThread(threadStart)
////
//// ------------------------------ DISABLE ------------------------------
[DISABLE]
dealloc(memThread) |
Note that the thread is your's so the registries are also all your's (meaning you are free to use at your will). _________________
|
|
Back to top |
|
|
DodgeWolfy Newbie cheater Reputation: 0
Joined: 13 May 2017 Posts: 19
|
Posted: Wed Jan 10, 2018 5:58 pm Post subject: |
|
|
Update:
Finally finished it, works perfectly, i can't thank you guys enough, especially @TheyCallMeTim13!
How i ended up doing it is using createThread to write all the values to the allocated space for each one as a backup of the original power value, another createThread script to modify and multiply the values by the specified multiplier and finally use a different createThread script when the user wants to reset, i know, extremely inefficient but hell, the game is a decade old, shouldn't be a problem when it comes to performance, i assigned each value only 8 bytes, i think it should deal OK with the values i am using!
If it's stupid and it works it's not stupid
And yes, i did declare 10 different symbols just to use for backup |
|
Back to top |
|
|
TheyCallMeTim13 Wiki Contributor Reputation: 50
Joined: 24 Feb 2017 Posts: 976 Location: Pluto
|
Posted: Wed Jan 10, 2018 6:10 pm Post subject: |
|
|
No, this should work fine. The threads terminate after the "ret" (return). It's just the allocated memory that stays. But if you are still using the memory, well this is just how memory works any way, and might as well make your memory work for you.
I would just nest the scripts in the address list, and put some clean up in the right spot. Just don't try and deallocate the threads memory right after running the thread (wait 0.1 seconds), else it can get caught in the deallocated memory and crash the thread and who knows what else.
And always have a "ret" at the end of a "call"ed threads instruction, else it will run tell it crashes never returning.
EDIT:
Here are some template plugins that may help, but know that I really think it's best to learn to build all things from scratch.
Custom 'AOB Injection' Templates
AAmaker
This one is mine and is where the thread script came from.
I2 Cheat Engine Auto Assembler Script Template Generator _________________
Last edited by TheyCallMeTim13 on Wed Jan 10, 2018 6:24 pm; edited 1 time in total |
|
Back to top |
|
|
DodgeWolfy Newbie cheater Reputation: 0
Joined: 13 May 2017 Posts: 19
|
Posted: Wed Jan 10, 2018 6:24 pm Post subject: |
|
|
I can't quite gather why ret is in a different label though, also the way i made it you basically toggle a "recovery" mode and as soon as you turn it off (obviously you don't Need to use it to backup your tune) it deallocates everything from it
I won't post full code because it's literally 5 lines copied over 10 times and just slightly changed for each number
But it's basically this:
RECOVERY
Code: | [Enable]
alloc(ECU_0K_Original,8)
registersymbol(ECU_0K_Original)
ECU_0K_Original:
dd (Float)0
[DISABLE]
dealloc(ECU_0K_Original)
unregistersymbol(ECU_0K_Original)
|
BACKUP
Code: | [Enable]
alloc(ECU_Tune_Recovery,$1)
label(ECU_Tune_Backup)
label(ECU_Tune_Destroy)
ECU_Tune_Recovery:
ECU_Tune_Backup:
push eax
mov eax,[GAME.exe+4903B0]
mov [ECU_0K_Original],eax
pop eax
ECU_Tune_Destroy:
ret
createThread(ECU_Tune_Backup)
[DISABLE]
dealloc(ECU_Tune_Recovery)
|
RESTORE
Code: | [Enable]
alloc(ECU_Tune_Recovery,$1)
label(ECU_Tune_Backup)
label(ECU_Tune_Destroy)
ECU_Tune_Recovery:
ECU_Tune_Backup:
push ebx
mov ebx,[ECU_0K_Original]
mov [GAME.exe+4903B0],ebx
pop ebx
ECU_Tune_Destroy:
ret
createThread(ECU_Tune_Backup)
[DISABLE]
dealloc(ECU_Tune_Recovery)
|
|
|
Back to top |
|
|
TheyCallMeTim13 Wiki Contributor Reputation: 50
Joined: 24 Feb 2017 Posts: 976 Location: Pluto
|
Posted: Wed Jan 10, 2018 6:45 pm Post subject: |
|
|
The "ret" is only in a different label because I just like stuff like that, a nice reassuring label that says, "Hay buddy, this has an end."
But I have a tendency to, really, type out descriptive labels and IDs.
But to each their own.
And you could use a loop for that, if it has a pattern that you can spot. And with your thread you can use all of the registries (no pushes or pops needed off the bat).
Code: | define(loopMax,(int)50)
[Enable]
alloc(ECU_Tune_Recovery, $100) // this needs to be at lest the number of bytes for the instructions
// I think windows just allocates a full 0x1000 bytes every time though (or at lest it did).
label(ECU_Tune_Backup)
ECU_Tune_Recovery:
label(loopStart)
ECU_Tune_Backup:
mov eax,0
mov ecx,loopMax
loopStart:
mov edx,[GAME.exe+eax*4+4903B0]
mov [ECU_0K_Original+eax*4],edx
add eax,4
loop loopStart
ret // So no label, but I like my tabs, down with spaceshowneedsthemanyway.
createThread(ECU_Tune_Backup)
[DISABLE]
dealloc(ECU_Tune_Recovery) |
Quote: | Tutorials Point
The LOOP instruction assumes that the ECX register contains the loop count. When the loop instruction is executed, the ECX register is decremented and the control jumps to the target label, until the ECX register value, i.e., the counter reaches the value zero. |
_________________
|
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
|