Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Empfohlene Antworten

Veröffentlicht

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

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

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

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.

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.

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.

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 :P

mfg

Eth

Sorry, das Interessante an der Sache ist, dass ich einen Rückgabewert 0 bekomme.

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?

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.

Ich versteh das irgendwie nicht. Der zeigt mir das Attribut einfach im PE nicht an. Steht doch dann unter Security oder?

Bei mir sieht das anders aus. Bei mir wird das gar nicht angezeigt.

post-25800-14430447379447_thumb.jpg

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?

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.

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?

Der User ist in der Gruppe "Benutzer" ( Benutzer mit eingeschränktem Zugriff)

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".

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!

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.

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);

}

Erstelle ein Konto oder melde dich an, um einen Kommentar zu schreiben.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.