![]() |
Benutzernamen von Prozessen ermitteln
Hallo!
Ich möchte gerne alle Prozesse auf einem System auflisten und außerdem anzeigen lassen, unter welchem Benutzer ein jeweiliger Prozess ausgeführt wird. Mittels CreateToolhelp32Snapshot kommt man zwar sehr leicht an alle laufenden Prozesse, jedoch nicht an die Benutzernamen. Ich habe schon mal versucht folgendermaßen vorzugehen: i) OpenProcess(...mit jeweiliger ProzessId) ii) GetSecurityInfo(...SE_KERNEL_OBJECT...OWNER_SECURI TY_INFORMATION...) iii) die in ii) erhaltene SID einem Benutzer zuordnen Sieht umständlich aus - ist es auch. :wall: Außerdem klappt das insbesondere bei Systemprozessen nicht immer reibungslos?! Weiß jemand, wie man elegant an den Namen des Benutzers kommt, der einen Prozess ausführt? Besten Dank im Voraus! |
Re: Benutzernamen von Prozessen ermitteln
Zitat:
|
Re: Benutzernamen von Prozessen ermitteln
Zitat:
|
Re: Benutzernamen von Prozessen ermitteln
Schon mit OpenProcess(PROCESS_QUERY_INFORMATION)/OpenProcessToken(TOKEN_QUERY)/QueryTokenInformation(TokenUser) probiert?
(eventuell vorher noch das Debug-Privileg für den eigenen Prozess aktivieren) |
Re: Benutzernamen von Prozessen ermitteln
Habe SeDebugPrivilege und Prozess-Token wurde mit
PROCESS_QUERY_INFORMATION geöffnet. Klappt einwandfrei bei Prozessen von normalen Benutzern, nicht aber bei Netzwerk- und Systemdiensten. |
Re: Benutzernamen von Prozessen ermitteln
Zitat:
|
Re: Benutzernamen von Prozessen ermitteln
Aus diesem Grund zeigt der TaskMgr nur den Benutzernamen an, wenn er auf einem Terminalserver-System läuft. Ansonsten bleibt diese Option deaktiviert!!!
Also, keine Chance, es sei denn du ermittelst dir irgendwie die Prototypen der beiden Verdächtigen, einer Funktion WinStationGetProcessSid() aus WINSTA.DLL und einer CachedGetUserFromSid() aus UTILDLL.DLL?! Ich schau's mir nachher nochmal an, die aus WINSTA.DLL brauchst du jedenfalls definitiv, die andere offensichtlich nur wenn du einfach an den Benutzernamen kommen willst. Die letzten beiden Parameter bei ![]() Sicher ist, daß TaskMgr diese Funktion auf einem TS aufruft. Unter W2K ist die Funktion per GetProcAddress eingebunden, bei WXP über Delay Loading ... In meinem Disassemblat sehe ich sogar, daß offensichtlich vom Task-Manager auf TS eine Funktion WinStationTerminateProcess() benutzt wird um Prozesse zu beenden. Wo der Sinn ist, bleibt mir noch rätselhaft. Vielleicht ist das nur Terminal-Session-übergreifend nötig oder so?!? Jedenfalls konnte ich in einem russischen Forum den Hinweis auf WinStationGetProcessSid() finden ![]() |
Re: Benutzernamen von Prozessen ermitteln
Zitat:
Zitat:
|
Re: Benutzernamen von Prozessen ermitteln
Hallo!
Danke für die vielen Hinweise, ich werde mal versuchen damit so weit wie möglich zu kommen. Wenn etwas einigermaßen brauchbares rausspringt, kommt der Quellcode hier rein :-D Viele Grüße peanut. |
Re: Benutzernamen von Prozessen ermitteln
Zitat:
Aber schon interessant. Würdest du dich dazu herablassen zu dieser Funktion und WinStationConnect die C- oder Delphi-Prototypen hier hinzuklimpern? :tongue: Zitat:
|
Re: Benutzernamen von Prozessen ermitteln
Zitat:
(wer undokumentierte Funktionen benutzt, sollte Fallbacks implementieren)
Delphi-Quellcode:
Wie immer ohne Gewähr...
// winsta.dll
const LOGONID_CURRENT = ULONG(-1); SERVERNAME_CURRENT = THandle(nil); type TFNWinStationConnectW = function( hServer : THandle; SessionId : ULONG; TargetSessionId: ULONG; pPassword : PWideChar; // use L"" instead of NULL bWait : BOOLEAN ): BOOLEAN; stdcall; type TFNWinStationDisconnect = function( hServer : THandle; SessionId: ULONG; bWait : BOOLEAN ): BOOLEAN; stdcall; type TFNWinStationGetProcessSid = function( hServer : THandle; ProcessId : ULONG; ProcessStartTime: TFileTime; pProcessUserSid : PSID; var dwSidSize : ULONG ): BOOLEAN; stdcall; // utildll.dll type TFNCachedGetUserFromSid = procedure( pSid : PSID; pUserName : PWideChar; var cbUserName: ULONG ); stdcall; ps: Für WinStationGetProcessSid braucht man kein WinStationConnect, allerdings muss die CreateTime stimmen, ansonsten gibt die WinStationGetProcessSid 'ungültiges Handle' zurück. |
Re: Benutzernamen von Prozessen ermitteln
Zitat:
Na denn: sssänk juh wärrie matsch :mrgreen: :mrgreen: :mrgreen: :mrgreen: :mrgreen: (BTW: Bekommst heute noch Mail bzgl. Objektnamen und Treiber) |
Programm lp
War auch etwas fleißig:
Delphi-Quellcode:
Wie man testenkann (*), komme ich jetzt auch an alle SIDs, leider klappt das mit dem mapping nicht so toll und man erhält häufig nur leere Strings.
program lp; {$APPTYPE CONSOLE}
uses SysUtils, Windows, tlhelp32, psapi; type LPByte = ^Byte; TNET_DISPLAY_USER = record usri1_name : LPWSTR; usri1_comment : LPWSTR; usri1_flags : DWORD; usri1_full_name : LPWSTR; usri1_user_id : DWORD; usri1_next_index: DWORD; end; PNET_DISPLAY_USER = ^TNET_DISPLAY_USER; function ConvertSidToStringSidA(Sid: PSID; var StringSid: LPTSTR): LongBool; stdcall; external 'advapi32.dll'; function GetSecurityInfo(handle: THandle; ObjectType: DWord; SecurityInfo: SECURITY_INFORMATION; ppsidOwner: PSID; ppsidGroup: PSID; ppDacl: PACL; ppSacl: PACL; ppSecurityDescriptor: PSECURITY_DESCRIPTOR): DWORD; stdcall; external 'advapi32.dll'; function NetQueryDisplayInformation(ServerName: LPWSTR; Level, Index, EntriesRequested, ReferredMaximumLength: DWORD; var ReturnedEntryCount: DWORD; var SortedBuffer: LPBYTE): LongWord; stdcall; external 'Netapi32.dll'; function NetApiBufferFree(Buffer: Pointer): DWORD; stdcall; external 'Netapi32.dll'; const SE_UNKNOWN_OBJECT_TYPE: DWord = 0; SE_FILE_OBJECT: DWord = 1; SE_SERVICE: DWord = 2; SE_PRINTER: DWord = 3; SE_REGISTRY_KEY: DWord = 4; SE_LMSHARE: DWord = 5; SE_KERNEL_OBJECT: DWord = 6; SE_WINDOW_OBJECT: DWord = 7; function AdjustToken(sPrivilege: String; boEnable: Boolean): Boolean; var hToken : Cardinal; lpLuid : Int64; NewPState : TOKEN_PRIVILEGES; ReturnLength: DWORD; begin Result := False; try if (OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken)) then begin if (LookupPrivilegeValue(nil, PCHAR(sPrivilege), lpLuid)) then begin ZeroMemory(@NewPState, SizeOf(TOKEN_PRIVILEGES)); NewPState.PrivilegeCount := 1; NewPState.Privileges[0].Luid := lpLuid; if (boEnable) then NewPState.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED; ReturnLength := 0; if (AdjustTokenPrivileges(hToken, False, NewPState, 0, nil, ReturnLength)) then Result := True; end; CloseHandle(hToken); end; except end; end; function GetEXEByPID(pid: DWord): String; var h: THandle; begin Result := ''; h := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, pid); if (h <> 0) then try SetLength(Result, MAX_PATH); ZeroMemory(@Result[1], MAX_PATH); GetModuleFileNameEx(h, 0, PChar(Result), MAX_PATH); Result:=TrimRight(Result); finally CloseHandle(h); end; Result := LowerCase(Result); end; function SidToString(ASID: PSID): String; var sDummy: LPTSTR; begin ConvertSidToStringSidA(ASID, sDummy); Result := String(sDummy); end; function GetUserBySID(ASID: PSID): String; var total: DWord; sBuffer: LPByte; UserInfo: PNET_DISPLAY_USER; UserSID : PSID; cbUserSID: Cardinal; sDomain : String; sUserName: String; cbsDomain: Cardinal; pNameUse : SID_NAME_USE; begin Result := ''; NetQueryDisplayInformation('\\.', 1, 0, 8192, 65536, total, sBuffer); UserInfo := @sBuffer^; while (total > 0) do begin sUserName := String(UserInfo.usri1_name); cbUserSID := 0; UserSID := nil; sDomain := ''; cbsDomain := 0; LookupAccountName(PChar('\\.'), PChar(sUserName), UserSID, cbUserSID, @sDomain[1], cbsDomain, pNameUse); GetMem(UserSID, cbUserSID); ZeroMemory(UserSID, cbUserSID); SetLength(sDomain, cbsDomain); ZeroMemory(@sDomain[1], Length(sDomain)); if (LookupAccountName(PChar('\\.'), PChar(sUserName), UserSID, cbUserSID, @sDomain[1], cbsDomain, pNameUse)) then begin ReallocMem(UserSID, cbUserSID); if IsValidSid(UserSID) and (SidToString(ASID) = SidToString(UserSID)) then begin Result := sUserName; break; end; end; dec(total); inc(UserInfo); end; NetApiBufferFree(sBuffer); end; function GetUserByPID(pid: DWord): String; var phandle: THandle; ppsidOwner: PSID; SecDescriptor: PSECURITY_DESCRIPTOR; nResult: DWord; begin Result := ''; try phandle := OpenProcess(PROCESS_QUERY_INFORMATION or GENERIC_READ, False, pid); if (phandle <> 0) then begin nResult := GetSecurityInfo(phandle, SE_KERNEL_OBJECT, OWNER_SECURITY_INFORMATION, @ppsidOwner, nil, nil, nil, @SecDescriptor); if (nResult = 0) then begin Result := GetUserBySID(ppsidOwner); // SidToString(ppsidOwner); (*) LocalFree(Cardinal(SecDescriptor)); end; end; except end; end; function GetProcessesAndUserNames: Integer; var hProcSnap: THandle; pe32 : TProcessEntry32; sEXEname : String; sUserName: String; begin Result := 0; AdjustToken('SeDebugPrivilege', True); // Perform snapshot hProcSnap := CreateToolHelp32SnapShot(TH32CS_SNAPALL, 0); if hProcSnap = INVALID_HANDLE_VALUE then exit; pe32.dwSize := SizeOf(pe32); if (Process32First(hProcSnap, pe32)) then begin // let`s go... writeln(UpperCase(pe32.szExeFile)); inc(Result); while (Process32Next(hProcSnap, pe32) = true) and (pe32.th32ProcessID <> GetCurrentProcessId) do begin sEXEname := Trim(LowerCase(GetEXEByPID(pe32.th32ProcessID))); sUserName := Trim(LowerCase(GetUserByPID(pe32.th32ProcessID))); if (sEXEname <> '') and (sEXEname <> '?') then writeln(sEXEname + ' | ' + sUserName) else writeln('['+UpperCase(pe32.szExeFile)+']' + ' | ' + sUserName); inc(Result); end; end; CloseHandle(hProcSnap); AdjustToken('SeDebugPrivilege', False); end; begin GetProcessesAndUserNames; readln; end. |
Re: Benutzernamen von Prozessen ermitteln
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe mir das mal angeguckt. Zum einem ist es sehr umständlich, zu mal du auch interne Funktionen benutzt und zum anderen gibst du Speicher nicht mehr frei, den du mit GetMem alloziierst bzw. du schließt die Handle nicht mehr, die du mit OpenProcess öffnest.
Ich habe das mal etwas umgeschrieben und verbesser. Unit im Anhang. |
Re: Benutzernamen von Prozessen ermitteln
Hallo Michael,
Zitat:
Zitat:
Danke für die Mühe! Viele Grüße peanut. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:55 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz