etherius Geschrieben 23. Juni 2006 Geschrieben 23. Juni 2006 Hallo Leute, ich arbeite im Moment an einem Prozess-Monitor für eines unserer Tools. Das Problem ist momentan dass das ganze ausschließlich mit Admin-Rechten läuft. Was wir prinzipiell machen ist mit java durch die Prozessliste loopen, die vorher über eine eigens programmierte C-Schnittstelle ausgelesen wird. Leider wird, zumindest so wie es bei uns implementiert ist, dir Prozessliste nicht komplett ausgegeben; stattdessen kann ich die PIDs aller Prozesse sehen, den Pfad der Prozesse die nicht von mir gestartet worden sind allerdings nicht. Allerdings muss es ja eine programmiertechnische Möglichkeit geben um da drumrum zu kommen und alle Prozesse zu sehen, sonst würden ja der Task Manager bzw. der Process Explorer von sysinternals (www.sysinternals.com) auch immer nur die eigenen Prozesse anzeigen können. Weiß jemand wie das funktioniert? Ich bin langsam mit meinem Latein am Ende. Bei google find ich auch irgendwie nichts. Ich würd unsere aktuelle Implementierung ja auch mit posten, allerdings ist die ein wenig zu lang für nen Forenbeitrag. mfg Eth Zitieren
Klotzkopp Geschrieben 26. Juni 2006 Geschrieben 26. Juni 2006 Ich nehme an, du sprichst von Windows. Es wäre gut zu wissen, welche Windows-Version es genau ist. Ich würd unsere aktuelle Implementierung ja auch mit posten, allerdings ist die ein wenig zu lang für nen Forenbeitrag.Du könntest aber schon die allgemeine Vorgehensweise bzw. die benutzten API-Funktionen posten. Ansonsten müsste ich meine Kristallkugel suchen Und weil das mit Standard-C++ nichts zu tun hat: Verschoben -> C++: Compiler, IDEs, APIs Zitieren
etherius Geschrieben 26. Juni 2006 Autor Geschrieben 26. Juni 2006 Da ich von der eigentlichen Implementierung _relativ wenig_ ahnung hab, da ich den Basiscode nicht geschrieben hab (war nen Arbeitskollege, der ist besser in C++ als ich), poste ich hier mal die beiden hauptsächlich verwendeten Funktionen: BOOL __stdcall GetProcessPath(DWORD dwPID, char* szBuff, DWORD dwBuffSize) { HANDLE hSnap; PROCESSENTRY32 ProcInfo = {sizeof(ProcInfo)}; char* szPath = NULL; DWORD dwModh; // we just need the first handle DWORD dwBytesWritten; HANDLE hProc; BOOL bDone; if (!bNT) { // non NT ! hSnap = _CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnap == INVALID_HANDLE_VALUE) return FALSE; if (!_Process32First(hSnap, &ProcInfo)) { CloseHandle(hSnap); return FALSE; } if (ProcInfo.th32ProcessID == dwPID) { CloseHandle(hSnap); if (!StrNCopy( ProcInfo.szExeFile, szBuff, sizeof(ProcInfo.szExeFile), dwBuffSize)) return FALSE; return TRUE; } while (_Process32Next(hSnap, &ProcInfo)) if (ProcInfo.th32ProcessID == dwPID) { CloseHandle(hSnap); if (!StrNCopy( ProcInfo.szExeFile, szBuff, sizeof(ProcInfo.szExeFile), dwBuffSize)) return FALSE; return TRUE; } // clean up CloseHandle(hSnap); return FALSE; // PID not found } else { // NT ! // get a process handle hProc = OpenProcess(NT_PROCESS_ACCESS, FALSE, dwPID); if (!hProc) return FALSE; // get the first module handle and its path if (!EnumProcessModules( hProc, (HINSTANCE*)&dwModh, sizeof(dwModh), &dwBytesWritten)) { CloseHandle(hProc); return FALSE; } if (!GetModuleFileNameEx( hProc, (HINSTANCE)dwModh, szBuff, dwBuffSize)) bDone = FALSE; else bDone = TRUE; // clean up CloseHandle(hProc); return bDone; } } und: BOOL __stdcall GetProcessIDList(DWORD *dwIDArray, DWORD dwArraySize) { HANDLE hSnap; DWORD *pDW, dwBytesWritten; PROCESSENTRY32 ProcInfo = {sizeof(ProcInfo)}; if (dwArraySize < sizeof(DWORD)) return FALSE; if (!bNT) { // non NT ! // make snapshot hSnap = _CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnap == INVALID_HANDLE_VALUE) return FALSE; __try // maybe the array is not writeable { pDW = dwIDArray; if (!_Process32First(hSnap, &ProcInfo)) { CloseHandle(hSnap); return FALSE; } *pDW++ = ProcInfo.th32ProcessID; dwArraySize -= sizeof(DWORD); while (dwArraySize && _Process32Next(hSnap, &ProcInfo)) { *pDW++ = ProcInfo.th32ProcessID; dwArraySize -= sizeof(DWORD); } // clean up CloseHandle(hSnap); } __except(1) { CloseHandle(hSnap); return FALSE; } return TRUE; } else { // NT ! if (!EnumProcesses( (DWORD*)&dwIDArray[0], dwArraySize, &dwBytesWritten)) return FALSE; return TRUE; } } mfg Eth Zitieren
Klotzkopp Geschrieben 26. Juni 2006 Geschrieben 26. Juni 2006 Ich wiederhole die Frage: Um welche Windowsversion geht es genau? Oder ist das Verhalten immer gleich, unabhängig von der Windowsversion? Wie du vielleicht siehst, macht der Code unter NT (genauer: in Abhängigkeit der globalen Variable bNT) etwas völlig anderes. Zitieren
etherius Geschrieben 26. Juni 2006 Autor Geschrieben 26. Juni 2006 Ah guter Punkt, sorry hatte ich überlesen; bin noch nicht ganz da ^^ Es geht ausschließlich um Win2k und WinXP. Der Code für Win98 ist nur aus irgendwelchen komischen Kompatibilitätsgründen noch drin. Zitieren
Klotzkopp Geschrieben 26. Juni 2006 Geschrieben 26. Juni 2006 Anscheinend braucht ein Prozess das Privileg SE_DEBUG_NAME, um an die Dateipfade der Prozesse zu kommen. Dieses Privileg bekommen nur Prozesse, die von einem Administrator gestartet werden, automatisch. Du kannst das Privilig aber nachträglich hinzufügen. Stichwort AdjustTokenPrivileges. Zitieren
etherius Geschrieben 26. Juni 2006 Autor Geschrieben 26. Juni 2006 Ich hab das Anhand einiger Beispiele mal grad implementiert, als extra funktion in der dll: /* * Class: de_symmedia_util_windows_process_Process * Method: setCurrentProcessSEDebug */ JNIEXPORT jint JNICALL Java_de_symmedia_util_windows_process_Process_setCurrentProcessSEDebug (JNIEnv * env, jclass obj) { HANDLE hToken; /* process token */ TOKEN_PRIVILEGES tp; /* token provileges */ DWORD dwSize = sizeof (TOKEN_PRIVILEGES); LUID luid; /* now, set the SE_SYSTEMTIME_NAME privilege to our current * process, so we can call SetSystemTime() */ if (!OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { return 1; } if (!LookupPrivilegeValue (NULL, SE_DEBUG_NAME, &luid)) { //printf ("LookupPrivilege() failed with code %d\n", GetLastError()); CloseHandle (hToken); return 1; } ZeroMemory (&tp, sizeof (tp)); tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; /* Adjust Token privileges */ if (!AdjustTokenPrivileges (hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, &dwSize)) { //printf ("AdjustTokenPrivileges() failed with code %d\n", GetLastError()); CloseHandle (hToken); return 1; } CloseHandle (hToken); return 0; } mit Java-Implementierung: public static native int setCurrentProcessSEDebug(); Funktioniert aber irgendwie nicht. Der Process Explorer zeigt mir das Recht für den Prozess nicht an und die Prozessliste seh ich auch nicht komplett. Hast du noch ne Idee? Wie gesagt, bin kein C-As mfg Eth Zitieren
Klotzkopp Geschrieben 26. Juni 2006 Geschrieben 26. Juni 2006 Funktioniert aber irgendwie nicht.Lies meine Signatur. Welchen Rückgabewert bekommst du denn? Alle anderen Diagnosemöglichkeiten hast du ja auskommentiert. Zitieren
etherius Geschrieben 26. Juni 2006 Autor Geschrieben 26. Juni 2006 Sorry, das Interessante an der Sache ist, dass ich einen Rückgabewert 0 bekomme. Zitieren
Klotzkopp Geschrieben 26. Juni 2006 Geschrieben 26. Juni 2006 Dein Code funktioniert bei mir in einer Konsolenanwendung. Der Process Explorer zeigt nach dem Aufruf von AdjustTokenPrivileges SeDebugPrivilege nicht mehr als Disabled an. Zitieren
etherius Geschrieben 26. Juni 2006 Autor Geschrieben 26. Juni 2006 Könnte das eventuell an dem Aufruf in der DLL liegen? Ich will ja prinzipiell an die javaw.exe ran, die die dll als library nachgeladen hat ... EDIT: Hast du das ganze mit einem normalo-account getestet? Zitieren
Klotzkopp Geschrieben 26. Juni 2006 Geschrieben 26. Juni 2006 Könnte das eventuell an dem Aufruf in der DLL liegen? Ich will ja prinzipiell an die javaw.exe ran, die die dll als library nachgeladen hat ...Kann ich nicht ausschließen. Mach doch vor und nach dem Aufruf eine MessageBox, dann kannst du dir das genauer ansehen. EDIT: Hast du das ganze mit einem normalo-account getestet?Ja. Das Privileg war vor dem Aufruf Disabled. Zitieren
etherius Geschrieben 26. Juni 2006 Autor Geschrieben 26. Juni 2006 Ich versteh das irgendwie nicht. Der zeigt mir das Attribut einfach im PE nicht an. Steht doch dann unter Security oder? Zitieren
Klotzkopp Geschrieben 26. Juni 2006 Geschrieben 26. Juni 2006 Steht doch dann unter Security oder?Genau. Es steht immer da, nur eben normalerweise Disabled. Die beiden Bilder zeigen des Zustand vorher und nachher: Zitieren
etherius Geschrieben 26. Juni 2006 Autor Geschrieben 26. Juni 2006 Bei mir sieht das anders aus. Bei mir wird das gar nicht angezeigt. Zitieren
Klotzkopp Geschrieben 26. Juni 2006 Geschrieben 26. Juni 2006 Ein Privileg, das nicht da ist, kannst du auch nicht mit AdjustTokenPrivileges aktivieren. Haben andere (nicht-Java-) Prozesse bei dir dieses Privileg? Zitieren
etherius Geschrieben 26. Juni 2006 Autor Geschrieben 26. Juni 2006 Nein haben sie nicht. Aber wie ich bereits sagte arbeite ich als normalo-benutzer ohne Admin-Rechte. Ich habe gerade mal ein wenig rumgespielt, und dabei festgestellt, dass selbst der Process Explorer im Normalbenutzerbetrieb die Pfadnamen der Prozesse nicht kennt. Allerdings kennt er den Namen der ausführbaren Datei. Wie komm ich denn da dran? Zitieren
Klotzkopp Geschrieben 26. Juni 2006 Geschrieben 26. Juni 2006 Aber wie ich bereits sagte arbeite ich als normalo-benutzer ohne Admin-Rechte. Hm. Ich bin hier zwar kein Admin, aber habe doch offenbar ziemlich viele Rechte. Allerdings kennt er den Namen der ausführbaren Datei. Wie komm ich denn da dran?Der Name ohne Pfad steht im szExeFile-Member der PROCESSENTRY32-Struktur. Zitieren
etherius Geschrieben 26. Juni 2006 Autor Geschrieben 26. Juni 2006 Die PROCESSENTRY32 Struktur wird in unserer Implementierung anscheinend nur für win98/me genutzt. Für spätere Versionen wird PSAPI verwendet. Macht das so überhaupt sinn? Zitieren
Guybrush Threepwood Geschrieben 26. Juni 2006 Geschrieben 26. Juni 2006 Was ist denn ein "Normalo-Benutzer"? Es gibt ja mehre Arten von Benutzergruppen. Z.B. Administratoren, Hauptbenutzer, Benutzer, Gäste usw... Zitieren
etherius Geschrieben 26. Juni 2006 Autor Geschrieben 26. Juni 2006 Der User ist in der Gruppe "Benutzer" ( Benutzer mit eingeschränktem Zugriff) Zitieren
Klotzkopp Geschrieben 26. Juni 2006 Geschrieben 26. Juni 2006 Die PROCESSENTRY32 Struktur wird in unserer Implementierung anscheinend nur für win98/me genutzt. Für spätere Versionen wird PSAPI verwendet. Macht das so überhaupt sinn?Kommt drauf an. Du hast nicht gezeigt, wie bNT gesetzt wird. Allerdings vermute ich da ein Missverständnis. CreateToolhelp32Snapshot gibt es wirklich nur unter NT nicht. Unter 2000 und XP ist es da. Die OpenProcess-Lösung ist die "ältere". Zitieren
etherius Geschrieben 26. Juni 2006 Autor Geschrieben 26. Juni 2006 Wie gesagt, ich hab das ganze nicht implementiert ich erweitere nur. Hab grad ein wenig MSDN zu dem Thema durchstöbert. Wir haben an sich offiziell nur noch Kompatibilität zu 2000 und XP, teilweise 2k3. So wie ich das sehe steht aber doch in der PROCESSENTRY32.szExeFile der komplette Pfad drin, oder? und auf den hab ich doch wieder keinen Zugriff ohne SE_DEBUG! Zitieren
Bubble Geschrieben 26. Juni 2006 Geschrieben 26. Juni 2006 Zur Prozessliste: Es gibt mehrere Möglichkeiten an eine Liste der grade ausgeführten Prozesse zu kommen. Nicht jede Variante wird unter jeder Windows-Version unterstützt. Sofern es Dir nicht wichtig ist NT zu unterstützen, kannst Du CreateToolhelp32Snapshot benutzen. Um den Pfad zur Exe ohne OpenProcess herauszufinden (so wie ich Dich verstanden habe, scheitert es an dieser Funktion aufgrund der Privilegien des Benutzers), kannst Du für jeden Prozess die Liste seiner Module durchgehen (jedes Modul hat einen eigenen Pfad). Eine weitere Möglichkeit wäre es, die Liste über WMI abzufragen. Zitieren
etherius Geschrieben 28. Juni 2006 Autor Geschrieben 28. Juni 2006 Ich hab es Läuft super: Kleines Beispiel: #include <windows.h> #include <stdio.h> #include <tchar.h> #include <tlhelp32.h> void main(void) { HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); if (hSnapshot==INVALID_HANDLE_VALUE) { // error: unable to create snapshot exit(1); } PROCESSENTRY32 pe; // fill up its size pe.dwSize=sizeof(PROCESSENTRY32); BOOL retval=Process32First(hSnapshot,&pe); while(retval) { printf("Process ID : %s\n",pe.szExeFile); pe.dwSize=sizeof(PROCESSENTRY32); retval=Process32Next(hSnapshot,&pe); } // close snapshot handle CloseHandle(hSnapshot); } Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.