Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Help Needed with Multiplying Floats and Updating a value.

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting
View previous topic :: View next topic  
Author Message
DodgeWolfy
Newbie cheater
Reputation: 0

Joined: 13 May 2017
Posts: 19

PostPosted: Wed Jan 10, 2018 3:31 pm    Post subject: Help Needed with Multiplying Floats and Updating a value. Reply with quote

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 Smile



Example.PNG
 Description:
 Filesize:  14.34 KB
 Viewed:  10787 Time(s)

Example.PNG


Back to top
View user's profile Send private message
TheyCallMeTim13
Wiki Contributor
Reputation: 50

Joined: 24 Feb 2017
Posts: 976
Location: Pluto

PostPosted: Wed Jan 10, 2018 3:40 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
jobeth213
Newbie cheater
Reputation: 0

Joined: 27 Sep 2016
Posts: 22

PostPosted: Wed Jan 10, 2018 3:49 pm    Post subject: Reply with quote

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
View user's profile Send private message
FreeER
Grandmaster Cheater Supreme
Reputation: 53

Joined: 09 Aug 2013
Posts: 1091

PostPosted: Wed Jan 10, 2018 3:50 pm    Post subject: Reply with quote

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
View user's profile Send private message
DodgeWolfy
Newbie cheater
Reputation: 0

Joined: 13 May 2017
Posts: 19

PostPosted: Wed Jan 10, 2018 3:52 pm    Post subject: Reply with quote

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
View user's profile Send private message
TheyCallMeTim13
Wiki Contributor
Reputation: 50

Joined: 24 Feb 2017
Posts: 976
Location: Pluto

PostPosted: Wed Jan 10, 2018 4:03 pm    Post subject: Reply with quote

@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
View user's profile Send private message Visit poster's website
DodgeWolfy
Newbie cheater
Reputation: 0

Joined: 13 May 2017
Posts: 19

PostPosted: Wed Jan 10, 2018 4:15 pm    Post subject: Reply with quote

@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
View user's profile Send private message
TheyCallMeTim13
Wiki Contributor
Reputation: 50

Joined: 24 Feb 2017
Posts: 976
Location: Pluto

PostPosted: Wed Jan 10, 2018 4:25 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
DodgeWolfy
Newbie cheater
Reputation: 0

Joined: 13 May 2017
Posts: 19

PostPosted: Wed Jan 10, 2018 4:38 pm    Post subject: Reply with quote

@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
View user's profile Send private message
TheyCallMeTim13
Wiki Contributor
Reputation: 50

Joined: 24 Feb 2017
Posts: 976
Location: Pluto

PostPosted: Wed Jan 10, 2018 4:52 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
DodgeWolfy
Newbie cheater
Reputation: 0

Joined: 13 May 2017
Posts: 19

PostPosted: Wed Jan 10, 2018 5:58 pm    Post subject: Reply with quote

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 Smile
And yes, i did declare 10 different symbols just to use for backup Very Happy
Back to top
View user's profile Send private message
TheyCallMeTim13
Wiki Contributor
Reputation: 50

Joined: 24 Feb 2017
Posts: 976
Location: Pluto

PostPosted: Wed Jan 10, 2018 6:10 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
DodgeWolfy
Newbie cheater
Reputation: 0

Joined: 13 May 2017
Posts: 19

PostPosted: Wed Jan 10, 2018 6:24 pm    Post subject: Reply with quote

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 Smile

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)



350zDemoTable.png
 Description:
 Filesize:  60.55 KB
 Viewed:  10688 Time(s)

350zDemoTable.png


Back to top
View user's profile Send private message
TheyCallMeTim13
Wiki Contributor
Reputation: 50

Joined: 24 Feb 2017
Posts: 976
Location: Pluto

PostPosted: Wed Jan 10, 2018 6:45 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites