AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Benachrichtigung wenn Prozess gestartet wurde

Benachrichtigung wenn Prozess gestartet wurde

Ein Thema von diabox · begonnen am 2. Jun 2012 · letzter Beitrag vom 15. Jul 2012
Antwort Antwort
Seite 1 von 2  1 2   
Benutzerbild von diabox
diabox

Registriert seit: 13. Sep 2006
61 Beiträge
 
Delphi 2010 Professional
 
#1

Benachrichtigung wenn Prozess gestartet wurde

  Alt 2. Jun 2012, 15:32
Hallo,

ich grübele jetzt seit einiger Zeit daran, wie mein Programm benachrichtigt werden kann, wenn ein bestimmter Prozess (mit Fenster) gestartet wurde.
Dabei sind mir bisher folgende Lösungen unter gekommen:

Überwachung nach EXE:
  • wiederholtes Prüfen, ob sich der Prozess in der Liste aktiver Prozesse befindet:
    CreateToolhelp32Snapshot alle X Sekunden aufrufen und nach szExeFile prüfen.
    Fazit: Doch recht hohe CPU-Last.
  • Beanspruchung der WMI "EventWatching", "Win32_ProcessStartTrace":
    Mit der WMI bin ich ehrlich gesagt noch etwas überfordert und das ist vielleicht auch etwas überdimensioniert.
    Fazit: Neuland

Überwachung nach Fenster:
  • wiederholtes Prüfen, ob sich ein bekannter Fenstername in der Liste der Fenster befindet:
    EnumWindows alle X Sekunden aufrufen und mit GetWindowTitle den Fenstertitel prüfen.
    Fazit: Zwar geringere CPU-Last, aber bestimmt nicht ideal.
  • Benachrichtigung beim "Auftauchen" eines Fenster (SetWinEventHook/SetWindowsHookEx):
    Mit SetWinEventHook habe ich noch nicht gearbeitet, aber das scheint ähnlich wie SetWindowsHookEx zu arbeiten:
    Callback in jedem neuen Prozess der prüft, ob es sich um Prozess X handelt. (Leider wird die Callback-Funktion auch bei anderen Events ausgeführt)
    Fazit: Jeden Prozess mit der Prüfung "belästigen" scheint mir auch nicht ideal.
  • Benachrichtigung beim Erstellen eines Prozess mit Fenster mit eigenem Hook (Registry: AppInit_DLLs):
    Fazit: Wieder sind viele zu Prozesse betroffen.


Das wären so die Ideen, die ich habe. Fällt euch noch etwas anderes ein?

Danke und schönes Wochenende!
Wer zweifelt, detoniert nicht!'
Dieter Nuhr
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 15. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#2

AW: Benachrichtigung wenn Prozess gestartet wurde

  Alt 2. Jun 2012, 16:31
Du könntest einen Image Hijack versuchen.
Wenn irgendjemand den Prozess starten möchte wird in Wirklichkeit der Prozess gestartet, den du angegeben hast.
http://blogs.mcafee.com/mcafee-labs/...cution-options
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#3

AW: Benachrichtigung wenn Prozess gestartet wurde

  Alt 2. Jun 2012, 16:59
Überwachung nach EXE:
  • wiederholtes Prüfen, ob sich der Prozess in der Liste aktiver Prozesse befindet:
    CreateToolhelp32Snapshot alle X Sekunden aufrufen und nach szExeFile prüfen.
    Fazit: Doch recht hohe CPU-Last.
Hohe CPU-Last? Dann mache ich etwas anders als du. Ich habe ein Programm, das Prozessen Affinitäten/Zugehörigkeiten zu CPUs/Kernen zuordnen kann. Um zu prüfen, ob ein vorgegebener Prozess läuft, nutze ich ebenfalls CreateToolhelp32Snapshot. Momentaner Stand: 2 Monate Laufzeit des Systems (ca. 12-14 Stunden pro Tag), abgelaufene CPU-Zeit meines Prozesses (bei einem Prüfintervall von 2 Sekunden): ~50 Minuten. Ich denke, das lässt sich verkraften.

