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 


Filtering Bad Floats

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
gwo
How do I cheat?
Reputation: 0

Joined: 12 Jun 2012
Posts: 3

PostPosted: Fri Nov 27, 2015 11:52 am    Post subject: Filtering Bad Floats Reply with quote

When I search for unknown initial value floats I usually start with with "Value between..." and drop something like -1e6 to 1e6 (clearly my value is more likely to be in this range)
However I also know what values with condition abs(x) < 1e-9 are also more likely to be the ones I am NOT interseted, since these are probably giberrish bytes in memory (see attachment).
I wrote a LUA script which retains values with condition low <= abs(x) <= high. However to execute it I need to drop the whole search list to the address list. This creates problems:
1) I can't scan anymore
2) LUA script is ridiculously slow
How do you solve "bad floats" problem?

P.S. I have googled and searched CE forum for the solution, so I appologize in advance if there is a solution



screen.png
 Description:
 Filesize:  39.98 KB
 Viewed:  5683 Time(s)

screen.png


Back to top
View user's profile Send private message
STN
I post too much
Reputation: 42

Joined: 09 Nov 2005
Posts: 2672

PostPosted: Fri Nov 27, 2015 11:56 am    Post subject: Reply with quote

Keep doing Next scan until you narrow it down to a few ?.

10,129 is a huge number, you can slim it down to hundreds even if you can't filter them further and then with a little trial and error you should be able to find it.


PS: I see the game is quake3, the source is available - you can find what you're looking for and more if you run the game through IDA or Olly with pdb.

_________________
Cheat Requests/Tables- Fearless Cheat Engine
https://fearlessrevolution.com
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Fri Nov 27, 2015 8:47 pm    Post subject: Reply with quote

There are a couple solutions I can think of, but they aren't easy ones. The first one deals with modifying the files CE uses to store your current memory scan on. I don't know that much about this, but here's what Dark Byte said:
Dark Byte wrote:
the "Foundlist" object is just a readonly view of a file on disk

you can find the path to it using getCurrentMemscan().ScanresultFolder

to manipulate this list, first release the file lock (foundlist.deinitialize)
and then you can edit the file.
when done, use foundlist.initialize

the tricky parts is editing the files (previous memory, etc...)

(from this post)

The second solution would be to create a custom value type that rules out addresses that are out of a certain range (maybe make it treat them like NaN or something).

_________________
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
mgr.inz.Player
I post too much
Reputation: 218

Joined: 07 Nov 2008
Posts: 4438
Location: W kraju nad Wisla. UTC+01:00

PostPosted: Sat Nov 28, 2015 5:33 am    Post subject: Reply with quote

Use custom type below. It should filter out values bigger than 1E6 and smaller than -1E6.
Also it should filter out values between -1e-9 and 1e-9.

Code:
alloc(bigValue,4)
alloc(smallValue,4)

bigValue:          // to ignore
dd (float)1E6

smallValue:        // to ignore
dd (float)1E-9


alloc(ConvertRoutine,1024)
alloc(ConvertBackRoutine,1024)
alloc(TypeName,256)
alloc(ByteSize,4)
alloc(UsesFloat,1)
label(continue)
label(discard)

TypeName:
db 'float filtered',0

ByteSize:
dd 4

UsesFloat:
db 1

ConvertRoutine:
[32-bit]
push ebp
mov ebp,esp
mov eax,[ebp+8]
define(src,eax)
[/32-bit]
[64-bit]
define(src,rcx)
[/64-bit]

fld dword ptr [src]
fabs

mov eax,[src]

fld dword ptr [bigValue]
fcomip ST(0),ST(1)
jb discard

fld dword ptr [smallValue]
fcomip ST(0),ST(1)
ja discard

jmp continue

discard:
mov eax,(float)NaN

continue:
fstp ST(0)

[32-bit]
leave
ret 4
[/32-bit]
[64-bit]
ret
[/64-bit]






ConvertBackRoutine:
[64-bit]
mov [rdx],ecx
ret
[/64-bit]

[32-bit]
push ebp
mov ebp,esp
push eax
push ebx
mov eax,[ebp+8]
mov ebx,[ebp+c]
mov [ebx],eax
pop ebx
pop eax
leave
ret 8
[/32-bit]

_________________


Last edited by mgr.inz.Player on Sat Nov 28, 2015 9:00 am; edited 1 time in total
Back to top
View user's profile Send private message MSN Messenger
gwo
How do I cheat?
Reputation: 0

Joined: 12 Jun 2012
Posts: 3

PostPosted: Sat Nov 28, 2015 5:59 am    Post subject: Reply with quote

