无效的浮点运算
Invalid Floating Point Operation
我一直收到此错误 "Invalid Floating Point Operation"。
我在 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;
我什至检查了 cpu window,这是因为它试图从指向空值的指针加载浮点值。
它不是 ReadMemory,因为这段代码在 while 循环中,它 returns 在 运行 之前的几个有效值导致此错误。
我该怎么办?
提前致谢。
我们可以看到代码存在两个潜在问题。
首先你没有检查ReadProcessMemory
的return值。由于各种原因,该调用可能会失败。由于您不检查错误,因此您无法知道函数调用是否成功。始终检查 API 调用是否成功。阅读 MSDN 上的文档以了解如何执行此操作。通常这涉及检查函数 return 值,就像这里的情况一样。如果函数失败,则浮点变量可能包含未初始化的数据,并且可能会发生错误。
另一个问题是 datafloat
是通过从另一个进程读取字节来填充的。如果这些字节不代表有效的浮点值,那么如果您尝试对该值进行操作,则会引发异常。并非所有位模式都代表有效的浮点值。例如,您可能偶然发现了一个信号 NaN 值。也许您应该与 CompareMem
进行比较,因为您似乎正在读取任意内存,这看起来像是在对其他程序进行逆向工程。按位比较测试将避免将无效值加载到浮动寄存器的风险。
最后,无论 null
是什么,我都不确定您所说的针对 null
测试浮点值是什么意思。浮点值不可为空。很可能你在那里有重大的误解。
我一直收到此错误 "Invalid Floating Point Operation"。
我在 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;
我什至检查了 cpu window,这是因为它试图从指向空值的指针加载浮点值。
它不是 ReadMemory,因为这段代码在 while 循环中,它 returns 在 运行 之前的几个有效值导致此错误。
我该怎么办?
提前致谢。
我们可以看到代码存在两个潜在问题。
首先你没有检查ReadProcessMemory
的return值。由于各种原因,该调用可能会失败。由于您不检查错误,因此您无法知道函数调用是否成功。始终检查 API 调用是否成功。阅读 MSDN 上的文档以了解如何执行此操作。通常这涉及检查函数 return 值,就像这里的情况一样。如果函数失败,则浮点变量可能包含未初始化的数据,并且可能会发生错误。
另一个问题是 datafloat
是通过从另一个进程读取字节来填充的。如果这些字节不代表有效的浮点值,那么如果您尝试对该值进行操作,则会引发异常。并非所有位模式都代表有效的浮点值。例如,您可能偶然发现了一个信号 NaN 值。也许您应该与 CompareMem
进行比较,因为您似乎正在读取任意内存,这看起来像是在对其他程序进行逆向工程。按位比较测试将避免将无效值加载到浮动寄存器的风险。
最后,无论 null
是什么,我都不确定您所说的针对 null
测试浮点值是什么意思。浮点值不可为空。很可能你在那里有重大的误解。