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?

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

}

Erstelle ein Benutzerkonto oder melde Dich an, um zu kommentieren

Du musst ein Benutzerkonto haben, um einen Kommentar verfassen zu können

Benutzerkonto erstellen

Neues Benutzerkonto fĂŒr unsere Community erstellen. Es ist einfach!

Neues Benutzerkonto erstellen

Anmelden

Du hast bereits ein Benutzerkonto? Melde Dich hier an.

Jetzt anmelden

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