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 


Problem with floats in assembly

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
JohannesJoestar
Advanced Cheater
Reputation: 0

Joined: 01 Nov 2015
Posts: 79

PostPosted: Thu Jun 22, 2017 4:15 pm    Post subject: Problem with floats in assembly Reply with quote

Hey there, I'm trying to make a script for a game that will obtain coordinates of the player, and play around with other coordinates if current entity is not a player.

In this particular case, I want to get Player's coordinates and set Ghost's x coordinate to 0. Background information:

[ebx+C] : Entity ID, 0 for Player and 1017(3F9) for Ghost.
[ebx+30] and [ebx+34] : X and Y coordinates.

I'm injecting to what I've got from "what writes to this adress" which is something that happens every tick, frame or whatever.
Original code:
Code:
  fstp dword ptr [ebx+30]
  fld dword ptr [ebx+50]


Obtaining the base adress and populating the coordinates are easy and I've achieved that with no problems. The issue kicks in with the ghost part of my script which is crashing the game probably because of my lack of knowledge on handling floats in
assembly.
Here is my script :
Code:
{ Game   : Spelunky.exe
  Version:
  Date   : 2017-06-22
  Author : Emperor Vincent

  This script will do stuff about coordinates
}

[ENABLE]

aobscanmodule(position,Spelunky.exe,D9 5B 30 D9 43 50) // should be unique
globalalloc(ppos,4)
alloc(newmem,$1000)

label(code)
label(return)
label(ghost)

newmem:
  // Check if ghost
  cmp dword ptr [ebx+C],3F9
  je ghost

  // Check if player
  cmp dword ptr [ebx+C],0
  jne code

  // Obtain player position base
  mov [ppos],ebx
  jmp code

ghost:
  push eax
  mov [eax],0

  // Set ghost x coordinate 0
  fld dword ptr [ebx+30]
  fmul dword ptr [eax]
  fstp dword ptr [ebx+30]

  pop eax

code:
  fstp dword ptr [ebx+30]
  fld dword ptr [ebx+50]
  jmp return

position:
  jmp newmem
  nop
return:
registersymbol(position)

[DISABLE]

position:
  db D9 5B 30 D9 43 50

unregistersymbol(position)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: "Spelunky.exe"+13DEB

"Spelunky.exe"+13DC0: E8 EB 49 0C 00        -  call Spelunky.exe+D87B0
"Spelunky.exe"+13DC5: EB 07                 -  jmp Spelunky.exe+13DCE
"Spelunky.exe"+13DC7: C6 86 9C 00 00 00 01  -  mov byte ptr [esi+0000009C],01
"Spelunky.exe"+13DCE: A1 30 13 4F 01        -  mov eax,[Spelunky.exe+131330]
"Spelunky.exe"+13DD3: 83 40 4C 05           -  add dword ptr [eax+4C],05
"Spelunky.exe"+13DD7: 83 78 50 02           -  cmp dword ptr [eax+50],02
"Spelunky.exe"+13DDB: 7D 07                 -  jnl Spelunky.exe+13DE4
"Spelunky.exe"+13DDD: C7 40 50 02 00 00 00  -  mov [eax+50],00000002
"Spelunky.exe"+13DE4: D9 43 30              -  fld dword ptr [ebx+30]
"Spelunky.exe"+13DE7: D8 44 24 14           -  fadd dword ptr [esp+14]
// ---------- INJECTING HERE ----------
"Spelunky.exe"+13DEB: D9 5B 30              -  fstp dword ptr [ebx+30]
"Spelunky.exe"+13DEE: D9 43 50              -  fld dword ptr [ebx+50]
// ---------- DONE INJECTING  ----------
"Spelunky.exe"+13DF1: D9 05 F0 4C 4E 01     -  fld dword ptr [Spelunky.exe+124CF0]
"Spelunky.exe"+13DF7: DC C1                 -  fadd st(1),st(0)
"Spelunky.exe"+13DF9: D9 C9                 -  fxch st(1)
"Spelunky.exe"+13DFB: D9 5B 50              -  fstp dword ptr [ebx+50]
"Spelunky.exe"+13DFE: D8 43 4C              -  fadd dword ptr [ebx+4C]
"Spelunky.exe"+13E01: D9 5B 4C              -  fstp dword ptr [ebx+4C]
"Spelunky.exe"+13E04: 8B 44 24 24           -  mov eax,[esp+24]
"Spelunky.exe"+13E08: 40                    -  inc eax
"Spelunky.exe"+13E09: 3B 44 24 20           -  cmp eax,[esp+20]
"Spelunky.exe"+13E0D: 89 44 24 24           -  mov [esp+24],eax
}



