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 


Negative Float Values

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
++METHOS
I post too much
Reputation: 92

Joined: 29 Oct 2010
Posts: 4197

PostPosted: Fri Feb 06, 2015 6:08 pm    Post subject: Negative Float Values Reply with quote

Using the below code, jle west only works if the value is between -1.0 to 0.

Code:
cmp [analog_base],(float)1.0
jge east
cmp [analog_base],(float)-1.0
jle west


If I change it to the below code, everything works as it should, however, jge west condition is also met when the value is between 0 to +0.99999999.

Code:
cmp [analog_base],(float)1.0
jge east
cmp [analog_base],(float)-1.0
jge west


Am I doing something wrong? I've checked everything over several times. The target is 64bit, using CE 6.4.

Thanks.
Back to top
View user's profile Send private message
Geri
Moderator
Reputation: 111

Joined: 05 Feb 2010
Posts: 5636

PostPosted: Fri Feb 06, 2015 6:39 pm    Post subject: This post has 1 review(s) Reply with quote

You have used cmp for float value. You should try float instructions instead.

http://www.jaist.ac.jp/iscenter-new/mpc/altix/altixdata/opt/intel/vtune/doc/users_guide/mergedProjects/analyzer_ec/mergedProjects/reference_olh/mergedProjects/instructions/instruct32_hh/vc89.htm

This is from the CE tutorial, step 4, float and double value compare (just to see how it looks like in a compiled software):

Code:
Tutorial-i386.exe+26128 - D9 05 C4F35500        - fld dword ptr [Tutorial-i386.exe+15F3C4]
Tutorial-i386.exe+2612E - D9 83 94040000        - fld dword ptr [ebx+00000494]
Tutorial-i386.exe+26134 - DED9                  - fcompp
Tutorial-i386.exe+26136 - DFE0                  - fnstsw ax
Tutorial-i386.exe+26138 - 9E                    - sahf
Tutorial-i386.exe+26139 - 72 3F                 - jb Tutorial-i386.exe+2617A
Tutorial-i386.exe+2613B - DD 05 C8F35500        - fld qword ptr [Tutorial-i386.exe+15F3C8]
Tutorial-i386.exe+26141 - DD 83 98040000        - fld qword ptr [ebx+00000498]
Tutorial-i386.exe+26147 - DED9                  - fcompp
Tutorial-i386.exe+26149 - DFE0                  - fnstsw ax
Tutorial-i386.exe+2614B - 9E                    - sahf
Tutorial-i386.exe+2614C - 72 2C                 - jb Tutorial-i386.exe+2617A

_________________
My trainers can be found here: http://www.szemelyesintegracio.hu/cheats

If you are interested in any of my crappy articles/tutorials about CE and game hacking, you can find them here:
http://www.szemelyesintegracio.hu/cheats/41-game-hacking-articles

Don't request cheats or updates.
Back to top
View user's profile Send private message
SteveAndrew
Master Cheater
Reputation: 30

Joined: 02 Sep 2012
Posts: 323

PostPosted: Fri Feb 06, 2015 8:17 pm    Post subject: Re: Negative Float Values Reply with quote

++METHOS wrote:
Using the below code, jle west only works if the value is between -1.0 to 0.

Code:
cmp [analog_base],(float)1.0
jge east
cmp [analog_base],(float)-1.0
jle west


If I change it to the below code, everything works as it should, however, jge west condition is also met when the value is between 0 to +0.99999999.

Code:
cmp [analog_base],(float)1.0
jge east
cmp [analog_base],(float)-1.0
jge west


Am I doing something wrong? I've checked everything over several times. The target is 64bit, using CE 6.4.

Thanks.



Yeah as Geri said a float value is compared differently than a standard byte value. You're comparing it as an integer value there...

This script depending on what you set defined "analog_base" to will follow a different path. It uses xmm register style "comiss"

(>= 1 will return 1 in eax)

(< 1 but >= -1 will return 0)

(< -1 will return -1)

Code:

[enable]
alloc(ComparingFloats,1024)
label(analog_base)
label(onepointzero)
label(negativeone)
label(LessThanNegativeOne)
label(GreaterOrEqualToOne)
label(GreaterOrEqualToNegativeOneButLessThanOne)
registersymbol(ComparingFloats)
createthread(ComparingFloats)

ComparingFloats:
movss xmm0,[analog_base]
comiss xmm0,[onepointzero]
jae GreaterOrEqualToOne

comiss xmm0,[negativeone]
jae GreaterOrEqualToNegativeOneButLessThanOne

LessThanNegativeOne:
mov eax,-1
ret

GreaterOrEqualToOne:
mov eax,1
ret

GreaterOrEqualToNegativeOneButLessThanOne:
xor eax,eax
ret

//analog_base:
//dd (float)1.5
analog_base:
dd (float)-2

onepointzero:
dd (float)1
negativeone:
dd (float)-1

[disable]

dealloc(ComparingFloats)
unregistersymbol(ComparingFloats)



You can also do fcom/fcomp/fucom/fucomp etc...

Though it's a little more complex to branch after getting the results of the comparison but still simple enough...
Code:

[enable]
alloc(ComparingFloats,1024)
label(analog_base)
label(onepointzero)
label(negativeone)
label(LessThanNegativeOne)
label(GreaterOrEqualToOne)
label(GreaterOrEqualToNegativeOneButLessThanOne)
registersymbol(ComparingFloats)
createthread(ComparingFloats)

ComparingFloats:
jmp ComparingFloats
fld [analog_base]
fcom [onepointzero]
fstsw ax
fwait
sahf
jae GreaterOrEqualToOne

fcom [negativeone]
fstsw ax
fwait
sahf
jae GreaterOrEqualToNegativeOneButLessThanOne

