Autor |
Beitrag |
Radioactive
      
Beiträge: 179
Win 98, Win XP Home SP2
D3 Prof, D7 Pers, D2005 Pers
|
Verfasst: So 31.10.04 14:46
Ich habe ein Programm mit CREATETOOLHLEP32SNAPSHOT und TERMINATEPROCESS geschrieben, dass andere Prozesse killen kann und dass seine Arbeit gut verrichtet. Nun bin ich auf folgendes Problem gestoßen: wenn ich z.B. zwei mal den Editor laufen habe, heißen beide Prozesse "notepad.exe", nur die PID unterscheidet sich.
Das Programm, dass ich abschießen will (ein von mir selbst programmiertes Programm) unterscheidet sich von seinem "gleichnamigen Bruder" nur durch einen Parameter.
 Nun die eigentliche Frage: Gibt es eine Möglichkeit, bei einem laufenden Programm/Prozess auszulesen, mit welchen/welchem Parameter es gestartet wurde?
Es ist z.B. mit dem Process Explorer von Sysinternals möglich, die "Command line" eines Programms/Prozesses in den Properties auszulesen.
Danke schon mal im Voraus,
Radioactive Moderiert von Klabautermann: Topic aus Off Topic verschoben am So 31.10.2004 um 15:42
|
|
Sprint
      
Beiträge: 849
|
Verfasst: So 31.10.04 16:08
Das kannst du mir VIRTUALQUERYEX auslesen.
_________________ Ciao, Sprint.
|
|
uall@ogc
      
Beiträge: 1826
Erhaltene Danke: 11
Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
|
Verfasst: So 31.10.04 18:01
VirtualQuery schaut doch nur nach einem bestimmten speicherbeichnach, welche rechte der hat etc. damit kann man (glaube ich) nicht achschaun mit welchen parameter der preozess gestartet wurde
|
|
Sprint
      
Beiträge: 849
|
Verfasst: Mo 01.11.04 00:30
uall@ogc hat folgendes geschrieben: | VirtualQuery schaut doch nur nach einem bestimmten speicherbeichnach, welche rechte der hat etc. damit kann man (glaube ich) nicht achschaun mit welchen parameter der preozess gestartet wurde |
VirtualQueryEx in Verbindung mit ReadProcessMemory. Bei Adresse $00020498 sollte der Environment Block anfangen und danach kommen diese geheimnisvollen Informationen die der Fragesteller haben möchte.
_________________ Ciao, Sprint.
|
|
uall@ogc
      
Beiträge: 1826
Erhaltene Danke: 11
Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
|
Verfasst: Mo 01.11.04 14:24
trotzdem kann man mit VirtualQuery das net auslesen, mit ReadProcessmemory schon eher
VirtualQuery schaut nur nach ob der speicher da ist
ausserdem sollte man nen VirtualProectEx noch drüber laufen lassen (oder net ;P)
|
|
Radioactive 
      
Beiträge: 179
Win 98, Win XP Home SP2
D3 Prof, D7 Pers, D2005 Pers
|
Verfasst: Mi 03.11.04 19:41
Titel: hää?
Danke, aber ich ich kapier nicht wirklich viel.
Könntet ihr nicht mal ein anschauliches beispiel posten (z.b. eine funktion, in die man die PID einsetzt und die dann die Command line zurückgibt)?
Was ist VirtualQueryEx? Und ReadProcessMemory? Wie benutzt man das?
|
|
Sprint
      
Beiträge: 849
|
Verfasst: Mi 03.11.04 20:27
Bei jedem erstellten Win32 Prozess wird an der Adresse $20000 eine Datenstruktur gespeichert, die in Visual C++ so aufgebaut ist...
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31:
| typedef struct _RTL_USER_PROCESS_PARAMETERS RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS; |
Meine Erfahrungen haben gezeigt, das das Auslesen nur bedingt mit Delphi möglich ist (WideString/WideChar). Mit den Funktionen wcsncpy, wcslen & Co. aus der MSVCRT.DLL klappt es schon besser.
_________________ Ciao, Sprint.
|
|
Sprint
      
