 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
CodeReaver Newbie cheater
Reputation: 0
Joined: 19 Apr 2005 Posts: 24
|
Posted: Tue Sep 27, 2016 1:47 pm Post subject: fxch always sets register to NaN |
|
|
I'm trying to use the fxch command to swap floats to the top of the FPU stack, but whenever I do, st(0) is set to NaN. The register that I'm swapping it with starts out with a legitimate floating point number, but seems to be getting corrupted by the fxch function.
Is it supposed to do that? Is there a way I can stop it?
|
|
| Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4711
|
Posted: Tue Sep 27, 2016 3:09 pm Post subject: |
|
|
Post your code. Whichever of the floating point registers you're swapping st(0) with obviously contains a NaN value. Set a breakpoint on the fxch instruction and look at the FPU registers to see.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
| Back to top |
|
 |
CodeReaver Newbie cheater
Reputation: 0
Joined: 19 Apr 2005 Posts: 24
|
Posted: Tue Sep 27, 2016 9:32 pm Post subject: |
|
|
| Code: | 003D0107 - DB 05 084DC500 - fild dword ptr [00C54D08] { [00000038] }
003D010D - D9CA - fxch st(2)
003D010F - 83 EC 08 - sub esp,08 { 8 }
003D0112 - D9 5C 24 FC - fstp dword ptr [esp-04]
003D0116 - D9 1C 24 - fstp dword ptr [esp]
003D0119 - D9 05 08003D00 - fld dword ptr [003D0008] { [0.80] }
003D011F - D9 05 0C003D00 - fld dword ptr [003D000C] { [1.00] }
003D0125 - 66 9C - pushf
003D0127 - 50 - push eax
003D0128 - D8D1 - fcom st(0),st(1)
003D012A - DFE0 - fnstsw ax
003D012C - 9E - sahf
003D012D - 72 02 - jb 003D0131
003D012F - D9C9 - fxch st(1)
003D0131 - DCCA - fmul st(2),st(0)
003D0133 - 58 - pop eax
003D0134 - 66 9D - popf
003D0136 - DDD8 - fstp st(0)
003D0138 - DDD8 - fstp st(0)
003D013A - D9 04 24 - fld dword ptr [esp]
003D013D - D9 44 24 FC - fld dword ptr [esp-04]
003D0141 - 83 C4 08 - add esp,08 { 8 }
003D0144 - D9CA - fxch st(2)
003D0146 - C3 - ret |
I didn't have the code with me at work, however given that the register is correct until after the second line and wrong from then onward, I didn't think it would be necessary.
These are the extended FPU registers before 003D010D (fxch st(2))
56.00
Nan
8048628.00
1026.00
632.00
1026.00
632.00
1026.00
These are the extended FPU registers afterwards
Nan
Nan
56.00
1026.00
632.00
1026.00
632.00
1026.00
So, by your logic, 8048628.00 is obviously not a number.
It puts NaN in st(0) whichever register I exchange it with. For example, I expect to see if I change it to fxch st(3)
1026.00
Nan
8048628.00
56.00
632.00
1026.00
632.00
1026.00
But I just end up with this
Nan
Nan
8048628.00
56.00
632.00
1026.00
632.00
1026.00
|
|
| Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4711
|
Posted: Tue Sep 27, 2016 11:16 pm Post subject: |
|
|
This isn't a common problem to see, so I wouldn't put it past some people to accidentally do something stupid like use a register they didn't mean to.
The only reason I can find after taking a brief look through the documentation is that the tag of the register st(2) is marked as empty, causing the fxch instruction to substitute it for a QNaN prior to the exchange.
To confirm this, pop st(0) and st(1), execute an FXAM instruction, and check the FPU status word (FNSTSW) to see if st(2) is empty or not. Another more explicit way would be to use FNSTENV to get the FPU tag word. The order of the FPU tag word corresponds to the physical registers, so get which register is the top of the stack from the FPU status word (should already have it via FNSTENV) in order to figure out which physical register is st(2).
If st(2) is marked as empty (which means that register technically isn't a number ), store the FPU environment, clear that tag's bits, load the FPU environment (FLDENV), and check if it works then.
See Intel's Software Developer's Manual Volume 1 Chapter 8 for more detailed information.
An easier solution might be to simply choose a different injection point and/or backtrace to where the program uses the value of st(2) and hook there.
_________________
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
|
|