Einzelnen Beitrag anzeigen

Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#14

AW: Vollständigen Datei- oder Verzeichnisnamen über das Handle ermitteln

  Alt 26. Apr 2012, 16:30
Ich verweise hier nochmal auf das Alignment bzw. die Enum Typ Größe. Mit den entsprechenden Compiler Switches funktionieren bei mir folgende Varianten problemlos:
Delphi-Quellcode:
var
  ReturnLength: ULONG;
begin
  // Deklaration als PULONG
  NtQueryObject(x, x, x, x, @ReturnLength);
  // Deklaration als var ULONG
  NtQueryObject(x, x, x, x, ReturnLength);
Ich kann mich irren, aber soweit ich weiß, interpretiert Delphi einen OUT Parameter genauso wie einen VAR Parameter. Sprich, wenn du, wie in deinem Beispiel ReturnLength als OUT PULONG deklarierst, ist das dann der Pointer auf den Pointer auf ReturnLength und nicht nur der Pointer auf ReturnLength.

Außerdem: Wenn du ReturnLength lokal als PULONG deklarierst, dann zeigt dieser Pointer entweder ins Leere (auf 0) oder wird mit einem Zufallswert initialisiert. Ruftst du dann die API auf und übergibst die Variable direkt, dann wird natürlich versucht die Rückgabelänge in einen invaliden Speicherbereich zu schreiben.
Wenn du ReturnLength aber als ULONG deklarierst und dann @ReturnLength übergibst, zeigt der Pointer auf die korrekt adressierte lokale Variable.

Zur Verdeutlichung:
Delphi-Quellcode:
var
  ReturnLength: ULONG;
  pReturnLength: PULONG;
begin
  // Wir gehen von einer ReturnLength deklaration als PULONG aus
  // FALSCH:
  // pReturnLength ist hier ein uninitialisierter Pointer.
  // die API versucht die Länge zu schreiben, indem sie dereferenziert: pReturnLength^ := Länge
  // da der Pointer aber auf einen undefinierten Speicherbereich zeigt, bekomst du eine AV
  NtQueryObject(x, x, x, x, pReturnLength);
  // RICHTIG:
  // der Speicher von ReturnLength wurde von Delphi korrekt alloziiert
  // wir übergeben die Referenz auf diesen Speicher, also den Pointer, der auf ReturnLength zeigt
  NtQueryObject(x, x, x, x, @ReturnLength);
Das Problem mit der Übergabe von Length = 0 kann ich ebenfalls nicht nachvollziehen. Der Aufruf von NtQueryObject(x, x, nil, 0, x) funktioniert für mich wunderbar. Aber vermutlich rührt dieses Problem von deiner fehlerhaften Implementation der ReturnLength her.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)

Geändert von Zacherl (26. Apr 2012 um 16:50 Uhr)
  Mit Zitat antworten Zitat