LessThanNegativeOne:
mov eax,-1
ret

GreaterOrEqualToOne:
mov eax,1
ret

GreaterOrEqualToNegativeOneButLessThanOne:
xor eax,eax
ret

analog_base:
dd (float)1.5
//analog_base:
//dd (float)0.5
//analog_base:
//dd (float)-2

onepointzero:
dd (float)1
negativeone:
dd (float)-1

[disable]

dealloc(ComparingFloats)
unregistersymbol(ComparingFloats)

_________________
Back to top
View user's profile Send private message
++METHOS
I post too much
Reputation: 92

Joined: 29 Oct 2010
Posts: 4197

PostPosted: Fri Feb 06, 2015 8:46 pm    Post subject: Reply with quote

Thanks, Geri. I've never used these before.

The code below works as it should, however, the conditions are met even if I barely touch the analog stick. jge east performs even when the analog stick is only half-way. jle west performs even if I barely nudge the analog stick. Something is not right about this code. The values look kosher while viewing in float type, but I can see strange behavior when viewing as double or 8 byte. For some reason, I can not get the code to cooperate while working with float type...and that's the only type that seems to be displaying properly without any strange behavior. I must be doing something wrong still. I've calibrated my controller and even used different xinput1_3.dll.

Code:
fld qword ptr [analog_base]
fld qword ptr [floate]
fcompp
jge east
fld qword ptr [analog_base]
fld qword ptr [floatw]
fcompp
jle west

analog_base:
dq (float)0
floate:
dq (float)1
floatw:
dq (float)-1


EDIT:
Thanks, SteveAndrew. I just saw your post after I replied to Geri. I'll take a look at your post after I have my dinner.

EDIT2:
SteveAndrew, I'm having some trouble following your scripts. I used a variation of your first script with less success than my previous method (see below). There appears to be an infinite loop in your second script (or am I reading that right?). Sorry, my knowledge of assembly is very basic.

Code:
movss xmm0,[analog_base]
comiss xmm0,[floate]
jge east
movss xmm0,[analog_base]
comiss xmm0,[floatw]
jge west


To clarify what I am trying to do...

[analog_base] holds the up/down value for the left analog stick on the gaming controller. The value is being loaded from a register from another injection point. I was using this label for something else and should have changed it, but I just forgot to. Anyway, when the L-Analog is pushed upwards, the value changes from (float) 0 to +1.0 (slightly higher than 1.0). Pushing downwards produces the opposite result (0 to -1.0, approximately).

I'm writing a fly mode script. I've never had this problem before...

Thanks, again.
Back to top
View user's profile Send private message
SteveAndrew
Master Cheater
Reputation: 30

Joined: 02 Sep 2012
Posts: 323

PostPosted: Fri Feb 06, 2015 9:44 pm    Post subject: This post has 1 review(s) Reply with quote

Okay when using the fcom/fcomp/fcompp the flags aren't set automatically which you can use to branch.

After the float compare instruction you have to have:
Code:

fnstsw ax //or fstsw ax
sahf


fstsw ax instruction puts the fpu "status word" into ax

sahf Transfers bits 0-7 of AH into the Flags Register. This includes AF, CF, PF, SF and ZF.

after that then you can do your ja/jb/je/ etc...

Also I ran into issues when using jge/jle for float comparisons with both methods... It appears you have to use the unsigned variety. Not sure why that is, but it only worked properly when I used jae/jb


EDIT: Yes my second one I forgot to remove that infinite loop... Since it creates a thread I was using that to debug it / test it... I would enable it then set a breakpoint after the jmp to self... then nop the jmp which would then hit my breakpoint.

So if you simple changed your conditionals it should start working properly:
Code:

movss xmm0,[analog_base]
comiss xmm0,[floate]
jae east
movss xmm0,[analog_base]
comiss xmm0,[floatw]
jae west


or your first one add the fnstsw ax + sahf as well:
Code:

fld qword ptr [analog_base]
fld qword ptr [floate]
fcompp
fnstsw ax
sahf
jae east
fld qword ptr [analog_base]
fld qword ptr [floatw]
fcompp
fnstsw ax
sahf
jbe west

_________________
Back to top
View user's profile Send private message
++METHOS
I post too much
Reputation: 92

Joined: 29 Oct 2010
Posts: 4197

PostPosted: Fri Feb 06, 2015 10:23 pm    Post subject: Reply with quote

SteveAndrew wrote:
Okay when using the fcom/fcomp/fcompp the flags aren't set automatically which you can use to branch.

After the float compare instruction you have to have:
Code:

fnstsw ax //or fstsw ax
sahf


fstsw ax instruction puts the fpu "status word" into ax

sahf Transfers bits 0-7 of AH into the Flags Register. This includes AF, CF, PF, SF and ZF.

after that then you can do your ja/jb/je/ etc...
-Yeah, I originally wrote it that way...the script works the same with or without the added fnstsw ax | sahf.

Quote:
Also I ran into issues when using jge/jle for float comparisons with both methods... It appears you have to use the unsigned variety. Not sure why that is, but it only worked properly when I used jae/jb
-This was the problem. Here is the working script (yay):

Code:
movss xmm0,[analog_base]
comiss xmm0,[floate]
ja east
movss xmm0,[analog_base]
comiss xmm0,[floatw]
jb west


Thanks, guys. I'll +rep you both when I can.
Back to top
View user's profile Send private message
SteveAndrew
Master Cheater
Reputation: 30

Joined: 02 Sep 2012
Posts: 323

PostPosted: Fri Feb 06, 2015 10:25 pm    Post subject: Reply with quote

Ahh see, so it was the conditionals! Very Happy Well glad you got it working for you now!
_________________
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