MfG Dalai
  Mit Zitat antworten Zitat
Benutzerbild von diabox
diabox

Registriert seit: 13. Sep 2006
61 Beiträge
 
Delphi 2010 Professional
 
#4

AW: Benachrichtigung wenn Prozess gestartet wurde

  Alt 2. Jun 2012, 17:50
Du könntest einen Image Hijack versuchen.
Danke! Das klingt wirklich sehr interessant. Scheint so ziemlich das zu sein wonach ich gesucht habe (Auch wenn der Bezug zu Malware betrübt ). Gibt es sowas auch für verwendete DLLs?

Hohe CPU-Last? Dann mache ich etwas anders als du.
Stimmt schon, Dalai. Hohe CPU-Last ist wirklich übertrieben. Aber es kommt mir falsch vor, dass einem Prozess, der eigentlich nichts tut außer auf einen anderen Prozess zu warten, dauerhaft Rechenzeit zugeteilt werden muss. Ein Event o.ä. wäre mir da lieber als ein dauerhaftes Polling. Aber interessant zu hören, dass eine solche Lösung im Einsatz ist, dann werde ich das vielleicht doch in Erwägung ziehen. Stoppst du, wenn Process32Next den richtigen Prozess gefunden hat oder ist es für dein Programm wichtig alle Einträge zu durchlaufen?
Wer zweifelt, detoniert nicht!'
Dieter Nuhr
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#5

AW: Benachrichtigung wenn Prozess gestartet wurde

  Alt 2. Jun 2012, 18:22
Aber es kommt mir falsch vor, dass einem Prozess, der eigentlich nichts tut außer auf einen anderen Prozess zu warten, dauerhaft Rechenzeit zugeteilt werden muss.
OK, dabei stimmen wir überein .

Zitat:
Ein Event o.ä. wäre mir da lieber als ein dauerhaftes Polling.
In der Tat. Allerdings wüsste ich momentan nicht, wie man das anstellen sollte. Das heißt aber nicht wirklich etwas, denn ich habe in der Richtung viel zu wenig Ahnung.

Zitat:
Stoppst du, wenn Process32Next den richtigen Prozess gefunden hat oder ist es für dein Programm wichtig alle Einträge zu durchlaufen?
Hier mal die relevante Funktion (abgespeckt):
Delphi-Quellcode:
var
   hProcSnapshot : THandle;
   ProcInfo : TProcessEntry32;
   ProzessHandle : HWND;
   dummy : DWORD;
begin
    hProcSnapshot:= CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0);
    if hProcSnapshot = INVALID_HANDLE_VALUE then Exit;
    ProcInfo.dwSize:= SizeOf(TProcessEntry32);
    if not Process32First(hProcSnapshot, ProcInfo) then Exit;
    repeat
        // Filter für bestimmte Prozesse. Wenn Filter leer, dann alle Prozesse
        if (LowerCase(ProcInfo.szExeFile) = proz) OR (proz = '') then
        begin
            if (LowerCase(ProcInfo.szExeFile) <> 'system') then
            begin
                ProzessHandle:= OpenProcess(PROCESS_QUERY_INFORMATION or
                                 PROCESS_VM_READ, false, ProcInfo.th32ProcessID);
                if (ProzessHandle <> 0) then
                begin
                    // hier Hauptaufgabe
                end;
                CloseHandle(ProzessHandle);
            end;
        end;
    until (not Process32Next(hProcSnapshot, ProcInfo));
    CloseHandle(hProcSnapshot);
end;
Die Funktion stellt dabei erstmal eine Liste der aktiven Prozesse zusammen und sammelt Infos über sie (PID, Name, Affinität, Priorität). Diese Liste wird dann im Anschluss verarbeitet (also nochmals durchlaufen) und mit der im Programm vordefinierten Liste der Prozesse verglichen und angewendet (Zugehörigkeit und Priorität zugewiesen).

