Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#16

AW: Program crasht beim Schließen, aber...

  Alt 25. Feb 2020, 01:52
Sowas kann man per se sich auch selbst schnell bauen.
Eigentlich würde es reichen, wenn man das FreeMemory überschreibt und dort den Inhalt "zerstört", dann werden Zugriffe nach dem Free fehlschlagen.

Der wichtige Teil ist natürlich das FillMemory/FillChar.
Delphi-Quellcode:
function MyFreeMem(P: Pointer): Integer;
begin
  FillMemory(P, UnknownSize, $A5); // 1010 0101 = HighBit + Odd
  Result := SysFreeMem(P);
end;

var
  MemMgr: TMemoryManagerEx;

initialization
  GetMemoryManager(MemMgr);
  MemMgr.FreeMem := MyFreeMem;
  SetMemoryManager(MemMgr);

finalization
  GetMemoryManager(MemMgr);
  MemMgr.FreeMem := SysFreeMem; // oder MemMgr.FreeMem im Init speichern
  SetMemoryManager(MemMgr);

end.
Aber leider ist es nicht so einfach im FreeMem die Größe rauszubekommen.
(wäre auch zu einfach gewesen, wenn diese MemoryAPI uns den Wert direkt als Parameter geben würde )

Im Windows (wenn FastMM verwendet) könnte erstmal rausfinden in was für einem Block (SmallXXX, Medium oder Large) der Speicher liegt
und dementsprechend dann auslesen wie groß der Speicher ist (inkl. dem zusätzlichen Speicher dahinter).
Bei den Small ist die Größe bekannt und bei den Anderen steht sie (ähnlich wie hier) vor den Daten gespeichert.

In Liunx/MacOS/iOS/Android kann es nochmal anders aussehn.

Nja, also der umständlicheren Einfachheit halber einfach die Größe noch mit einfügen, um schnell und sicher den Wert vom GetMem zu bekommen.
Delphi-Quellcode:
function MyGetMem(Size: NativeInt): Pointer;
begin
  Inc(Size, SizeOf(Integer));
  Result := SysGetMem(Size);
  PInteger(Result)^ := Size;
  Inc(NativeInt(Result), SizeOf(Integer));
end;

function MyFreeMem(P: Pointer): Integer;
begin
  Dec(NativeInt(P), SizeOf(Integer));
  FillMemory(P, PInteger(P)^, $A5); // 1010 0101 = HighBit + Odd
  Result := SysFreeMem(P);
end;

function MyReallocMem(P: Pointer; Size: NativeInt): Pointer;
begin
  Dec(NativeInt(P), SizeOf(Integer));
  Inc(Size, SizeOf(Integer));
  Result := SysReallocMem(P, Size);
  PInteger(Result)^ := Size;
  Inc(NativeInt(Result), SizeOf(Integer));
end;

function MyAllocMem(Size: NativeInt): Pointer;
begin
  Inc(Size, SizeOf(Integer));
  Result := SysAllocMem(Size);
  PInteger(Result)^ := Size;
  Inc(NativeInt(Result), SizeOf(Integer));
end;

var
  MemMgr: TMemoryManagerEx;

initialization
  GetMemoryManager(MemMgr);
  MemMgr.GetMem := MyGetMem;
  MemMgr.FreeMem := MyFreeMem;
  MemMgr.ReallocMem := MyReallocMem;
  MemMgr.AllocMem := MyAllocMem;
  SetMemoryManager(MemMgr);

finalization
  GetMemoryManager(MemMgr);
  MemMgr.GetMem := SysGetMem;
  MemMgr.FreeMem := SysFreeMem;
  MemMgr.ReallocMem := SysReallocMem;
  MemMgr.AllocMem := SysAllocMem;
  SetMemoryManager(MemMgr);

end.
und nicht vergessen, dass dieses in der DPR als erste Unit im Uses sein muß
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (25. Feb 2020 um 11:00 Uhr) Grund: das komische "Allert" entfernt
  Mit Zitat antworten Zitat