Hi.
@Alice: Du hattest zwar eine PN gesendet, aber ich werde einen Lösungsansatz hier posten, da sicher noch einige dieses Problem haben werden.
Das Problem ist, wie bereits geschrieben, dass die nötigen Rechte fehlen um alle Informationen zu allen Prozessen zu erhalten.
Als erstes muss das Programm den Sicherheitsrahmen des lokalen Systems "imitieren". Das geschieht über den Aufruf von
ImpersonateSelf(SecurityImpersonation).
Dann muss über die
OpenThreadToken-Funktion ein Handle zum eigenem Thread (das Programm) mit der gewünschten Zugriffsart geöffnet werden. Über die
LookupPrivilegeValue-Funktion wird eine eindeutige ID geholt, welche das entsprechende Sicherheitsprivileg beschreibt. Über den Parameter "lpName" wird der String "SeDebugPrivilege" übergeben, dadurch wird der gewünschte Zugriff bedingungslos gewährt. Diese ID braucht man um die Privilegien des eigenen Anwendung zu ändern.
Jetzt müssen die Privilegien der eigenen Anwendung noch eingestellt werden (
AdjustTokenPrivileges-Funktion) und schon gibts bei der Informationsabfrage der Prozesse keine Probleme mehr.
ACHTUNG: Ich habs selbst noch nicht probiert, aber durch die erhaltenen Privilegien könnte man auch wichtige Prozesse "abschießen", auf welche man sonst keinen Zugriff hat. Es könnte also möglich sein wichtige Systemprozesse zu beenden oder deren Einstellungen zu verändern (Priorität, etc...). Es sollten außerdem aus Sicherheitsgründen die Privilegien, nach den gewünschten Aktionen, immer wieder zurückgesetzt werden.
Hier nach der Theorie nun auch mal etwas Quelltext:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72:
|
function TForm1.SetDebugPrivilege( bEnable: Boolean ): Boolean; var hToken: THandle; const SE_DEBUG_NAME = 'SeDebugPrivilege'; begin ImpersonateSelf(SecurityImpersonation); if OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, false, hToken) then begin SetPrivilege(hToken, SE_DEBUG_NAME, bEnable); CloseHandle(hToken); Result := true; end else begin Result := false; end; end;
procedure TForm1.SetPrivilege( hToken: THandle; sPrivilege: String; bEnable: Boolean ); var tp: TTokenPrivileges; tpPrev: TTokenPrivileges; luid: Int64; BufferLength: Cardinal; ReturnValue: Cardinal; begin BufferLength := SizeOf(TTokenPrivileges); LookupPrivilegeValue(nil,PAnsiChar(sPrivilege),luid); tp.PrivilegeCount := 1; tp.Privileges[0].Luid := luid; if bEnable then begin tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED; end else begin tp.Privileges[0].Attributes := 0; end; AdjustTokenPrivileges(hToken,false,tp,BufferLength,tpPrev,ReturnValue); end; |
Ich kann jetzt jederzeit über
Delphi-Quelltext
1:
| SetDebugPrivilege(true); |
die Privilegien setzen und über
Delphi-Quelltext
1:
| SetDebugPrivilege(false); |
wieder zurücksetzen.
Was ich auch noch nicht ausprobiert habe, ob es einen Unterschied bezüglich des Holens von Informationen macht "OpenProcess(...)" mit Zugriffslevel PROCESS_ALL_ACCESS aufzurufen. Eigentlich sollte PROCESS_QUERY_INFORMATION reichen.
Ich hoffe dass ich helfen konnte und ich nix vergessen bzw. falsch wiedergegeben habe. Bin halt selber noch nicht so tief in die WinAPI und deren Auswüchse eingetaucht.
Mfg
Olli
EDV-Systeme verarbeiten, womit sie gefüttert werden.
Kommt Mist rein, kommt Mist raus. -André Kostolany-