AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Code-Bibliothek Neuen Beitrag zur Code-Library hinzufügen Delphi Dateipfad eines Prozess Images für 64 bit Prozesse ermitteln
Thema durchsuchen
Ansicht
Themen-Optionen

Dateipfad eines Prozess Images für 64 bit Prozesse ermitteln

Ein Thema von Zacherl · begonnen am 25. Apr 2011 · letzter Beitrag vom 8. Aug 2012
Antwort Antwort
Benutzerbild von Zacherl
Zacherl

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

Dateipfad eines Prozess Images für 64 bit Prozesse ermitteln

  Alt 25. Apr 2011, 18:13
In folgendem Thread kam die Frage auf, wie man den Prozesspfad eines 64 bit Prozesses ermitteln kann:
http://www.delphipraxis.net/160026-p...iatedicon.html

Da MSDN-Library durchsuchenGetModuleFileNameEx und Konsorten leider fehlschlagen, wenn man versucht aus einem 32 bit Prozess auf einen 64 bit Prozess zuzugreifen, muss man ein wenig in die Trickkiste greifen und die native MSDN-Library durchsuchenNtQueryInformationProcess API verwenden. Folgender Code ermittelt den Image Pfad eines beliebigen Prozesses anhand der Prozess ID und konvertiert den nativen Pfad ins standard DOS Format.

Edit 1: Für Systeme ab Windows Vista wird nun zuerst versucht die MSDN-Library durchsuchenQueryFullProcessImageName API aufzurufen, welche den exakten DOS Pfad für beliebige Prozesse, egal ob 32 oder 64 bit liefert.
Edit 2: Die native MSDN-Library durchsuchenNtQueryInformationProcess API habe ich durch MSDN-Library durchsuchenGetProcessImageFileName ersetzt. Diese Funktion ist zwar erst ab XP verfügbar, dies macht aber nichts, da es von Windows kleiner XP sowieso keine 64 bit Versionen gab.
Edit 3: Für Systeme unter Windows XP wird nun MSDN-Library durchsuchenGetModuleFileNameEx als Fallback verwendet, um den Prozesspfad zu ermitteln.

Delphi-Quellcode:
function DeviceNameToFilePath(FileName: String): String;
var
  Buffer: array[0..MAX_PATH - 1] of Char;
  BufferSize: DWord;
  LogicalDrives: array of Char;
  I: Integer;
  DeviceName: String;
begin
  Result := '';
  BufferSize := GetLogicalDriveStrings(MAX_PATH, @Buffer[0]);
  if (BufferSize = 0) then Exit;
  SetLength(LogicalDrives, (BufferSize - 2 * SizeOf(Char)) div 3);
  for I := Low(LogicalDrives) to High(LogicalDrives) do
  begin
    LogicalDrives[I] := Buffer[I * 4];
  end;
  for I := Low(LogicalDrives) to High(LogicalDrives) do
  begin
    BufferSize := QueryDosDevice(PChar(LogicalDrives[I] + ':'),
      @Buffer[0], MAX_PATH);
    if (BufferSize > 0) then
    begin
      DeviceName := AnsiLowerCase(PWideChar(@Buffer[0]));
      if (AnsiLowerCase(Copy(FileName, 1, Length(DeviceName))) =
        DeviceName) then
      begin
        Result := LogicalDrives[I] + ':' + Copy(FileName,
          Length(DeviceName) + 1, Length(FileName));
        Exit;
      end;
    end;
  end;
end;

function GetProcessPathByHandle(hProcess: THandle): String;
var
  QueryFullProcessImageName: function(hProcess: THandle; dwFlags: DWord;
    ImageFileName: PWideChar; dwSize: PDWord): BOOL; stdcall;
  GetProcessImageFileName: function(hProcess: THandle;
    ImageFileName: PWideChar; dwSize: DWord): DWord; stdcall;
  GetModuleFileNameEx: function(hProcess: THandle; hModule: HMODULE;
    FileName: PWideChar; dwSize: DWord): DWord; stdcall;
  FileName: array[0..MAX_PATH - 1] of WideChar;
  BufferSize: DWord;
