AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Ermitteln ob ein Programm oder Prozess ein Dienst ist
Thema durchsuchen
Ansicht
Themen-Optionen

Ermitteln ob ein Programm oder Prozess ein Dienst ist

Ein Thema von Codewalker · begonnen am 22. Mai 2006 · letzter Beitrag vom 16. Aug 2006
Antwort Antwort
Seite 1 von 3  1 23      
Benutzerbild von Codewalker
Codewalker

Registriert seit: 18. Nov 2005
Ort: Ratingen
945 Beiträge
 
Delphi XE2 Professional
 
#1

Ermitteln ob ein Programm oder Prozess ein Dienst ist

  Alt 22. Mai 2006, 14:03
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?
Thomas
  Mit Zitat antworten Zitat
Angel4585

Registriert seit: 4. Okt 2005
Ort: i.d.N.v. Freiburg im Breisgau
2.199 Beiträge
 
Delphi 2010 Professional
 
#2

Re: Ermitteln ob ein Programm oder Prozess ein Dienst ist

  Alt 22. Mai 2006, 14:21
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.
Martin Weber
Ich bin ein Rüsselmops
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#3

Re: Ermitteln ob ein Programm oder Prozess ein Dienst ist

  Alt 22. Mai 2006, 14:31
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.
  Mit Zitat antworten Zitat
Benutzerbild von Codewalker
Codewalker

Registriert seit: 18. Nov 2005
Ort: Ratingen
945 Beiträge
 
Delphi XE2 Professional
 
#4

Re: Ermitteln ob ein Programm oder Prozess ein Dienst ist

  Alt 22. Mai 2006, 15:52
Danke, ich werds damit mal versuchen...
Thomas
  Mit Zitat antworten Zitat
Benutzerbild von Codewalker
Codewalker

Registriert seit: 18. Nov 2005
Ort: Ratingen
945 Beiträge
 
Delphi XE2 Professional
 
#5

Re: Ermitteln ob ein Programm oder Prozess ein Dienst ist

  Alt 26. Mai 2006, 16:35
Zitat von Angel4585:
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
Soweit so gut, ich habs mit dem Systemkonto, etc. versucht. Jetzt würde ich für den Zweifelsfall noch gern die Überprüfung mit NET STOP einbauen. Das sollte aber innerhalb meines Programms erfolgen, ohne dass dabei das Konsolenfenster geöffnet wird. Ist das möglich und wenn ja, wir kann ich das Ergebnis von NET STOP abfangen?
Thomas
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#6

Re: Ermitteln ob ein Programm oder Prozess ein Dienst ist

  Alt 26. Mai 2006, 16:59
Das geht mit den entsprechenden API-Funktionen zum Starten und Stoppen. Anhaltspunkte findest du hier:
http://assarbad.info/en/stuff/tutorials/ntsvc/
  Mit Zitat antworten Zitat
Benutzerbild von Codewalker
Codewalker

Registriert seit: 18. Nov 2005
Ort: Ratingen
945 Beiträge
 
Delphi XE2 Professional
 
#7

Re: Ermitteln ob ein Programm oder Prozess ein Dienst ist

  Alt 13. Aug 2006, 19:07
Für die Forensuche - Die Lösung:

Hilfsfunktion:
Delphi-Quellcode:
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;
Eigentliche Funktion:

Delphi-Quellcode:
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 = 'SYSTEMthen
  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;
Funktioniert bis jetzt ohne Probleme, bin aber für Diskussion offen
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#8

Re: Ermitteln ob ein Programm oder Prozess ein Dienst ist

  Alt 13. Aug 2006, 19:57
Zitat von Codewalker:
Funktioniert bis jetzt ohne Probleme, bin aber für Diskussion offen
<homermäßig>Naaaain </homermäßig>

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: Warum sollte ein normales Programm nicht auch als SYSTEM laufen können?
4. Punkt: Zuguterletzt Stichwort MSDN-Library durchsuchenImpersonation

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.
  Mit Zitat antworten Zitat