Beiträge: 849
|
Verfasst: Mi 03.11.04 20:30
@Admins & Mods: Darf ich meine eigenen Beiträge nicht mehr editieren?
Quelltext 1: 2: 3: 4: 5: 6:
| typedef struct _RTL_DRIVE_LETTER_CURDIR { USHORT Flags; USHORT Length; ULONG TimeStamp; UNICODE_STRING DosPath; } RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR; |
_________________ Ciao, Sprint.
|
|
.Chef
      
Beiträge: 1112
|
Verfasst: Mi 03.11.04 20:31
Sprint hat folgendes geschrieben: | @Admins & Mods: Darf ich meine eigenen Beiträge nicht mehr editieren? |
Ist im Moment deaktiviert (hab ich vorhin irgendwo gelesen) ...
_________________ Die Antworten auf die 5 häufigsten Fragen:
1. Copy(), Pos(), Length() --- 2. DoubleBuffered:=True; --- 3. Application.ProcessMessages bzw. TThread --- 4. ShellExecute() --- 5. Keine Vergleiche von Real-Typen mit "="!
|
|
Sprint
      
Beiträge: 849
|
Verfasst: Mi 03.11.04 20:36
.Chef hat folgendes geschrieben: | Ist im Moment deaktiviert (hab ich vorhin irgendwo gelesen) ... |
Okay. Danke.
_________________ Ciao, Sprint.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mi 03.11.04 20:39
Welche Länge sind denn die WideChar-Strings? Oder sind die als PWChar realisiert und nehmen ein DWORD ein?
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Sprint
      
Beiträge: 849
|
Verfasst: Do 04.11.04 04:14
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40:
| function GetProcessCmdLine(ProcessId: DWORD): String; var ProcessHandle: THandle; MBI: TMemoryBasicInformation; Buffer: Pointer; SystemInfo: TSystemInfo; Size: DWORD; BytesRead: DWORD; Position: PByte; begin
FillChar(SystemInfo, SizeOf(TSystemInfo), 0); GetSystemInfo(SystemInfo); GetMem(Buffer, SystemInfo.dwPageSize); try ProcessHandle := OpenProcess(PROCESS_VM_READ or PROCESS_QUERY_INFORMATION, False, ProcessId); if ProcessHandle <> 0 then begin Size := SizeOf(TMemoryBasicInformation); FillChar(MBI, Size, 0); if VirtualQueryEx(ProcessHandle, Pointer($00020000), MBI, Size) = Size then begin if ReadProcessMemory(ProcessHandle, MBI.BaseAddress, Buffer, SystemInfo.dwPageSize, BytesRead) then begin Position := Buffer; Inc(Position, $498); Inc(Position, (Length(PWideChar(Position)) + 2) * SizeOf(WideChar)); Inc(Position, (Length(PWideChar(Position)) + 2) * SizeOf(WideChar)); Result := PWideChar(Position); end else RaiseLastOSError; end else RaiseLastOSError; end else RaiseLastOSError; finally FreeMem(Buffer); end;
end; |
In Zeile 27 und 28 kann es ein Problem geben. Komischerweise sind die Strings manchmal mit einem Byte getrennt.
Richtig wäre aber ja zwei Bytes. Wenn es ein nullterminieter WideString ist, dann müsste ein Zeichen gleich zwei Bytes sein.
Irgendwie haut das aber nicht bei jedem Programm hin.
_________________ Ciao, Sprint.
|
|
Radioactive 
      
