Delphi:如何从内存中完全删除String

时间:2013-12-06 15:57:58

标签: string delphi memory encryption

Var
S1:String;
S2:String;
begin
   S1:='Sensitive Data';
   S2:=Crypt(S1,'encryption key');
   S1:='';
   FreeAndNil(S1);
end;

现在当我使用像“WinHex”这样的程序搜索我的进程内存时,我可以很容易地找到未加密的字符串! 即使我试图创建新的表单来加密这个字符串然后卸载表单但它仍然存在

有没有办法彻底删除它

提前致谢

2 个答案:

答案 0 :(得分:6)

完成后,您需要用零覆盖字符串。像这样:

ZeroMemory(Pointer(s), Length(s)*SizeOf(Char));

如果您是偏执狂,编译器将优化掉ZeroMemory,那么您可以使用SecureZeroMemory。但是,Delphi编译器不会优化ZeroMemory,所以这有点没有实际意义。

如果你只是写:

s := '';

然后内存将按原样返回给内存管理器。然后,您无法控制内存管理器何时(如果有)重新使用或返回内存。

显然你需要对字符串的所有副本执行此操作,因此唯一合理的方法是不复制敏感数据。

根据您的问题,这些都不会对代码有帮助,因为您的敏感数据是字符串文字,因此存储在可执行文件中。这种方法只能有意义地应用于动态数据。我认为你的真实程序不会将敏感数据放入文字中。

哦,不要将字符串传递给FreeAndNil。您只能将对象变量传递给FreeAndNil,但该过程使用无类型的var参数,因此编译器无法避免您的错误。

答案 1 :(得分:4)

Var
  S1:String;
  S2:String;
begin
   S1:='Sensitive Data';
   S2:=Crypt(S1,'encryption key');
   UniqueString(S1); // <-- if reference count of S1 is not 1
   ZeroMemory(Pointer(S1), Length(S1)*SizeOf(Char));
   // or better: SecureZeroMemory(Pointer(S1), Length(S1)*SizeOf(Char));
   S1:='';
end;