Safeguarding sensitive data from hackers or processes debuggers by protecting memory regions from access and ensuring data is cleared when no longer needed.

It's crucial to protect sensitive information, such as encryption keys, passwords, and other confidential data, from unauthorized access. Without proper memory protection, even temporarily stored sensitive data in memory can be vulnerable to attacks like memory dumps or process injection. This unit helps to lock and protect memory, ensuring that sensitive data is shielded and securely erased when no longer needed.
ProtectedMemory unit to your Delphi project.ProtectMemory, UnProtectMemory, and ReleaseProtectedMemory procedures to secure your memory.ReleaseAllProtectedMemory.TProtectedStream classTProtectedStream class was added, inheriting from TMemoryStream.VirtualAlloc for memory allocation and VirtualProtect to protect and unprotect the memory.IsProtected property lets you toggle between protected (no access) and unprotected (read/write) states.uses
ProtectedMemory;
var
Data: array[0..255] of Byte;
DataPtr: Pointer;
begin
Data[0] := 99;
Data[1] := 11;
Data[2] := 22;
Data[3] := 33;
Data[4] := 44;
Data[5] := 55;
DataPtr := @Data[0];
// Protect the memory (prevents access to the memory region)
ProtectMemory(DataPtr, SizeOf(Data));
// Accessing the protected memory here will return zeros.
// Unprotect the memory before accessing it
UnProtectMemory(DataPtr);
// Optionally release the memory and clear its content
ReleaseProtectedMemory(DataPtr);
end;uses
ProtectedMemory;
var
SensitiveStr: string;
NonSensitiveStr: string;
DataPtr: Pointer;
begin
SensitiveStr := 'Sensitive Data';
NonSensitiveStr := 'Not Sensitive Data';
// Get a pointer to SensitiveStr's memory
DataPtr := Pointer(SensitiveStr);
// Protect the memory region containing SensitiveStr
Writeln('Protecting memory...');
ProtectMemory(DataPtr, Length(SensitiveStr) * SizeOf(Char));
// Accessing SensitiveStr here will return zeros or show undefined behavior
Writeln('SensitiveStr after protection: ', SensitiveStr);
// You can still access NonSensitiveStr, which is unaffected
NonSensitiveStr := 'Updated Non-Sensitive Data';
Writeln('NonSensitiveStr: ', NonSensitiveStr);
// UnProtect Memory it's reutrn it's orginal data
Writeln('Releasing memory...');
UnProtectMemory(DataPtr);
// SensitiveStr is now restored
Writeln('Restored SensitiveStr: ', SensitiveStr);
end;uses
ProtectedStream;
var
Stream: TProtectedStream;
Data: AnsiString;
Buffer: array[0..255] of Byte;
begin
Data := 'Sensitive Data';
Stream := TProtectedStream.Create;
try
Stream.Write(PAnsiChar(Data)^, Length(Data));
Data := '';
Stream.IsProtected := True; // Protect the memory
// Unprotect to read
Stream.IsProtected := False;
Stream.Read(Buffer, 10);
finally
Stream.Free;
end;
end;ProtectMemory(var DataPtr: Pointer; Size: NativeUInt): Protects the specified memory region by setting it to PAGE_NOACCESS and locking it to prevent paging. The data is copied to a new protected memory block, and the original pointer is updated to point to this protected block.
UnProtectMemory(DataPtr: Pointer): Restores the memory protection to PAGE_READWRITE and removes the region from the list of protected memory blocks.
ReleaseProtectedMemory(DataPtr: Pointer): Restores memory access, clears the content by securely zeroing the memory, and removes it from the protected list.
ReleaseAllProtectedMemory(): Releases and clears all protected memory regions.
Shadi Ajam
YES! We’d love your support! Please give it a ? and share it with others.
Share on social media: