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