![]() |
AW: CommandLines der Prozesse unter Windows 64 Bit ermitteln?
Zitat:
|
AW: CommandLines der Prozesse unter Windows 64 Bit ermitteln?
Zitat:
Ohne die beiden letztgenannten Units geht es in der Zeile
Delphi-Quellcode:
function GetPeb32(ph : THandle; var PEB : TPeb32):Boolean;
los, dort findet der Compilter den Typ TPeb32 nicht, dito weiter unten mit TPeb64. Weiter geht es mit
Delphi-Quellcode:
dort findet er den 2. und 3. Typ der var-Listung nicht.
Function PEB32ProcName(ph : THandle; Base:boolean):String;
var PEB : TPeb32; LdrData : TPebLdrData32; LdrModule : TLdrDataTableEntry32; Die paar anderen Kleckermeldungen gehen anscheinend darauf zurück, daß diese Typen unbekannt sind. Nochmals besten Dank und viele Grüße Delphi-Laie |
AW: CommandLines der Prozesse unter Windows 64 Bit ermitteln?
Liste der Anhänge anzeigen (Anzahl: 1)
Du findest Nicos Units hier:
![]() // EDIT: Ich habe die Datei mal angehängt, da das laut Lizenz erlaubt ist. |
AW: CommandLines der Prozesse unter Windows 64 Bit ermitteln?
Sebastian, Du bist ein Schatz! Ich suchte direkt nach den Unit-Dateinamen und war damit natürlich nicht erfolgreich.
Nochmals besten Dank Euch beiden! |
AW: CommandLines der Prozesse unter Windows 64 Bit ermitteln?
Zitat:
![]() erstes Ergebnis, ganz unten: ![]() ;-) |
AW: CommandLines der Prozesse unter Windows 64 Bit ermitteln?
Wie auch immer, ich kam bei der Suche jedenfalls nicht bis zum gewünschten Ziele.
Ich staune immer wieder, wie viele im Internet veröffentlichte Quelltexte mir Probleme bereiten, hier das von Zacherl verlinkte Beispielprogramm. Hier meine Erfahrungen mit XE2: 1. Die Compilerdirektive {$IFDEF CPU64} erzeugte merkwürdige Fehler im {$Else}-Zweig (nachdem die 32-Bit-Compilierung fehlerfrei klappte!). Alle durch {$IFDEF WIN64} ersetzt, danach schien XE2 verstanden zu haben, was gemeint ist, denn es flutschte darauhin durch die 64-Bit-Abteilungen. 2. Einige wenige Typumwandlungen von Pointer nach einen Integertyp oder umgekehrt waren noch nötig. Dann war endlich auch das erste 64-Bit-Compilat erzeugt. 3. Programmstart: Der Prozedureinsprungspunkt einer der beiden Funktionen wurde nicht gefunden. Das wundert mich nicht, denn durch den Dependency Walker wußte ich schon, daß in der gewöhnlichen ntdll.dll die Funktionen NtWow64QueryInformationProcess64 und NtWow64ReadVirtualMemory64 gar nicht enthalten sind. Also explizit die ntdll.dll im syswow64-Pfad angegeben. Dann wurden die Funktionen gefunden, weil diese Fehlermeldung entfiel, dafür gab es aber auch wieder gleich zum Programmstart eine andere Fehlermeldung, nämlich daß die Anwendung nicht korrekt gestartet werden kann (inkl. einer Binäradresse). Das gleiche Verhalten hatte ich auch schon mit meinem ursprünglichen Programm, das die Kommandozeile unter 64 Bit abzufragen versuchte. Von PEB unter 64 Bit lasse ich nunmehr definitiv ab und werde mich deshalb nun der WMI-Lösung meiner ursprünglichen Frage zuwenden. Nochmals danke Euch beiden für Eure Hilfsbereitschaft und Geduld mit mir! |
AW: CommandLines der Prozesse unter Windows 64 Bit ermitteln?
Zitat:
Eigentlich sind die Funktionen auch dafür gedacht, dass du aus einem 32-Bit Programm auf die Informationen eines 64-Bit Programms zugreifen kannst. |
AW: CommandLines der Prozesse unter Windows 64 Bit ermitteln?
Das Problem mit den fehlenden Imports kann ich auch nicht nachvollziehen. Habe mal ein bisschen rumgespielt:
Delphi-Quellcode:
Zusätzlich brauchst du folgende Definitionen:
const
{$IFDEF WIN32} OFFSET_PROCESSPARAMETERS = $10; OFFSET_COMMANDLINE = $40; {$ELSE} OFFSET_PROCESSPARAMETERS = $20; OFFSET_COMMANDLINE = $70; {$ENDIF} OFFSET_PROCESSPARAMETERSWOW64 = $20; OFFSET_COMMANDLINEWOW64 = $70; function GetProcessCommandLineFromPEB(hProcess: THandle): String; var Status: NTSTATUS; ReturnLength: UInt64; ProcessInfo: TProcessBasicInformation; ProcessParametersPointer: NativeUInt; CommandLine: TUnicodeString; {$IFDEF WIN32} IsWow64: BOOL; Wow64ProcessInfo: TWow64ProcessBasicInformation64; Wow64CommandLine: TWow64UnicodeString64; Wow64ProcessParametersPointer: UInt64; {$ENDIF} begin Result := 'ERROR'; {$IFDEF WIN32} if (not IsWow64Process(hProcess, IsWow64)) then begin RaiseLastOSError; end; if (not IsWow64) then begin // Query PEB base address Status := NtWow64QueryInformationProcess64(hProcess, ProcessBasicInformation, @Wow64ProcessInfo, SizeOf(Wow64ProcessInfo), @ReturnLength); if ((not NT_SUCCESS(Status)) or (ReturnLength <> SizeOf(Wow64ProcessInfo))) then begin RaiseLastOSError(RtlNtStatusToDosError(Status)); end; // Read the ProcessParameters pointer Status := NtWow64ReadVirtualMemory64(hProcess, Wow64ProcessInfo.PebBaseAddress + OFFSET_PROCESSPARAMETERSWOW64, @Wow64ProcessParametersPointer, SizeOf(Wow64ProcessParametersPointer), @ReturnLength); if ((not NT_SUCCESS(Status)) or (ReturnLength <> SizeOf(Wow64ProcessParametersPointer))) then begin RaiseLastOSError(RtlNtStatusToDosError(Status)); end; // Read the CommandLine UNICODE_STRING Status := NtWow64ReadVirtualMemory64(hProcess, Wow64ProcessParametersPointer + OFFSET_COMMANDLINEWOW64, @Wow64CommandLine, SizeOf(Wow64CommandLine), @ReturnLength); if ((not NT_SUCCESS(Status)) or (ReturnLength <> SizeOf(Wow64CommandLine))) then begin RaiseLastOSError(RtlNtStatusToDosError(Status)); end; // Read the actual commandline SetLength(Result, Wow64CommandLine.Length div SizeOf(Result[1])); Status := NtWow64ReadVirtualMemory64(hProcess, Wow64CommandLine.Buffer, @Result[1], Wow64CommandLine.Length, @ReturnLength); if ((not NT_SUCCESS(Status)) or (ReturnLength <> Wow64CommandLine.Length)) then begin RaiseLastOSError(RtlNtStatusToDosError(Status)); end; Exit; end; {$ENDIF} // Query PEB base address Status := NtQueryInformationProcess(hProcess, ProcessBasicInformation, @ProcessInfo, SizeOf(ProcessInfo), @ReturnLength); if ((not NT_SUCCESS(Status)) or (ReturnLength <> SizeOf(ProcessInfo))) then begin RaiseLastOSError(RtlNtStatusToDosError(Status)); end; // Read the ProcessParameters pointer Status := NtReadVirtualMemory(hProcess, Pointer(NativeUInt(ProcessInfo.PebBaseAddress) + OFFSET_PROCESSPARAMETERS), @ProcessParametersPointer, SizeOf(ProcessParametersPointer), @ReturnLength); if ((not NT_SUCCESS(Status)) or (ReturnLength <> SizeOf(ProcessParametersPointer))) then begin RaiseLastOSError(RtlNtStatusToDosError(Status)); end; // Read the CommandLine UNICODE_STRING Status := NtReadVirtualMemory(hProcess, Pointer(NativeUInt(ProcessParametersPointer) + OFFSET_COMMANDLINE), @CommandLine, SizeOf(CommandLine), @ReturnLength); if ((not NT_SUCCESS(Status)) or (ReturnLength <> SizeOf(CommandLine))) then begin RaiseLastOSError(RtlNtStatusToDosError(Status)); end; // Read the actual commandline SetLength(Result, CommandLine.Length div SizeOf(Result[1])); Status := NtReadVirtualMemory(hProcess, CommandLine.Buffer, @Result[1], CommandLine.Length, @ReturnLength); if ((not NT_SUCCESS(Status)) or (ReturnLength <> CommandLine.Length)) then begin RaiseLastOSError(RtlNtStatusToDosError(Status)); end; end;
Delphi-Quellcode:
Und der Aufruf wäre z.b. so:
type
NTSTATUS = LongInt; HANDLE = THandle; // Set struct alignment and enum size for C compatibility {$IFDEF WIN32} {$A4} {$ELSE} {$A8} {$ENDIF} {$Z4} type TProcessInfoClass = ( ProcessBasicInformation, ProcessQuotaLimits, ProcessIoCounters, ProcessVmCounters, ProcessTimes, ProcessBasePriority, ProcessRaisePriority, ProcessDebugPort, ProcessExceptionPort, ProcessAccessToken, ProcessLdtInformation, ProcessLdtSize, ProcessDefaultHardErrorMode, ProcessIoPortHandlers, ProcessPooledUsageAndLimits, ProcessWorkingSetWatch, ProcessUserModeIOPL, ProcessEnableAlignmentFaultFixup, ProcessPriorityClass, ProcessWx86Information, ProcessHandleCount, ProcessAffinityMask, ProcessPriorityBoost, ProcessDeviceMap, ProcessSessionInformation, ProcessForegroundInformation, ProcessWow64Information, ProcessImageFileName, ProcessLUIDDeviceMapsEnabled, ProcessBreakOnTermination, ProcessDebugObjectHandle, ProcessDebugFlags, ProcessHandleTracing, MaxProcessInfoClass); type TProcessBasicInformation = record ExitStatus: Cardinal; PebBaseAddress: PVOID; AffinityMask: NativeUInt; BasePriority: NativeUInt; UniqueProcessId: NativeUInt; InheritedFromUniqueProcessId: NativeUInt; end; {$IFDEF WIN32} TWow64ProcessBasicInformation64 = record ExitStatus: Cardinal; Pad1: DWord; PebBaseAddress: UInt64; AffinityMask: UInt64; BasePriority: Cardinal; Pad2: DWord; UniqueProcessId: UInt64; InheritedFromUniqueProcessId: UInt64; end; {$ENDIF} TUnicodeString = record Length: USHORT; MaximumLength: USHORT; Buffer: Pointer; end; {$IFDEF WIN32} TWow64UnicodeString64 = record Length: USHORT; MaximumLength: USHORT; Pad1: DWord; Buffer: UInt64; end; {$ENDIF} {$IFDEF WIN32} function NtWow64QueryInformationProcess64(ProcessHandle: HANDLE; ProcessInformationClass: TProcessInfoClass; ProcessInformation: PVOID; ProcessInformationLength: ULONG; ReturnLength: PUInt64): NTSTATUS; stdcall; external 'ntdll.dll'; function NtWow64ReadVirtualMemory64(ProcessHandle: HANDLE; BaseAddress: UInt64; Buffer: Pointer; BufferLength: UInt64; ReturnLength: PUInt64): NTSTATUS; stdcall; external 'ntdll.dll'; {$ENDIF} function NtQueryInformationProcess(ProcessHandle: HANDLE; ProcessInformationClass: TProcessInfoClass; ProcessInformation: PVOID; ProcessInformationLength: ULONG; ReturnLength: PULONG): NTSTATUS; stdcall; external 'ntdll.dll'; function NtReadVirtualMemory(ProcessHandle: HANDLE; BaseAddress : PVOID; Buffer: PVOID; BufferLength: ULONG; ReturnLength: PULONG): NTSTATUS; stdcall; external 'ntdll.dll'; function RtlNtStatusToDosError(Status: NTSTATUS): ULONG; stdcall; external 'ntdll.dll'; function NT_SUCCESS(Status: NTSTATUS): BOOL; begin Result := Status >= 0; end;
Delphi-Quellcode:
procedure TForm2.Button1Click(Sender: TObject);
var hProcess: THandle; begin hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_OPERATION or PROCESS_VM_READ, false, 3000); if (hProcess <> 0) then try MessageBox(0, PChar(GetProcessCommandlineFromPEB(hProcess)), 'Info', MB_ICONINFORMATION); finally CloseHandle(hProcess); end; end; |
AW: CommandLines der Prozesse unter Windows 64 Bit ermitteln?
Hallo,
müssen das nicht packed records sein, oder ist das Alignment in den Records irgendwie geändert worden? Heiko |
AW: CommandLines der Prozesse unter Windows 64 Bit ermitteln?
Zitat:
Hatte damit früher schon einigen Ärger, deshalb bin ich dazu übergegangen immer explizit {$A4/8} anzugeben, wenn ich irgendwelche Structs für die WinAPI deklariere. Selbes Spiel mit den Enums. Delphi interpretiert (weiß nicht, ob das immer noch der Fall ist, aber früher war es so) Enums mit < 256 Elementen immer als Byte, wohingegen die meisten C/C++ Compiler Enums auf 4 Byte erweitern. Deshalb auch hier immer ein explizites {$Z4}. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:48 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz