Invalid Floating Point Operation

12,925

There are two potential problems with the code that we can see.

First of all you do not check the return value of ReadProcessMemory. That call could fail for a variety of reasons. Since you don't check for errors you have no way of knowing whether or not the function call succeeded. Always check API calls for success. Read the docs on MSDN to find out how to do so. Usually this involves checking the function return value, as is the case here. If the function fails, then the floating point variable may contain uninitialized data and an error may ensue.

The other problem is that datafloat is being populated by reading bytes from another process. If those bytes do not represent a valid floating point value, then an exception will be raised if you try to operate on that value. Not all bit patterns represent valid floating point values. For instance, you may have hit upon a signaling NaN value. Perhaps you should be comparing with a CompareMem given that you appear to be reading arbitrary memory in what looks like an effort to reverse engineer some other program. Testing by bitwise comparison will avoid the risk of loading invalid values into floating registers.

Finally, I'm not sure what you mean by testing a floating point value against null, whatever null is. Floating point values are not nullable. It is very likely that you have a significant misunderstanding there.

Share:
12,925

Related videos on Youtube

D3X
Author by

D3X

Updated on June 14, 2022

Comments

  • D3X
    D3X almost 2 years

    I keep getting this error "Invalid Floating Point Operation".

    I'm on Delphi 7.

    uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    TlHelp32, Dialogs, StdCtrls, ExtCtrls, Buttons, ComCtrls;
    
    var //global
    PHandle, cancel, bytes, scantype: integer;
    

    ...

    procedure Tmain.scanbtnClick(Sender: TObject);
        var max, address: Integer;
        floatinput, floatinput1, floatinput2, datafloat: Real;
        x: cardinal;
        itm: TListItem;
    begin
    
      floatinput := StrToFloat(Trim(valueinput.Text));
      floatinput1 := StrToFloat(Trim(valueinput1.Text));
      floatinput2 := StrToFloat(Trim(valueinput2.Text));
    
      if floatinput2 < floatinput1 then
      begin
        floatinput1 := floatinput1 + floatinput2;
        floatinput2 := floatinput1 - floatinput2;
        floatinput1 := floatinput1 - floatinput2;
      end;
    
      result.Show;
    
      x := 0;
      address := 0;
    
      result.resultlist.Clear;
    
      repeat
        Application.ProcessMessages;
        statusbar1.Panels.Items[1].Text := 'Searching... ' + IntToStr(address * 100 div max) + '% (' + IntToStr(address div bytes) + ' out of ' + IntToStr(max div bytes) + ').';
    
        if ReadprocessMemory(PHandle, Ptr(address), @datafloat, bytes, x) then
          begin
            if (x > 0) then
            begin
              if scantype = 0 then
              begin
                if datafloat = floatinput then             //error here
                begin
                  itm := result.resultlist.Items.Add;
                  itm.Caption := '0x' + IntToHex(address,8);
                  itm.SubItems.Add(FormatFloat('0.0#########', datafloat));
                end;
              end;
              if scantype = 1 then
              begin
                if datafloat > floatinput              //also here
                then begin
                  itm := result.resultlist.Items.Add;
                  itm.Caption := '0x' + IntToHex(address,8);
                  itm.SubItems.Add(FormatFloat('0.0#########', datafloat));
                end;
              end;
              if scantype = 2 then
              begin
                if datafloat < floatinput     //here too
                then begin
                  itm := result.resultlist.Items.Add;
                  itm.Caption := '0x' + IntToHex(address,8);
                  itm.SubItems.Add(FormatFloat('0.0#########', datafloat));
                end;
              end;
              if scantype = 2 then
              begin
                if (dataint <= intinput2) and (dataint >= intinput1)    //even here
                then begin
                  itm := result.resultlist.Items.Add;
                  itm.Caption := '0x' + IntToHex(address,8);
                  itm.SubItems.Add(FormatFloat('0.0#########', datafloat));
                end;
              end;
    
            end;
          end;
    
        if x <> 0
        then address := address + x
        else address := address + bytes;
    
      until (address >= Max) or (cancel = 1);
    
    end;
    

    I even checked on the cpu window, and it happens because its trying to load a floating point value from a pointer that is pointing at a null value.

    It's not the ReadMemory, because this little piece of code is on a while loop and it returns several valid values before running into this error.

    What should I do?

    Thanks in advance.

  • D3X
    D3X over 8 years
    Okay so i changed my code, and now i only proceed if the result of ReadProcessMemory is true, and then i check if the number of bytes read is > 0, and even though i don't fully understand why, the comparemem routine worked, but what if i want to know if datafloat > floatinput? Shouldn't I be able to compare two real values?
  • D3X
    D3X over 8 years
    Actually.. nope. CompareMem is returning false even when it should return true, when i use normal comparison it returns only the values that it should, but always step in this error after a while..
  • D3X
    D3X over 8 years
    Okay, i fixed it, your answer was actually really usefull. What i did was declare 'Math' in uses and then check if 'datafloat' is not a NaN by using the IsNan routine, thank you.
  • David Heffernan
    David Heffernan over 8 years
    CompareMem will work if you use it right. If you want to do other than equality comparison for non-zero, finite values it will work. Using IsNaN is a good option. The whole point is that you are operating on values whose provenance you don't know.