![]() |
Ermitteln ob ein Programm oder Prozess ein Dienst ist
Hallo zusammen.
Weiß jemand, wie ich herausfinden kann, ob ein Programm (exe?) oder ein Prozess ein Dienst ist. Ich würde gerne einen Prozess bei beenden neu starten, jedoch muss man ja Programme über CreateProcess und Dienste im Systemkonto mit "net start dienstname" starten. Wie kann man diesen Unterschied automatisch ermitteln? |
Re: Ermitteln ob ein Programm oder Prozess ein Dienst ist
du könntest versuchen den Dienst oder das Programm mit NET STOP vorher zu beenden, wenn die Meldung kommt der es kein installierter DIenst ist, ist es ein normales Programm.. kA ob des so funzt.
|
Re: Ermitteln ob ein Programm oder Prozess ein Dienst ist
Herausbekommen kann man das mit Sicherheit garnicht richtig (es gibt nämlich auch EXE-Dateien, die sich als Zwitter verhalten). Es gibt aber gewisse Anhaltspunkte:
1. Ist der Elternprozeß SERVICES.EXE? 2. Läuft der Prozeß als SYSTEM? Es gibt sicher noch mehr. Das Problem ist halt, daß man bei einer Zwitter-EXE es kaum generisch ermitteln kann. |
Re: Ermitteln ob ein Programm oder Prozess ein Dienst ist
Danke, ich werds damit mal versuchen...
|
Re: Ermitteln ob ein Programm oder Prozess ein Dienst ist
Zitat:
|
Re: Ermitteln ob ein Programm oder Prozess ein Dienst ist
Das geht mit den entsprechenden API-Funktionen zum Starten und Stoppen. Anhaltspunkte findest du hier:
![]() |
Re: Ermitteln ob ein Programm oder Prozess ein Dienst ist
Für die Forensuche - Die Lösung:
Hilfsfunktion:
Delphi-Quellcode:
Eigentliche Funktion:
function GetUserAndDomainFromPID(ProcessId: DWORD; var User, Domain: String): Boolean;
{ Hilfsfunktion. Ermittelt zu einer PID den Benutzerkontext und die Domäne } var hToken: THandle; cbBuf: Cardinal; ptiUser: PTOKEN_USER; snu: SID_NAME_USE; ProcessHandle: THandle; UserSize, DomainSize: DWORD; bSuccess: Boolean; begin Result := False; ProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION, False, ProcessId); if ProcessHandle <> 0 then begin if OpenProcessToken(ProcessHandle, TOKEN_QUERY, hToken) then begin bSuccess := GetTokenInformation(hToken, TokenUser, nil, 0, cbBuf); ptiUser := nil; while (Not bSuccess) And (GetLastError = ERROR_INSUFFICIENT_BUFFER) do begin ReallocMem(ptiUser, cbBuf); bSuccess := GetTokenInformation(hToken, TokenUser, ptiUser, cbBuf, cbBuf); end; CloseHandle(hToken); if Not bSuccess then begin Exit; end; UserSize := 0; DomainSize := 0; LookupAccountSid(nil, ptiUser.User.Sid, nil, UserSize, nil, DomainSize, snu); if (UserSize <> 0) And (DomainSize <> 0) then begin SetLength(User, UserSize); SetLength(Domain, DomainSize); if LookupAccountSid(nil, ptiUser.User.Sid, PChar(User), UserSize, PChar(Domain), DomainSize, snu) then begin Result := True; User := StrPas(PChar(User)); Domain := StrPas(PChar(Domain)); end; end; if bSuccess then begin FreeMem(ptiUser); end; end; CloseHandle(ProcessHandle); end; end;
Delphi-Quellcode:
Funktioniert bis jetzt ohne Probleme, bin aber für Diskussion offen :wink:
function IsServiceApp(AppName: String; PID: Integer; var ServiceName: String): Boolean;
{ Überprüft, ob ein Prozess mit der PID ein Dienst ist. Bedingungen: - Benutzerkonto ist das Systemkonto - Service ist in der Registry eingetragen } var User, Domain: String; Reg: TRegistry; List: TStringList; I: Integer; begin Result := False; GetUserAndDomainFromPID(PID, User, Domain); // Ermittelt den Benutzerkontext if User = 'SYSTEM' then begin // Programm läuft im Systemkontext... (könnte ein Dienst sein) Reg := TRegistry.Create; List := TStringList.Create; Reg.RootKey := HKEY_LOCAL_MACHINE; Reg.OpenKeyReadOnly('\SYSTEM\CurrentControlSet\Services\'); // Serviceliste öffnen Reg.GetKeyNames(List); // Alle Untereinträge auflisten for I := 0 to List.Count - 1 do begin Reg.OpenKeyReadOnly('\SYSTEM\CurrentControlSet\Services\' + List[i]); if Reg.ValueExists('ImagePath') // Wenn zugehörige Startdatei angegeben... (sonst kann nicht zugeordnet werden über den Prozessnamen) then begin if LowerCase(ExtractFileNameFromSystemPath(Reg.ReadString('ImagePath'))) = LowerCase(AppName) // Wenn die Dienst-EXE = Prozess-EXE --> Prozess ist ein Dienst then begin Result := True; // Prozess = Dienst ServiceName := List[i]; // Prozessnamen zurückgeben (z.B. "Spooler") Break; // Schleife verlassen end; end; end; List.Free; Reg.Free; end; end; |
Re: Ermitteln ob ein Programm oder Prozess ein Dienst ist
Zitat:
1. Punkt: was passiert, wenn einmal der Service-Schlüssel aaa und einmal zzz, beidemale mit dem gleichen ImagePath existieren? Hat ja niemand gesagt, daß man von einer EXE nur eine Instanz als Service laufen lassen kann. 2. Punkt: ImagePath kann auch Parameter enthalten, nicht nur Pfade. Abgesehen davon kann es mal eine Umgebungsvariable und einmal schon "expandierte" Pfade enthalten. 3. Punkt: ![]() 4. Punkt: Zuguterletzt Stichwort ![]() Anderes ließe sich noch anführen. So richtig kann man es eben doch nicht rausbekommen. Der Prozeßbaum (Suche nach "svchost") wäre noch eine Alternative, aber auch nicht 100% sicher - schließlich kann ein Dienst auch einen "normalen" Prozeß starten. |
Re: Ermitteln ob ein Programm oder Prozess ein Dienst ist
okay, okay. 1:0 für Dich, verdammt gute Argumente :wink: . Aber ich hab einen Vorschlag, es zu ändern:
Zitat:
Zitat:
Zitat:
![]() Zitat:
Zitat:
|
Re: Ermitteln ob ein Programm oder Prozess ein Dienst ist
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:04 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