[HELP] Floating-point numbers in ASM

Technical Discussions not Related Directly to MHS. For Example, Coding, Hex Editing, General Hacking, Etc.

Moderators: g3nuin3, SpeedWing, WhiteHat

[HELP] Floating-point numbers in ASM

Postby CoMPMStR » Fri Nov 06, 2009 8:01 am

There's part of this game I'm hacking that uses float as the datatype even though it should be integer, for example with the skill points. The value is always a whole number, so here's my problem.

There aren't a lot of places that access the address, only 2 to be exact. I set an execute breakpoint (to see what else accesses this location) and found out that there's lots of other accessing with other values from this location. If I were to just write a simple code cave as usual, the game will crash. However, I did notice in the FPU that lots of the other values being passed through the location are not whole numbers, meaning they all have some trailing digits other than 0 behind the decimal point.

My question is how can I determine, in ASM, whether a floating-point number contains any non-zero digits in the mantissa or if it's a whole number with no fractional part?
Image

______________________________________________________
My Utilities:
CT <-> LSSAVE Converter
LSS Visual Dialog Designer
.NET Trainer Helper Library

~Whether you think you can or you think you can't, you're right.

L. Spiro wrote:In my left hand is a red pill. If you take it I will show you the truth. I lost my right hand in the war, so I’m afraid you’re stuck with the red pill.
User avatar
CoMPMStR
(P)ot (I)n (M)y (P)ipe
 
Posts: 451
Joined: Thu Mar 06, 2008 7:50 am
Location: Best Place

Postby L. Spiro » Fri Nov 06, 2009 9:46 pm

Just call msvcrt.dll:fmod with the number being parameter 1 and 1.0f being parameter 2. If the result is zero the number is whole.


L. Spiro
Our songs remind you of songs you’ve never heard.
User avatar
L. Spiro
L. Spiro
 
Posts: 3129
Joined: Mon Jul 17, 2006 10:14 pm
Location: Tokyo, Japan

Postby CoMPMStR » Sat Nov 07, 2009 12:49 am

Just as expected of the MHS creator, great solution! ;) Although a little on the brief side. :lol:

I'm still new to ASM so calling dll functions is not something I've learned to do yet (pushing parameters and so forth), so I was puzzled at first. After some searching I found an fmod ASM source and simply changed it up some to fit my code cave. :D You probably could've just told me to use fprem but I'm glad you didn't. :P Thank you!

Code: Select all
fld1                     ; Load 1.0f
fld dword ptr [esp+4]    ; Load value to check
fmod:
fprem                    ; Get the partial remainder
fstsw ax                 ; Get coprocessor status
test ax,0400h            ; Complete remainder ?
jnz fmod                 ; No, go get next remainder
fstp dword ptr [tmpval]  ; Store resulting remainder in temp location
fcomp st(1)              ; Pop to remove extra garbage
fld dword ptr [tmpval]   ; Load remainder back to check
fldz                     ; Load 0.0f
fcompp                   ; Compare and pop both
fstsw ax                 ; Retrieve comparison result in the AX register
fwait                    ; Ensure the previous instruction is completed
sahf                     ; Transfer the condition codes to the CPU's flag register
jne end                  ; Jump, if not equal to 0, to end of code


[esp+4] is the value in question being checked for remainder.
[tmpval] is an allocated memory location used to store the remainder. Needed to remove garbage and allow normal game flow, worked for me anyway.
fmod and end are labels... for anyone that's interested.
Image

______________________________________________________
My Utilities:
CT <-> LSSAVE Converter
LSS Visual Dialog Designer
.NET Trainer Helper Library

~Whether you think you can or you think you can't, you're right.

L. Spiro wrote:In my left hand is a red pill. If you take it I will show you the truth. I lost my right hand in the war, so I’m afraid you’re stuck with the red pill.
User avatar
CoMPMStR
(P)ot (I)n (M)y (P)ipe
 
Posts: 451
Joined: Thu Mar 06, 2008 7:50 am
Location: Best Place

Postby L. Spiro » Sat Nov 07, 2009 6:11 pm

To be frank I could not have advised you to use fprem anyway, as I am not proficient with the floating-point ASM instructions.
I was sure of an fmod command, but checking Google (to verify exactly how it works) for it left me with no results, and time was short so I could not afford an exhaustive search.

If it were me, I would have compiled a call to ::fmod() and looked at the disassembly to see what commands it was outputting and how the arguments
were arranged/passed.


L. Spiro
Our songs remind you of songs you’ve never heard.
User avatar
L. Spiro
L. Spiro
 
Posts: 3129
Joined: Mon Jul 17, 2006 10:14 pm
Location: Tokyo, Japan

Postby CoMPMStR » Sat Nov 07, 2009 11:10 pm

I tried looking at the msvcrt.dll:fmod disassembly to see how it was working at first, that's why I got puzzled (first it's a mov instruction followed by a jmp). Since I'm still new to this, I didn't notice anything that showed me how to call it correctly; so my last resort was doing some searching. Luckily, I just typed fmod asm into google and the first result was (more or less) exactly what I was looking to find, took me less than 5 minutes. It would've taken me alot longer to figure out how to pass the parameters and call :fmod() directly, than it did to change that source some.
Image

______________________________________________________
My Utilities:
CT <-> LSSAVE Converter
LSS Visual Dialog Designer
.NET Trainer Helper Library

~Whether you think you can or you think you can't, you're right.

L. Spiro wrote:In my left hand is a red pill. If you take it I will show you the truth. I lost my right hand in the war, so I’m afraid you’re stuck with the red pill.
User avatar
CoMPMStR
(P)ot (I)n (M)y (P)ipe
 
Posts: 451
Joined: Thu Mar 06, 2008 7:50 am
Location: Best Place


Return to Technical Unrelated

Who is online

Users browsing this forum: No registered users and 0 guests

cron