![]() |
CommandLines der Prozesse unter Windows 64 Bit ermitteln?
Hallo Delphifreunde!
Kennt Ihr eine einfache und stabile Möglichkeit, die CommandLines aller (oder zumindest der meisten) Prozesse anhand deren Prozeß-IDs unter 64 Bit zu ermitteln? Debugrechte sind natürlich vorausgesetzt und erfolgreich angefordert, zumal das Compilat natürlich auch 64 Bit hat (mit XE2 erstellt). Ich fand im Internet zwei recht ähnliche Delphi-Lösungen, die beide auf der kombinierten Anwendung der NTQueryProcessInformation- und ReadProcessMemory-Funktion beruhen und unter Windows 32 Bit wie gewünscht funktionieren (Abrufen der Process Basic Information). Unter Windows 7 64 Bit funktionert es jedoch nicht, nicht mal mit dem eigenen Prozeß (Prozeß-ID des eigenen Programmes). Zwar konnte ich mich ein wenig vorarbeiten (Integerwerte auf 64 Bit erweitert), doch bis zum erfolgreichen Ermitteln der Kommandozeile reicht es nie, an irgendeinem der wiederholten ReadProcessMemory-Aufrufe scheitert es regelmäßig. Natürlich lasse ich mir GetLastError ausgeben, doch für mehr als dem "Aufbohren" der Bitanzahl der Integerwerte reichten die Meldungen mir nicht. Ehe ich hier beide Zwischenergebnisse ausgieße, einfach die Fragen: 1. Ist das Ermitteln der Kommandozeilen unter Windows 64 Bit überhaupt möglich, insbesondere mit den genannten API-Funktionen? 2. Gibt es ggf. eine recht simple Variante zur Ermittlung der jeweiligen Kommandozeile, die stabil und bitanzahlunabhängig funktioniert? Ich vermute, daß der Process Environment Block (PEB) unter 64 Bit grundsätzlich anders gestaltet ist (s. ![]() Vielen Dank im voraus für Eure Aufmerksamkeit! Delphi-Laie |
AW: CommandLines der Prozesse unter Windows 64 Bit ermitteln?
Du kannst einfach die Spalte CommandLine aus der WMI Klasse Win32_Process nutzen:
![]() Anders machen das andere Tools auch meistens nicht. |
AW: CommandLines der Prozesse unter Windows 64 Bit ermitteln?
Hallo Sebastian, besten Dank für Deine Antwort!
WMI erfordert, soweit ich mich schlaugelesen habe, auf NTx das Laufen des Windows-Verwaltungsinstrumentations-Dienstes (WinMgmt.exe). Daher sympathisiere ich nicht so sehr mit dieser Lösung. Für alle, die es interessiert, hier die beiden Funktionen, die als 32-Bit-Compilate für 32-Bit-Prozesse funktionieren (die Integervariablen müssen dann auf 32 Bit reduziert werden). Bei 64 Bit scheitert es immer an irgendeinem der wiederholten ReadProcessMemory-Aufrufe.
Delphi-Quellcode:
implementation NtQueryInformationProcess:function(ProcessHandle:THandle;ProcessInformationClass:UInt64{DWORD};ProcessInformation:Pointer;ProcessInformationLength:ULONG;ReturnLength:PULONG):LongInt;stdcall=nil; type UNICODESTRING=record Length,MaximumLength:UInt64;//Word; Buffer:PWideChar; end; type PROCESS_BASIC_INFORMATION=packed record ExitStatus:{U}Int64;//DWORD; PebBaseAddress:Pointer; AffinityMask,BasePriority,UniqueProcessId,InheritedUniquePID:{U}Int64;//DWORD; end; function getcommandline1(PID:dword):string; label 0; var PBI:PROCESS_BASIC_INFORMATION; CommandLine:UNICODESTRING; lib:THandle; ReturnLength:NativeUInt;//Cardinal; begin hProcess:=OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,false,pe.th32ProcessID); if hProcess<>invalid_handle_value then begin lib:=Loadlibrary('ntdll.dll'); if lib<>0 then begin NtQueryInformationProcess:=GetProcAddress(lib,'NtQueryInformationProcess'); if (NtQueryInformationProcess(hProcess,0{=>ProcessBasicInformation},@PBI,sizeof(PBI),@ReturnLength)=0{STATUS_SUCCESS}) {and (ReturnLength=SizeOf(PBI))} then begin if not ReadProcessMemory(hProcess,Pointer({U}Int64(PBI.PEBBaseAddress)+OffsetProcessParametersx32),@rtlUserProcAddress,sizeof(Pointer),ReturnLength) then begin result:='1. '+SysErrorMessage(GetLastError); goto 0 end; if not ReadProcessMemory(hProcess,Pointer({U}Int64(rtlUserProcAddress)+OffsetCommandLinex32),@CommandLine,sizeof(CommandLine),ReturnLength) then begin result:='2. '+SysErrorMessage(GetLastError); goto 0 end; SetLength(CommandLineContents,CommandLine.length); if not ReadProcessMemory(hProcess,CommandLine.Buffer,@CommandLineContents[1],CommandLine.Length,ReturnLength) then begin result:='3. '+SysErrorMessage(GetLastError); goto 0 end; result:=WideCharLenToString(PWideChar(CommandLineContents),CommandLine.length div 2); end else result:='NTQueryInformationProcess gescheitert: '+SysErrorMessage(GetLastError); 0:Freelibrary(lib) end; CloseHandle(hProcess) end end; function getcommandline2(PID:dword):string; label 0; var ProcessHandle:THandle; rtlUserProcAddress,PMBAddress:Pointer; command_line:UnicodeString; command_line_contents:WideString; ReturnLength:NativeUInt;//Cardinal; function GetPEBAddress(inhandle:THandle):pointer; var pbi:PROCESS_BASIC_INFORMATION; MyHandle:THandle; myFunc:procedure(ProcessHandle:THandle; ProcessInformationClass:DWord; ProcessInformation:Pointer; ProcessInformationLength:DWord; ReturnLength:Pointer);stdcall; begin MyHandle:=LoadLibrary('NTDLL.DLL'); if MyHandle<>0 then begin myfunc:=GetProcAddress(myHandle,'NtQueryInformationProcess'); if @myfunc<>nil then MyFunc(inhandle,0{=>ProcessBasicInformation},@pbi,sizeof(pbi),nil); FreeLibrary(Myhandle) end; Result:=pbi.PEBBaseAddress end; begin ProcessHandle:=OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,false,PID); if ProcessHandle<>invalid_handle_value then begin PMBAddress:=GetPEBAddress(ProcessHandle); if not ReadProcessMemory(ProcessHandle,Pointer(int64(PMBAddress)+OffsetProcessParametersx32),@rtlUserProcAddress,sizeof(Pointer),ReturnLength) then begin result:='1. '+SysErrorMessage(GetLastError); goto 0 end; if not ReadProcessMemory(ProcessHandle,Pointer(Longint(rtlUserProcAddress)+OffsetCommandLinex32),@command_line,sizeof(command_line),ReturnLength) then begin result:='2. '+SysErrorMessage(GetLastError); goto 0 end; SetLength(Command_Line_Contents,command_line.length);ReadProcessMemory(ProcessHandle,command_Line.Buffer,@command_Line_contents[1],command_line.length,ReturnLength); Result:=WideCharLenToString(PWideChar(command_Line_Contents),command_line.length div 2); 0:CloseHandle(ProcessHandle) end else result:='Kein gültiges Prozeßhandle '+SysErrorMessage(GetLastError); end; |
AW: CommandLines der Prozesse unter Windows 64 Bit ermitteln?
Zitat:
|
AW: CommandLines der Prozesse unter Windows 64 Bit ermitteln?
Zitat:
WMI ist ein Grundbestandteil von Windows, ohne läuft nicht einmal die Windows Firewall... |
AW: CommandLines der Prozesse unter Windows 64 Bit ermitteln?
Das Anfordern maximaler Privilegien, das ich schrieb, setzt natürlich Administrationsrechte voraus, das ist mir klar.
Ich bin jetzt auch inzwischen soweit (also breitgeschlagen), daß ich mich mit WMI näher und mich mit den beiden o.g. auf 64 Bit "aufgebohrten" Funktionen nicht mehr beschäftigen werde. Nochmals danke für diesen Anstoß! Unter Windows 2000 und XP ist der Instrumentationsdienst für mich ein Fremdkörper und gehört zu denen, die ich deaktiviere, und fahre damit immer recht gut (der Router "firewallt" ja ohnehin). Bei neueren Windows, und mir geht es ja um 64 Bit, ließ ich ihn bisher in Ruhe, wird ja dann auch in die svchost.exe verpackt. |
AW: CommandLines der Prozesse unter Windows 64 Bit ermitteln?
Ursache des Problems ist folgende:
Zitat:
|
AW: CommandLines der Prozesse unter Windows 64 Bit ermitteln?
Ich staune immer wieder, was manche Genies im Internet aufzustöbern imstande sind.
Vielen Dank, Zacherl! |
AW: CommandLines der Prozesse unter Windows 64 Bit ermitteln?
Zitat:
![]() |
AW: CommandLines der Prozesse unter Windows 64 Bit ermitteln?
Hallo Zacherl, nur allein das Nachvollziehen das von Dir verlinkten Beispielprogrammes ist ein nachmittagsfüllendes Programm, das leider bisher im Versuch steckenblieb. Es scheitert an den Units, die für das Programm benötigt werden. Bis zur NcxTypes.pas konnte ich alle Units besorgen (JEDI bzw. letztere, die NcxTypes von Luckies Internetseite). Die beiden Units NcxNtDef.pas und NcxNtTeb.pas konnte ich nicht auftreiben.
Darf ich Dich deshalb fragen, ob Du das Beispielprogramm selbst einmal zum Laufen brachtest, und, falls ja, woher Du die beiden letztgenannten Units bezogst? Danke und Gruß Delphi-Laie |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:17 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