Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Neuen Beitrag zur Code-Library hinzufügen (https://www.delphipraxis.net/33-neuen-beitrag-zur-code-library-hinzufuegen/)
-   -   Delphi Data Execution Prevention (DEP) aktivieren (https://www.delphipraxis.net/153501-data-execution-prevention-dep-aktivieren.html)

HeikoAdams 5. Aug 2010 13:19

Data Execution Prevention (DEP) aktivieren
 
Da bei älteren Delphi-Versionen die Data Execution Prevention noch manuell aktiviert werden muss, kann man die nachfolgende Funktion dafür nutzen.
Delphi-Quellcode:
function ActiveDEP: Cardinal;
const
  OptIn: Byte = 2;
  PROCESS_DEP_ENABLE = 1;
var
  Info: TOSVersionInfo;
  SetProcessDEPPolicy: function (dwFlags: dword): Boolean; stdcall;
  GetSystemDEPPolicy: function: Word; stdcall;
  nStatus: Word;
  h :HINST;
begin
  Result := S_FALSE;
  ZeroMemory(@Info, SizeOf(TOSVersionInfo));
  Info.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);

  // Wir benötigen mind. Windows XP SP3
  if Windows.GetVersionEx(Info)
    and (Info.dwMajorVersion >= 6)
    or ((Info.dwMajorVersion = 5)
    and (Info.dwMinorVersion = 1)
    and (lstrcmpi(Info.szCSDVersion, 'Service Pack 3') = 0)) then
  begin
    h := SafeLoadLibrary('Kernel32.dll', SEM_NOOPENFILEERRORBOX);
    nStatus := OptIn;

    // Den aktuellen systemweiten Status der Datenausführungsverhinderung (DEP) abfragen
    if (h <> 0) then
    begin
      @GetSystemDEPPolicy := GetProcAddress(h, 'GetSystemDEPPolicy');
      FreeLibrary(h);    
      nStatus := GetSystemDEPPolicy();
    end;

    // Wenn der Staus auf OptIn (=2) steht, dann kann DEP für den aktuelle Prozess aktviert werden
    if (nStatus = OptIn) then
    begin
      h := SafeLoadLibrary('Kernel32.dll', SEM_NOOPENFILEERRORBOX);

      if (h <> 0) then
      begin
        @SetProcessDEPPolicy := GetProcAddress(h, 'SetProcessDEPPolicy');
        FreeLibrary(h);

        if not SetProcessDEPPolicy(PROCESS_DEP_ENABLE) then
          Result := GetLastError
        else
          Result := S_OK;
      end;
    end;
  end
  else
    Result := ERROR_OLD_WIN_VERSION;
end;

Bernhard Geyer 5. Aug 2010 13:39

AW: Data Execution Prevention (DEP) aktivieren
 
Danke für den Code. :thumb: War vor ein paar Tagen auch auf der Suche ...

Zitat:

Zitat von HeikoAdams (Beitrag 1039772)
Da bei älteren Delphi-Versionen die Data Execution Prevention noch manuell aktiviert werden muss,

Wie kann man das bei neueren Delphi-Versionen (hier D2009) alternativ machen?

Und hast du dich evtl. auch schon bezüglich ASLR auf die suche gemacht?

himitsu 5. Aug 2010 13:46

AW: Data Execution Prevention (DEP) aktivieren
 
Zitat:

Zitat von Bernhard Geyer (Beitrag 1039781)
Und hast du dich evtl. auch schon bezüglich ASLR auf die suche gemacht?

Hier ist vorallem "schön", daß A) viele DLL-Ersteller (auch in Delphi) die Standard-ImageBase belassen
und b) selbst viele windowseigene DLLs den selben Adressraum belegen.

Kein Wunder daß da viele DLLs verschoben werden müssen und dadurch auch nicht unbedingt immer am selben Platz liegen :wall:

HeikoAdams 5. Aug 2010 13:50

AW: Data Execution Prevention (DEP) aktivieren
 
Zitat:

Zitat von Bernhard Geyer (Beitrag 1039781)
Wie kann man das bei neueren Delphi-Versionen (hier D2009) alternativ machen?

AFAIK macht das bei neueren Version der Compiler. Kann man über den Process-Explorer von Sysinternals prüfen ;)

Zitat:

Zitat von Bernhard Geyer (Beitrag 1039781)
Und hast du dich evtl. auch schon bezüglich ASLR auf die suche gemacht?

Jepp, hab da aber noch nicht zu gefunden.

Edit: Ich habe die Funktion ein wenig überarbeitet, so dass jetzt im Fehlerfall der Wert von GetLastError zurückgeliefert wird. Damit kann man dann auch mehr anfangen als mit True/False ;)

rob74 7. Aug 2010 15:42

AW: Data Execution Prevention (DEP) aktivieren
 
Ich habe mich auch in letzter Zeit mit diesem Thema beschäftigt. Die einfachste Möglichkeit ist, die Compiler-Direktive {$SetPEOptFlags $0140} (am besten im Projekt-Quelltext) zu verwenden - dies setzt den DllCharacteristics-Wert des Optional PE Headers (Siehe MSDN). $0100 heißt IMAGE_DLLCHARACTERISTICS_NX_COMPAT (aktiviert DEP), $0040 heißt IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE (aktiviert ASLR). Das funktioniert sogar in älteren Delphi-Versionen (ich weiß nicht seit wann es SetPEOptFlags gibt, aber in Turbo Delphi funktioniert's problemlos).

Das Ganze hat leider einen Haken: diese Flags werden nur unter Vista und 7 ausgewertet, unter XP nicht. Das heißt, unter XP (ab SP2) entscheidet das System, welcher Prozess DEP kriegt und welcher nicht - außer das Programm benutzt die Funktion SetProcessDEPPolicy. Diese Funktion gibt es leider aber erst ab XP SP3 (und in Vista erst ab SP1). Um DEP auch unter XP SP2 nutzen zu können, kann man es wie der Chromium-Browser machen: die rufen die undokumentierte Funktion NtSetInformationProcess mit den Parametern ProcessExecuteFlags= PROCESS_INFORMATION_CLASS=$22 und ProcessInformation=MEM_EXECUTE_OPTION_PERMANENT | MEM_EXECUTE_OPTION_ENABLE=$9 auf (Quellcode zu sehen bei Google Code Search).

ASLR gibt's unter XP übrigens gar nicht, erst unter Vista.

himitsu 7. Aug 2010 15:49

AW: Data Execution Prevention (DEP) aktivieren
 
Zitat:

Zitat von rob74 (Beitrag 1040152)
Die einfachste Möglichkeit ist, die Compiler-Direktive {$SetPEOptFlags $0140} (am besten im Projekt-Quelltext) zu verwenden ...
(ich weiß nicht seit wann es SetPEOptFlags gibt, aber in Turbo Delphi funktioniert's problemlos).

Seit Delphi 2009/2010 geht das auch über die Projektoptionen siehe Delphi-Compiler > Linken > zuätzliche optionale PE-Header-Flags setzen

Bernhard Geyer 7. Aug 2010 16:23

AW: Data Execution Prevention (DEP) aktivieren
 
Zitat:

Zitat von rob74 (Beitrag 1040152)
Ich habe mich auch in letzter Zeit mit diesem Thema beschäftigt. Die einfachste Möglichkeit ist, die Compiler-Direktive {$SetPEOptFlags $0140} (am besten im Projekt-Quelltext) zu verwenden ...

Danke. Das ist genau das was ich mal ausprobieren will um auch solche Fehler schon in de Entwicklung zu finden und nicht DEP-Fehler nur bei Kunden zu haben und selbst nich nachvollziehen zu können.

Christian Seehase 7. Aug 2010 23:55

AW: Data Execution Prevention (DEP) aktivieren
 
Zitat:

Zitat von himitsu (Beitrag 1039784)
Kein Wunder daß da viele DLLs verschoben werden müssen und dadurch auch nicht unbedingt immer am selben Platz liegen :wall:

Der Vorteil ist aber, dass so manches Schadprogramm vor die Wand läuft, da es sich, gerade bei System-DLLs, auf bestimmte Adressen verlässt.

himitsu 8. Aug 2010 07:30

AW: Data Execution Prevention (DEP) aktivieren
 
Der Code-Speicher dürfte doch als CopyOnWrite definiert sein ... wenn sich da alles Verschiebt, müssen überall die Adressen geändert werden und dann hätte jeder Prozess seine eigene DLL-Version.

Bei vielen DLLs läppert sich das und Speicher muß man doch nicht unbedingt verschwenden.

Und dieses ASLR würde das dann noch verschlimmern. :?
Wird das eigentlich auf alle DLLs angewendet oder läßt sich dieses nur auch "wichtige" DLLs beschränken?

Aber notfalls läßt sich das auch bei dynamisch geladene DLLs selber etwas machen oder man bastelt sich selber einen EXE/DLL-Loader (sowas wie bei UPX) und das würde dann auch unter XP und Co. laufen.

Fridolin Walther 8. Aug 2010 08:21

AW: Data Execution Prevention (DEP) aktivieren
 
Zitat:

Zitat von himitsu (Beitrag 1040210)
Der Code-Speicher dürfte doch als CopyOnWrite definiert sein ... wenn sich da alles Verschiebt, müssen überall die Adressen geändert werden und dann hätte jeder Prozess seine eigene DLL-Version.

Nunja, ganz so dramatisch ist es dann doch nicht. ASLR legt die neuen Image Bases letztlich nicht pro Prozess sondern pro Reboot fest. Bedeutet innerhalb der selben Sitzung haben alle DLLs die selben Image Bases. Erst nach einem Reboot wird wieder durcheinander gewuerfelt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:16 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz