Zum Inhalt springen

Empfohlene Beiträge

Geschrieben

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

Geschrieben

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

Geschrieben

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

Geschrieben

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.

Geschrieben

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.

Geschrieben

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.

Geschrieben

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

Geschrieben

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?

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

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?

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

Geschrieben

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!

Geschrieben

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.

Geschrieben

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

}

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...