begin
  Result := '';
  // Windows Vista or higher
  @QueryFullProcessImageName := GetProcAddress(LoadLibrary('kernel32.dll'),
    'QueryFullProcessImageNameW');
  if Assigned(QueryFullProcessImageName) then
  begin
    BufferSize := MAX_PATH;
    if (QueryFullProcessImageName(hProcess, 0, @FileName[0], @BufferSize)) then
    begin
      Result := PWideChar(@FileName[0]);
      Exit;
    end;
  end;
  // Windows XP
  @GetProcessImageFileName := GetProcAddress(LoadLibrary('kernel32.dll'),
    'GetProcessImageFileNameW');
  if (not Assigned(GetProcessImageFileName)) then
  begin
    @GetProcessImageFileName := GetProcAddress(LoadLibrary('psapi.dll'),
      'GetProcessImageFileNameW');
  end;
  if Assigned(GetProcessImageFileName) then
  begin
    BufferSize := GetProcessImageFileName(hProcess, @FileName[0], MAX_PATH);
    if (BufferSize > 0) then
    begin
      Result := DeviceNameToFilePath(PWideChar(@FileName[0]));
      Exit;
    end;
  end;
  // Windows 2000
  @GetModuleFileNameEx := GetProcAddress(LoadLibrary('kernel32.dll'),
    'GetModuleFileNameExW');
  if (not Assigned(GetModuleFileNameEx)) then
  begin
    @GetModuleFileNameEx := GetProcAddress(LoadLibrary('psapi.dll'),
      'GetModuleFileNameExW');
  end;
  if Assigned(GetModuleFileNameEx) then
  begin
    BufferSize := GetModuleFileNameEx(hProcess, 0, @FileName[0], MAX_PATH);
    if (BufferSize > 0) then
    begin
      Result := PWideChar(@FileName[0]);
      // Bugfix for system and service processes
      if (Copy(Result, 1, 4) = '\??\') then
      begin
        Result := Copy(Result, 5, Length(Result));
      end;
      Exit;
    end;
  end;
end;

function GetProcessPathByPID(PID: DWord): String;
var
  hProcess: THandle;
begin
  Result := '';
  hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
    false, PID);
  if (hProcess <> 0) and (hProcess <> INVALID_HANDLE_VALUE) then
  try
    Result := GetProcessPathByHandle(hProcess);
  finally
    CloseHandle(hProcess);
  end;
end;
Viele Grüße
Zacherl
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)

Geändert von Zacherl (26. Apr 2011 um 21:24 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

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

AW: Dateipfad eines Prozess Images für 64 bit Prozesse ermitteln

  Alt 26. Apr 2011, 21:26
Copy & Paste Bug beim Importieren der APIs gefixt
Bugfix für System und Service Prozesse. Bei Prozessen, auf die man nur mit dem SeDebugPrivilege zugreifen kann, wird unter Windows 2000 die Zeichenfolge "\??\" der Rückgabe von GetModuleFileNameEx() vorangestellt.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
hesch21

Registriert seit: 31. Aug 2004
Ort: Basel
114 Beiträge
 
Delphi XE2 Enterprise
 
#3

AW: Dateipfad eines Prozess Images für 64 bit Prozesse ermitteln

  Alt 21. Jun 2012, 11:53
Hallo Zacherl

die Funktion wäre super, nur bring ich sie leider nicht zum funktionieren. Erste kleine Anmerkung: Bei Delphi7 gibt's bei
Delphi-Quellcode:
    BufferSize := QueryDosDevice(PChar(LogicalDrives[I] + ':'),
      @Buffer[0], MAX_PATH);
in der
Code:
function DeviceNameToFilePath(FileName: String): String;
einen Typumwandlungsfehler.
Lösung: Eine String-Variable (hi) deklarieren und:
Code:
      hi := LogicalDrives[I] + ':';
      BufferSize := QueryDosDevice(PChar(hi), @Buffer[0], MAX_PATH);
Ich habe zum Testen ein ganz dämliches Programm drum herum gebastelt. Ein Button und ein Edit. ins Edit-Feld gebe ich aus dem Task-Manager eine PID (z.B. von Delphi) ein und mit der rufe ich GetProcessPathByPID auf. Ich bekomme aber immer einen leeren String zurück.
Getestet auf XP-Prof. mit Delphi7. Wenn ich das mit dem Debugger durchspiele, holt er sich zwar ein ImageFileName über die PSAPI.DLL. Aber irgendwie verliert er sich în der Umwandlungsroutine DeviceNameToFilePath. Ich kann mir nicht vorstellen, dass es mit meiner oben erwähnten Korrektur zu tun, vermute aber viel mehr irgend ein Delphi-Versionen-Problem
Heinz Schneider

Geändert von hesch21 (21. Jun 2012 um 16:21 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

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

AW: Dateipfad eines Prozess Images für 64 bit Prozesse ermitteln

  Alt 8. Aug 2012, 16:39
Kannst du erkennen, was genau in der Funktion schief geht? Die DeviceNameToFilePath() Funktion ist leider ziemlich dirty, allerdings kenne ich keine bessere Möglichkeit.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:32 Uhr.
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