Benutzerbild von Codewalker
Codewalker

Registriert seit: 18. Nov 2005
Ort: Ratingen
945 Beiträge
 
Delphi XE2 Professional
 
#9

Re: Ermitteln ob ein Programm oder Prozess ein Dienst ist

  Alt 14. Aug 2006, 13:31
okay, okay. 1:0 für Dich, verdammt gute Argumente . Aber ich hab einen Vorschlag, es zu ändern:

Zitat von Olli:
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.
Okay, aber für die reine Erkennung, ob es ein Dienst ist, tut es da ja auch. Dann kann ich halt nur nicht mit Sicherheit den Dienstnamen ermitteln. Dn könnte man ja in solchen Zweifelsfällen auf einen leeren String setzen bzw. als StringList beide Werte zurückgeben. Außerdem darf die Schleife dann bei einem Fund nicht automatisch abgebrochen werden.

Zitat von Olli:
2. Punkt: ImagePath kann auch Parameter enthalten, nicht nur Pfade. Abgesehen davon kann es mal eine Umgebungsvariable und einmal schon "expandierte" Pfade enthalten.
Okay, das lässt sich aber auch noch machen. ExtractFileNameFromSystemPath habe ich selbst geschrieben um Pfad wie %systemdir% und ähnliche aufzulösen. Kann ich bei Gelegenheit gerne posten (hab ich grad nicht zur Hand).

Das könnte man über die Module ermitteln. Bei einem normalen Programm ist das Modul 0 immer das Programm selber. Bei einem Dienst dürfte das doch dann nicht der Fall sein. Siehe auch hier Link am Ende des ersten Posts

Zitat von Olli:
4. Punkt: Zuguterletzt Stichwort MSDN-Library durchsuchenImpersonation
Was meinst du damit?

Zitat von Olli:
Der Prozeßbaum (Suche nach "svchost") wäre noch eine Alternative, aber auch nicht 100% sicher
Und das sagt mir auch nicht viel....
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#10

Re: Ermitteln ob ein Programm oder Prozess ein Dienst ist

  Alt 14. Aug 2006, 13:53
Zitat von Codewalker:
Okay, aber für die reine Erkennung, ob es ein Dienst ist, tut es da ja auch. Dann kann ich halt nur nicht mit Sicherheit den Dienstnamen ermitteln. Dn könnte man ja in solchen Zweifelsfällen auf einen leeren String setzen bzw. als StringList beide Werte zurückgeben. Außerdem darf die Schleife dann bei einem Fund nicht automatisch abgebrochen werden.
Sicher.

Zitat von Codewalker:
Okay, das lässt sich aber auch noch machen. ExtractFileNameFromSystemPath habe ich selbst geschrieben um Pfad wie %systemdir% und ähnliche aufzulösen. Kann ich bei Gelegenheit gerne posten (hab ich grad nicht zur Hand).
Hmm.

Zitat von Codewalker:
Das könnte man über die Module ermitteln. Bei einem normalen Programm ist das Modul 0 immer das Programm selber. Bei einem Dienst dürfte das doch dann nicht der Fall sein. Siehe auch hier Link am Ende des ersten Posts
Das müßtest du mir nochmal erklären, wenn es geht.

Zitat von Codewalker:
Was meinst du damit?
Ein Thread innerhalb eines Dienstes muß nicht als SYSTEM laufen, auch wenn der Dienst als SYSTEM gestartet wurde. Ergo kann das Token falsch sein, oder schlimmer, du kannst möglicherweise garnicht die Rechte haben um auf Ressourcen zuzugreifen, die du im obigen Code ansprichst.

Zitat von Codewalker:
Und das sagt mir auch nicht viel....
Daß einige Prozesse einen Elternprozeß haben ist dir klar? Für Dienste gibt es normalerweise einen einzigen Elternprozeß (services.exe) unter dem dann andere laufen (svchost.exe für DLL-Services usw.).
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


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 18:26 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