Beim Durchschauen des Codes ist mir aufgefallen, dass in diesem Teil überhaupt keine Fehlerbehandlung und auch keine Überlaufprüfung vorhanden ist, eieiei. Naja, ich wollte das Programm eh komplett überarbeiten (aber erst, wenn ich Zeit habe).

MfG Dalai
  Mit Zitat antworten Zitat
Benutzerbild von diabox
diabox

Registriert seit: 13. Sep 2006
61 Beiträge
 
Delphi 2010 Professional
 
#6

AW: Benachrichtigung wenn Prozess gestartet wurde

  Alt 2. Jun 2012, 18:30
So ähnlich sieht das bei mir auch aus:

Delphi-Quellcode:
function IsProcessRunning(const FileName: string): Cardinal;
var
  hSnapshot : Cardinal;
  EntryParentProc: TProcessEntry32;
begin
  Result := 0;
  hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if hSnapshot = INVALID_HANDLE_VALUE then
    exit;
  try
    EntryParentProc.dwSize := SizeOf(EntryParentProc);
    if Process32First(hSnapshot, EntryParentProc) then
      repeat
        if FileName = EntryParentProc.szExeFile then
          begin
            Result := EntryParentProc.th32ProcessID;
            break;
          end;
      until not Process32Next(hSnapshot, EntryParentProc);
  finally
    CloseHandle(hSnapshot);
  end;
end;
Zum Thema WMI "EventWatching", "Win32_ProcessStartTrace": Rein Interesse halber: Hat damit schon mal jemand gearbeitet und hat Tipps/Code-Schnipsel/Erfahrungen, die er teilen kann?
Wer zweifelt, detoniert nicht!'
Dieter Nuhr
  Mit Zitat antworten Zitat
NickelM

Registriert seit: 22. Jul 2007
Ort: Carlsberg
445 Beiträge
 
Delphi 2009 Professional
 
#7

AW: Benachrichtigung wenn Prozess gestartet wurde

  Alt 3. Jun 2012, 02:39
Ich hab noch nie damit gearbeitet, habe aber durch stöbern in der C++ Docu den Code zusammen geschusstert. Du musst nur noch es nur noch in nem Thread auslagern, da er die Anwendung so auf eisleget und du hast deine Abfrage. Im Anhang die Interfaces Datei, die ich per Delphi erstellen gelassen hab, nur die die meisten müsste man umändern, damit man die Errorcodes zurückbekommt, aber beim Debuggen übernihmt das die VCL meistens von selbst. Die Funktionen für diesen Ablauf habe ich bereits umgeändert.
Die Eigenschaften musst du im String suchen. Es gibt auch eine Möglichkeit, sie über die Interfaces abzurufen, aber dies führte bei mir nur zu Fehlern. Kannst es ja mal versuchen, wenn du durchblickst xD
Hier der Code:
Delphi-Quellcode:
var hr : HRESULT;
    pLoc : ISWbemLocator;
    pSvc : ISWbemServices;
    pObj,pNewInsta : ISWbemObject;
    pEvent : ISWbemEventSource;
    Str : WideString;