Beiträge: 179
Win 98, Win XP Home SP2
D3 Prof, D7 Pers, D2005 Pers
|
Verfasst: Fr 05.11.04 17:43
Titel: Danke!
Erst mal Danke! Ein guter Quelltext!
Bei mir gibt es keine Probleme, nur ein paar Systemprozessen (z.B.: smss.exe) tritt ein Error auf. Wenn ich den Quelltext so wie beschrieben übernehme, werden die Commandline der meisten Prozesse angezeigt. Bei manchen fehlt jedoch z.B. das erste Anführungszeichen, (")
am Schluss steht jedoch eines. Auch kann ich die CmdLine von winlogon.exe nur korrekt auslesen, wenn ich den Quelltext wie folgt ändere oder bei anderen Prozessen anders ändere (Zeile 27/2  :
Quelltext 1: 2:
| Inc(Position, (Length(PWideChar(Position)) + 1) * SizeOf(WideChar)); Inc(Position, (Length(PWideChar(Position)) + 5) * SizeOf(WideChar)); |
Dann kann ich aber andere CmdLines nicht mehr ansehen. Bei vielen wird auch gar nichts angezeigt. Es ist auch so, dass ich eine CmdLine mal nicht anzeigen kann, wenn ich aber mein Testprogramm neu starte, geht es doch.
Vielleicht liegt das aber auch an Delphi und es geht mit anderen Sprachen besser. Trotzdem, vielen Dank!
Wer Ideen hat, soll sich melden!
Radioactive
|
|
toms
      
Beiträge: 1099
Erhaltene Danke: 2
|
Verfasst: Fr 05.11.04 22:36
Zitat: | Vielleicht liegt das aber auch an Delphi und es geht mit anderen Sprachen besser. |
Hi,
Das liegt ganz sicher nicht an Delphi sondern an der Funktion.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Sa 06.11.04 01:04
Ich hab mal mit einem RAM-Editor das Problem erforscht: Setzt mal Position auf das DWord an der Position $00020044. Dann braucht ihr zum einen die weiteren Inc-Befehle nicht und zum anderen erhaltet ihr damit sofort und zuverlässig die richtigen Informationen.
Achso: Einige Prozesse können nicht ausgelesen werden, da sie vom System gestartet werden. Um sie dennoch auslesen zu können, muss mn Admin sein und über gewisse Exployts Erbe des System-Prozesses werden. Danach sollte auch dies kein Problem mehr sein. Allerdings sei hier davon abgeraten, da eure Anwendung ansonsten mit großer Wahrscheinlichkeit früher oder später von Virenscannern eliminiert wird.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Sprint
      
Beiträge: 849
|
Verfasst: Fr 03.12.04 09:12
Hab mein Beispiel nochmal überarbeitet und sollte jetzt fehlerfrei laufen.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41:
| function GetProcessCmdLine(ProcessId: DWORD): String; var ProcessHandle: THandle; MBI: TMemoryBasicInformation; Buffer: Pointer; SystemInfo: TSystemInfo; Size: DWORD; CmdLine: WideString; LengthCmdLine: Word; PosCmdLine: Pointer; begin
Result := ''; FillChar(SystemInfo, SizeOf(TSystemInfo), 0); GetSystemInfo(SystemInfo); GetMem(Buffer, SystemInfo.dwPageSize); try ProcessHandle := OpenProcess(PROCESS_VM_READ or PROCESS_QUERY_INFORMATION, False, ProcessId); if ProcessHandle <> 0 then begin Size := SizeOf(TMemoryBasicInformation); FillChar(MBI, Size, 0); if VirtualQueryEx(ProcessHandle, Pointer($00020000), MBI, Size) = Size then if ReadProcessMemory(ProcessHandle, MBI.BaseAddress, Buffer, SystemInfo.dwPageSize, DWORD(nil^)) then begin LengthCmdLine := PWord(Longint(Buffer) + $42)^; if LengthCmdLine < (MAX_PATH * 2) then begin SetLength(CmdLine, LengthCmdLine); PosCmdLine := Pointer(PLongint(Longint(Buffer) + $44)^); if ReadProcessMemory(ProcessHandle, PosCmdLine, PWideChar(CmdLine), LengthCmdLine, DWORD(nil^)) then Result := Trim(Copy(CmdLine, 1, Pos(#0, CmdLine) - 1)); end; end; CloseHandle(ProcessHandle); end; finally FreeMem(Buffer); end;
end; |
_________________ Ciao, Sprint.
|
|
no1likeyou
Hält's aus hier
Beiträge: 2
|
Verfasst: Di 07.08.07 11:45
Titel: 64 Bit CommandLine
Bei 32Bit Prozessen funktioniert das gut aber leider nicht bei Prozessen die mit 64bit compiliert wurden.
Liegt das vielleicht an der Speicheradresse von VirtualQueryEx?
>> if VirtualQueryEx(ProcessHandle, Pointer($00020000), MBI, Size) = Size then
Wenn ja wie könnte man die je nach Prozess-Typ verbiegen?
Oder gibt es mittlerweile eine elegantere Lösung um an die CommandLine eines Prozesses zu gelangen?
|
|
|