I tried commenting out the whole ghost section, which made it work again therefore the problem is definitely in the ghost part.
I appreciate any kind of suggestions/solutions.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Thu Jun 22, 2017 4:38 pm    Post subject: Reply with quote

Code:
ghost:
  push eax
  mov [eax],0

You're not moving 0 into the register eax. You're moving 0 into the memory address specified by eax. If that address is a pointer to a vtable (eax looks like it's pointing to a structure), then it's going to crash the game when anything tries to access the vtable because it would dereference a null pointer.

Even if you weren't writing to memory you shouldn't be writing to, it wouldn't work, since you let the game overwrite [ebx+30] with the value that was on the fpu stack prior to the injection point.

Just pop the value that was on the fpu stack off and move 0 into [ebx+30]. The encoding of the floating point value 0 is simply 0, so you don't need to do anything special.
Code:
[ENABLE]
aobscanmodule(position,Spelunky.exe,D9 5B 30 D9 43 50)
globalalloc(ppos,4)
alloc(newmem,$1000)

label(exit)
label(return)
label(ghost)

registersymbol(position)

newmem:
  cmp dword ptr [ebx+C],3F9 // check for ghost
  je ghost
  fstp dword ptr [ebx+30]  // original code
  cmp dword ptr [ebx+C],0  // check for player
  jne exit
  mov [ppos],ebx  // save player
  jmp exit
ghost:
  fstp st(0)
  mov [ebx+30],0  // set x-coord to 0
exit:
  fld dword ptr [ebx+50]  // original code
  jmp return


position:
  jmp newmem
  nop
return:

[DISABLE]
position:
  db D9 5B 30 D9 43 50

unregistersymbol(position)
dealloc(newmem)

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
JohannesJoestar
Advanced Cheater
Reputation: 0

Joined: 01 Nov 2015
Posts: 79

PostPosted: Fri Jun 23, 2017 3:19 am    Post subject: Reply with quote

ParkourPenguin wrote:
Code:
ghost:
  push eax
  mov [eax],0

You're not moving 0 into the register eax. You're moving 0 into the memory address specified by eax. If that address is a pointer to a vtable (eax looks like it's pointing to a structure), then it's going to crash the game when anything tries to access the vtable because it would dereference a null pointer.

Even if you weren't writing to memory you shouldn't be writing to, it wouldn't work, since you let the game overwrite [ebx+30] with the value that was on the fpu stack prior to the injection point.

Just pop the value that was on the fpu stack off and move 0 into [ebx+30]. The encoding of the floating point value 0 is simply 0, so you don't need to do anything special.
Code:
[ENABLE]
aobscanmodule(position,Spelunky.exe,D9 5B 30 D9 43 50)
globalalloc(ppos,4)
alloc(newmem,$1000)

label(exit)
label(return)
label(ghost)

registersymbol(position)

newmem:
  cmp dword ptr [ebx+C],3F9 // check for ghost
  je ghost
  fstp dword ptr [ebx+30]  // original code
  cmp dword ptr [ebx+C],0  // check for player
  jne exit
  mov [ppos],ebx  // save player
  jmp exit
ghost:
  fstp st(0)
  mov [ebx+30],0  // set x-coord to 0
exit:
  fld dword ptr [ebx+50]  // original code
  jmp return


position:
  jmp newmem
  nop
return:

[DISABLE]
position:
  db D9 5B 30 D9 43 50

unregistersymbol(position)
dealloc(newmem)


I see. I'm still not used to floats in assembly Razz
Works great now, thanks!
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine 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