|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
gwo How do I cheat? Reputation: 0
Joined: 12 Jun 2012 Posts: 3
|
Posted: Fri Nov 27, 2015 11:52 am Post subject: Filtering Bad Floats |
|
|
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
Description: |
|
Filesize: |
39.98 KB |
Viewed: |
5683 Time(s) |
|
|
|
Back to top |
|
|
STN I post too much Reputation: 42
Joined: 09 Nov 2005 Posts: 2672
|
Posted: Fri Nov 27, 2015 11:56 am Post subject: |
|
|
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.
_________________
|
|
Back to top |
|
|
ParkourPenguin I post too much Reputation: 138
Joined: 06 Jul 2014 Posts: 4275
|
Posted: Fri Nov 27, 2015 8:47 pm Post subject: |
|
|
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 |
|
|
mgr.inz.Player I post too much Reputation: 218
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Sat Nov 28, 2015 5:33 am Post subject: |
|
|
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 |
|
|
gwo How do I cheat? Reputation: 0
Joined: 12 Jun 2012 Posts: 3
|
Posted: Sat Nov 28, 2015 5:59 am Post subject: |
|
|
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 |
|
|
mgr.inz.Player I post too much Reputation: 218
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Sat Nov 28, 2015 9:03 am Post subject: |
|
|
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 |
|
|
ParkourPenguin I post too much Reputation: 138
Joined: 06 Jul 2014 Posts: 4275
|
Posted: Sat Nov 28, 2015 9:30 am Post subject: |
|
|
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 |
|
|
mgr.inz.Player I post too much Reputation: 218
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Sat Nov 28, 2015 11:20 am Post subject: |
|
|
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 |
|
|
ParkourPenguin I post too much Reputation: 138
Joined: 06 Jul 2014 Posts: 4275
|
Posted: Sat Nov 28, 2015 12:17 pm Post subject: |
|
|
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.
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 |
|
|
|
|
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
|
|