mgr.inz.Player this is perfect! thanks!

P.S. IMO compund logical search statements still should be implemented as CE core functionality
Back to top
View user's profile Send private message
mgr.inz.Player
I post too much
Reputation: 218

Joined: 07 Nov 2008
Posts: 4438
Location: W kraju nad Wisla. UTC+01:00

PostPosted: Sat Nov 28, 2015 9:03 am    Post subject: Reply with quote

No problem.

Keep in mind that above CustomType script will reject zeros as well (because it is between -1e-9 and 1e-9)

Or, you want zero to be included? I can change the script.


Code:
IMO compund logical search statements still should be implemented as CE core functionality

For that, we have Lua and CustomType.

_________________
Back to top
View user's profile Send private message MSN Messenger
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Sat Nov 28, 2015 9:30 am    Post subject: Reply with quote

I was trying to make a script like that using the xmm registers instead of the fpu. I found out that it was crashing because ucomiss was signaling a floating-point invalid operation exception when the input was NaN. I tried to avoid that using this at the beginning (32-bit):
Code:
mov eax,[ebp+8]
mov eax,[eax]
and eax,7F800000
cmp eax,7F800000
je skipComparisonsAndReturn
...

I had read the last bit 31 is for the sign, 30-23 is the exponent, and 22-0 is the fraction for a single precision float. If 30-23 are all set, then that float is either NaN or Inf depending on whether the fraction is zero or not. This didn't work out, though.

So, a couple questions:
Why does an operand of NaN not crash the program with the fcomip instruction like it does with ucomiss?
What's the correct way to do this with xmm registers, or should I just avoid those and always use the fpu instead?

_________________
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
mgr.inz.Player
I post too much
Reputation: 218

Joined: 07 Nov 2008
Posts: 4438
Location: W kraju nad Wisla. UTC+01:00

PostPosted: Sat Nov 28, 2015 11:20 am    Post subject: Reply with quote

Are you sure? CE injects Custom Type scripts to itself.


CE has masked exceptions (FPU and SSE/SSE2):
Code:
Set8087CW($133f);
SetSSECSR($1f80);



also CE uses this:
Code:
SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide, exOverflow, exUnderflow, exPrecision]);

for every TScanner thread.





SSE version:
Code:
alloc(bigValue,4)
alloc(smallValue,4)

bigValue:          // to ignore
dd (float)1E6

smallValue:        // to ignore
dd (float)1E-9


alloc(ConvertRoutine,1024)
alloc(ConvertBackRoutine,1024)
alloc(TypeName,256)
alloc(ByteSize,4)
alloc(UsesFloat,1)
label(continue)
label(discard)
label(tmp)

TypeName:
db 'float filtered (SSE)',0

ByteSize:
dd 4

UsesFloat:
db 1

ConvertRoutine:
[32-bit]
push ebp
mov ebp,esp
mov eax,[ebp+8]
define(src,eax)
[/32-bit]
[64-bit]
define(src,rcx)
[/64-bit]

movd xmm0,[tmp]
movd xmm1,[src]
andnps xmm0,xmm1 // ABS

ucomiss xmm0,[bigValue]
ja discard
ucomiss xmm0,[smallValue]
jb discard

mov eax,[src]
jmp continue

discard:
mov eax,(float)NaN

continue:

[32-bit]
leave
ret 4
[/32-bit]
[64-bit]
ret
[/64-bit]
tmp:
dd 80000000





ConvertBackRoutine:
[64-bit]
mov [rdx],ecx
ret
[/64-bit]

[32-bit]
push ebp
mov ebp,esp
push eax
push ebx
mov eax,[ebp+8]
mov ebx,[ebp+c]
mov [ebx],eax
pop ebx
pop eax
leave
ret 8
[/32-bit]

_________________
Back to top
View user's profile Send private message MSN Messenger
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Sat Nov 28, 2015 12:17 pm    Post subject: Reply with quote

I did test it with some code, but I injected that code into another process that didn't have that protection. This made me think that was the problem. I've found out now that it's not. Embarassed

Anyway, my problem was with how I handled the stack. I used it to temporarily store the bounds used in the ucomiss. I cleaned it up later by adding to the rsp. I assumed pushing a float, which takes up 4 bytes of space, would decrement rsp by 4. In a 32-bit process, that's true; however, in a 64-bit process (which CE is in for me), it's not. Pushing a 4-byte value onto the stack decrements rsp by 8, so I have to add 8 to rsp to clean it up.

Everything is now working perfectly fine after I made that change. Thank you very much for the example- it's cleaner and shorter than what I was doing. I really need to study the differences between x86 and x64.

_________________
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
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