begin
  //Haupt-Interface
  hr := CoCreateInstance(CLASS_SWbemLocator, nil,
        CLSCTX_INPROC_SERVER, IID_ISWbemLocator, pLoc);
  if FAILED(hr) then
  begin
    ShowMessage('Fehler');
    Exit
  end;
  //Basiert anscheinend auf IP/Domain, ob man da vielleicht Server-Prozzese abrufen kann? Glaub ich eher nicht.
  hr := pLoc.ConnectServer('localhost', '', '', '', '', 0, '',nil, pSvc);
  if FAILED(hr) then
  begin
    pLoc._Release;
    ShowMessage('Fehler');
    Exit;
  end;

  ShowMessage('Connected to WMI'); //Ab hier hast du Zugriff.
  //Der Erste Parameter ist die Abfrage, dies basiert sehr auf SQL, was auch in der Beschreibung von "WQL", wie es sich nennt, steht.
  //Du kannst sehr vieles abrufen, aber damit fragst du ab, wenn ein Prozzes gestartet wurde.
  //Bei mir hat es mit dem Windows Editor geklappt, und 0 % CPU Auslastung beim Warten xD
  hr := pSvc.ExecNotificationQuery('SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE targetInstance ISA "Win32_Process"',
        'WQL',
        $00000020 or $00000010,
        nil,
        pEvent);

  if FAILED(hr) then
  begin
    pLoc._Release;
    pSvc._Release;
    ShowMessage('Fehler bei Query');
    Exit;
  end;
  //Hier die Schleife, nach NextEvent, wartet das Programm auf einen Prozzes start.
  while True do
  hr := pEvent.NextEvent(wbemTimeoutInfinite,pNewInsta);
  //pNewInsta ist nun der neue Prozzes, womit du nun alle Infos abfragen kannst
  if FAILED(hr) then
  begin
    pLoc._Release;
    pSvc._Release;
    pEvent._Release;
    ShowMessage('Fehler bei Instance');
    Exit;
  end;
  //Lass dir es mal in nem Memo ausgeben, da siehste, das sogut
  //wie alles in einem Klartext steht, in einer Art C++ Class Format.
  //Die ist aber sehr leicht zuverstehen finde ich.
  //Sollte für deine Zwecke reichen
  Str := pNewInsta.GetObjectText_(0); //Ist am einfachsten.
  //...bis hier hin.
Angehängte Dateien
Dateityp: pas WbemScripting_TLB.pas (96,8 KB, 13x aufgerufen)
Nickel
"Lebe und denke nicht an morgen"
Zitat aus dem gleichnamigen Bollywoodfilm.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.330 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Benachrichtigung wenn Prozess gestartet wurde

  Alt 3. Jun 2012, 07:29
Doch, das geht auch auf anderen PCs, wenn du dort die notwendigen Zugriffsrechte hast.

Deine Warteschleife hat allerdings keinen Abbruch, deshalb wird das so kaum funktionieren. Fehlt da vielleicht ein begin..end?

Ich würde hier aber auch eher Events benutzen. Stichwort ExecNotificationQueryAsync. Bei Bedarf kann ich dazu auch ein Beispiel basteln.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benutzerbild von diabox
diabox

Registriert seit: 13. Sep 2006
61 Beiträge
 
Delphi 2010 Professional
 
#9

AW: Benachrichtigung wenn Prozess gestartet wurde

  Alt 3. Jun 2012, 16:32
Vielen Dank, NickelM! Das ist, glaube ich, der erste Delphi-Code-Schnipsel, den ich - so ausführlich kommentiert - dazu gesehen habe
Bei Bedarf kann ich dazu auch ein Beispiel basteln.
Beispiele sind immer sehr willkommen, gerade bei COM-Geschichten
Wer zweifelt, detoniert nicht!'
Dieter Nuhr
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.330 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: Benachrichtigung wenn Prozess gestartet wurde

  Alt 3. Jun 2012, 17:09
Ok, hab ich dann mal gemacht. Hat doch ein paar Minuten länger gedauert als ich dachte.

Direkt lauffähig ist das Beispiel ab Delphi 2007 inklusive XE2. Bei Delphi 2006 muss Application.MainFormOnTaskbar in der Projektdatei entfernt werden, die Uraltversionen vorher habe ich nicht getestet, aber da könnte es reichen die Quelltextdateien als Ansi zu speichern.
Angehängte Dateien
Dateityp: 7z WMI Process Create Event.7z (420,5 KB, 51x aufgerufen)
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!

Geändert von jaenicke ( 3. Jun 2012 um 17:12 Uhr)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 05:36 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