我正在编写一些适用于机密(对我而言)数据的应用程序。我希望,理想情况下,在它工作之后,内存中的这些数据不会有“尾巴”。
在这方面,出现了一个想法:如您所知,SetLength() 过程在增加字符串/数组的大小时,可以为其分配一个新的内存块,如果它没有足够的空间,则从旧内存块复制数据旧位置新尺寸的空间。
好吧,实际上问题是:是否可以使用这样的包装器(见评论)?
procedure SecureResize(var Data: TBytes; NewSize: Integer);
var
OldPtr: Pointer;
OldSize: Integer;
begin
OldPtr := Pointer(Data);
OldSize := Length(Data);
SetLength(Data, NewSize);
if (OldSize < NewSize) and (OldPtr <> Pointer(Data)) then
begin {
Данные были перемещены, поэтому необходимо затереть их в старой
локации. Формально, OldPtr указывает на "свободный" участок памяти,
но может ли его за это время занять другой процесс или можно
гарантировать что в этом месте он ещё никем не занят и спокойно
затереть данные?.. }
FillChar(OldPtr^, OldSize, 0);
end else if OldSize > NewSize then
FillChar(Data[NewSize], OldSize - NewSize, 0);
end;
在“这样的包装器”中,可能存在 AV,因为旧页面可能已经是“MEM_RELEASE”。
您可以简单地创建一个新的副本数组,然后清理旧的。
但是,我认为,为此类数据创建(将它们封装在)一个类以覆盖 FreeInstance 以满足您的需要更具建设性。
RtlSecureZeroMemory,因为优化器可能会抛出未使用的内存清零。