AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Programm von Dienst starten lassen (Jetzt aber wirklich mal)
Thema durchsuchen
Ansicht
Themen-Optionen

Programm von Dienst starten lassen (Jetzt aber wirklich mal)

Ein Thema von CodeX · begonnen am 26. Feb 2008 · letzter Beitrag vom 5. Aug 2014
Antwort Antwort
Seite 2 von 5     12 34     Letzte »    
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#11

Re: Programm von Dienst starten lassen (Jetzt aber wirklich

  Alt 21. Mai 2008, 21:14
Zitat von CodeX:
@Dezipaitor
zu 2. Das andere Token bekomme ich aber wirklich nur von einem bestimmten Administratoraccount auf dem Rechner, oder? Es wäre eben schön, wenn das auch anders gehen könnte und der User nicht gezwungen wäre, irgendein Passwort einzugeben. Kann ich denn als SYSTEM ein Admin-Token einfach so erstellen und das nicht von einem bestehenden Account kopieren? Dann bräuchte man eben keine Login-Daten...
Du willst also das Token vom Benutzer kopiere und nur Adminrechte einfügen? Nunja. Das müsste gehen. Man kann nur kein komplett neues Token erstellen, weil dafür eine Logon ID notwendig ist, die man von einen Logonprovider bekommt. Ka wie das geht. Im Moment macht das nur LsaLogonUser. Man kann aber eine vorhandene ID nutzen, die z.b. ein Benutzer beim Einloggen bekommen hat. Mein CreateToken Beispiel in JWSCL macht das.


Zitat von CodeX:
zu 3. Ne, nichts zur Sicherheit, aber damit das Programm normal funktionieren kann und z.B. auf Current_User zugreifen kann und auf dessen Desktop dargestellt werden kann. Sonst besteht doch auch das Problem, dass die GUI gar nicht sichtbar ist.
Das geht auch mit dem normalen Benutzertoken. Dazu brauchst du nur die SessionID und WTSQueryUserToken
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
CodeX

Registriert seit: 30. Okt 2004
475 Beiträge
 
Delphi 12 Athens
 
#12

Re: Programm von Dienst starten lassen (Jetzt aber wirklich

  Alt 22. Mai 2008, 05:20
Zitat von Dezipaitor:
Du willst also das Token vom Benutzer kopiere und nur Adminrechte einfügen? Nunja. Das müsste gehen.
Klingt gut. Die Frage ist nur: Wie?


Zitat von Dezipaitor:
Das geht auch mit dem normalen Benutzertoken. Dazu brauchst du nur die SessionID und WTSQueryUserToken
Und wie komme ich an die SessionID?

Prinzipiell würde ich das ja so machen:
Delphi-Quellcode:
function GetEnvironment(): LPVOID;
var
  LToken: THandle;
  LDupToken: THandle;
  LSessionID: DWORD;
begin
  Result := nil;

  LSessionID := WTSGetActiveConsoleSessionId; //<- da muss wohl was anderes hin...
  WTSQueryUserToken(LSessionID, @LToken);
  DuplicateTokenEx(LToken, TOKEN_ASSIGN_PRIMARY or TOKEN_ALL_ACCESS, nil, SecurityIdentification, TokenPrimary, LDupToken);

  if (not CreateEnvironmentBlock(Result, LDupToken, True)) then
    Result := nil;
end;



function RunProcess(FileName: string): Longword;
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
begin
  FillChar(StartupInfo, SizeOf(StartupInfo), #0);
  StartupInfo.cb := SizeOf(StartupInfo);
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
  StartupInfo.wShowWindow := SW_SHOW;
  if not CreateProcess(nil,
    @Filename[1],
    nil,
    nil,
    False,
    NORMAL_PRIORITY_CLASS or CREATE_NEW_PROCESS_GROUP, //<- stimmen die Flags so?
    GetEnvironment, //<- hier die Umgebung des normalen Benutzers übergeben
    nil,
    StartupInfo,
    ProcessInfo)
    then
      Result := WAIT_FAILED;
end;
Aber WTSGetActiveConsoleSessionId liefert mir ja nur die SessionID von SYSTEM, bringt also nichts. Wie muss der Code statt dessen lauten, damit ich die Umgebung dann bei CreateProcess mit übergeben kann?


Huch, doch schon so spät. Du siehst, mir lässt das keine Ruhe. Ich gehe jetzt erstmal schlafen...
  Mit Zitat antworten Zitat
Benutzerbild von Remko
Remko

Registriert seit: 10. Okt 2006
Ort: 's-Hertogenbosch, Die Niederlande
222 Beiträge
 
RAD-Studio 2010 Arc
 
#13

Re: Programm von Dienst starten lassen (Jetzt aber wirklich

  Alt 22. Mai 2008, 09:16
WTSQueryUserToken returns a user's primary token so you don't need to duplicate it. Just past the tokenhandle to CreateProcessAsUser and be sure to pass nil for the desktop param of the startupinfo structure. Something like this:
Delphi-Quellcode:
  // Obtain the primary user token
  WTSQueryUserToken(SessionId, hToken);

  if hToken <> 0 then
  begin
    // Fill buffer with zeroes
    ZeroMemory(@si, SizeOf(si));
    si.cb := SizeOf(si);

    si.lpDesktop := nil;

    if CreateProcessAsUser(hToken, nil, Cmd, nil, nil, False, 0, nil, nil,
      si, pi) then
...
Notes: WTSQueryUserToken needs Windows XP/2003 or higher, if you need windows 2000 compatibility check Jwscl as it contains a WTSQueryUserTokenEx function that also works on Windows 2000.
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#14

Re: Programm von Dienst starten lassen (Jetzt aber wirklich

  Alt 22. Mai 2008, 17:14
Willst du das wirklich alles nur mit der WinAPI machen? Das geht natürlich. Plane aber mal noch 3-4Wochen Zusatzaufwand dafür ein. Ich selbst würde da nur noch die JWSCL benutzen.
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
CodeX

Registriert seit: 30. Okt 2004
475 Beiträge
 
Delphi 12 Athens
 
#15

Re: Programm von Dienst starten lassen (Jetzt aber wirklich

  Alt 22. Mai 2008, 17:38
Zitat von Remko:
WTSQueryUserToken returns a user's primary token so you don't need to duplicate it. Just past the tokenhandle to CreateProcessAsUser and be sure to pass nil for the desktop param of the startupinfo structure. Something like this...
Yes, you're right this is shorter, but it gives me the environment of SYSTEM and not of the logged in user.

Delphi-Quellcode:
function GetEnvironment(): LPVOID;
var
  SessionID : DWORD;
  hToken : THandle;
begin
  Result := nil;

  WTSQueryUserToken(SessionID, hToken);

  if (not CreateEnvironmentBlock(Result, hToken, True)) then
    Result := nil;
end;
Zitat von Remko:
Notes: WTSQueryUserToken needs Windows XP/2003 or higher, if you need windows 2000 compatibility check Jwscl as it contains a WTSQueryUserTokenEx function that also works on Windows 2000.
OK, good that you remind me, because I do need 2000 compatibility. Unfortunatelly I still can't get Jwscl to work so I can't test WTSQueryUserTokenEx at the moment.


Zitat von Dezipaitor:
Willst du das wirklich alles nur mit der WinAPI machen? Das geht natürlich. Plane aber mal noch 3-4Wochen Zusatzaufwand dafür ein. Ich selbst würde da nur noch die JWSCL benutzen.
Ich würde ja sehr gerne die Jwscl benutzen, aber ich bekomme das leider nicht zum Laufen bei mir. Ich mache jetzt mal eine frische Installation von Jwa und Jwscl dann mal sehen...
  Mit Zitat antworten Zitat
CodeX

Registriert seit: 30. Okt 2004
475 Beiträge
 
Delphi 12 Athens
 
#16

Re: Programm von Dienst starten lassen (Jetzt aber wirklich

  Alt 22. Mai 2008, 20:29
Ok, nach einer vollständigen und peniblen Neuinstallation funktioniert Jwa und Jwscl jetzt wohl. Scheint was durcheinander gekommen zu sein mit der alten und der aktuellen Version. Nun gut, das geht ja jetzt schon mal. Dann versuche ich jetzt mal da drauf aufzubauen.


Das habe ich jetzt zusammengebasteln:

Delphi-Quellcode:
var
  UserToken: TJwSecurityToken;
  ConsoleUser : TJwSecurityId;

  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;

  UserEnvironment : LPVOID;
begin
  UserToken := TJwSecurityToken.CreateWTSQueryUserTokenEx(nil, WtsGetActiveConsoleSessionID);

  try

    ZeroMemory(@StartupInfo, SizeOf(StartupInfo));
    StartupInfo.cb := SizeOf(StartupInfo);
    StartupInfo.lpDesktop := nil;

    StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
    StartupInfo.wShowWindow := SW_SHOW;


    CreateEnvironmentBlock(UserEnvironment, UserToken.TokenHandle, True); //<- so richtig?


    CreateProcess(nil,
      PChar('c:\test.exe'),
      nil,
      nil,
      False,
      NORMAL_PRIORITY_CLASS or CREATE_NEW_PROCESS_GROUP,
      UserEnvironment, //<- EnvironmentBlock
      nil,
      StartupInfo,
      ProcessInfo);


  finally
    FreeAndNil(UserToken);
  end;

end;
1. Ich verwende CreateProcess und nicht CreateProcessAsUser, weil ich ja gar nicht brauche, dass das Programm als anderer Benutzer ausgeführt wird. Ist das dann so OK?

2. Die Umgebung (UserEnvironment) wird nicht richtig verarbeitet. Wenn ich nil statt UserEnvironment übergebe, dann startet das Programm als SYSTEM hat aber auch dessen Umgebungsvariablen. Wenn ich aber versuche, den EnvironmentBlock zu erstellen (wie im Code dargestellt), dann startet das Programm gar nicht mehr. Wo liegt der Fehler? Bzw. wie geht das richtig?

3. Selbst wenn das dann starten würde, bin ich immer noch der Meinung, dass bei Verwendung von WtsGetActiveConsoleSessionID ich die Umgebung von SYSTEM erhalte und nicht vom User. Wie dann? edit: Hm, habe das jetzt mit UserToken.GetTokenUserName überprüft und es ist der Benutzername. Sollte dann also wohl doch so funktionieren...
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#17

Re: Programm von Dienst starten lassen (Jetzt aber wirklich

  Alt 22. Mai 2008, 21:19
Zitat von CodeX:
1. Ich verwende CreateProcess und nicht CreateProcessAsUser, weil ich ja gar nicht brauche, dass das Programm als anderer Benutzer ausgeführt wird. Ist das dann so OK?
Wenn du den neuen Prozess nicht als den Benutzer ausführen willst, dann nutze CreateProcess. Wenn dein aktueller Prozess SYSTEM ist, dann wird der neue auch SYSTEM.

Zitat von CodeX:
2. Die Umgebung (UserEnvironment) wird nicht richtig verarbeitet. Wenn ich nil statt UserEnvironment übergebe, dann startet das Programm als SYSTEM hat aber auch dessen Umgebungsvariablen. Wenn ich aber versuche, den EnvironmentBlock zu erstellen (wie im Code dargestellt), dann startet das Programm gar nicht mehr. Wo liegt der Fehler? Bzw. wie geht das richtig?
Guck mal hier
http://blog.delphi-jedi.net/2008/04/...in-full-glory/
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
CodeX

Registriert seit: 30. Okt 2004
475 Beiträge
 
Delphi 12 Athens
 
#18

Re: Programm von Dienst starten lassen (Jetzt aber wirklich

  Alt 22. Mai 2008, 23:44
Du hast wohl alles schon mal gemacht, oder?

Habe ein wenig mit Deiner Funktion herumexperimentiert.

Hier meine Ergebnisse:

Wenn ich die Funktion genau so übernehme, dann wird die Umgebung von "Default User" genommen.
Zum Testen schaue ich immer über SHGetSpecialFolderLocation nach, welcher Bentzerordner aus dem Programm heraus angezeigt wird.

Nehme ich bei CreateEnvironmentBlock als zweiten Parameter 0, erhalte ich
C:\Dokumente und Einstellungen\Default User\Anwendungsdaten

Mit der nachfolgenden Änderung kommt das gewünschte
C:\Dokumente und Einstellungen\MyUser\Anwendungsdaten

Ich denke CreateEnvironmentBlock(@pEnv, 0, true); sollte deshalb geändert werden.

Das hier funktioniert als Ersatz:
Delphi-Quellcode:
//UserToken := TJwSecurityToken.CreateWTSQueryUserTokenEx(nil, WtsGetActiveConsoleSessionID); //nur ab XP :(
UserToken := TJwSecurityToken.CreateCompatibilityQueryUserToken(MAXIMUM_ALLOWED, 'explorer.exe'); //auch für 2000! :)
JwaWindows.CreateEnvironmentBlock(@pEnv, UserToken.TokenHandle, true);
Damit läuft das Programm als SYSTEM Anwendung aber mit der Umgebung des aktuellen Benutzers.


Bleibt noch eine Frage: Für Vista lässt sich da nichts mehr anpassen, oder? Da wird das Programm nämlich auf dem speziellen Desktop gestartet und entsprechend nicht normal angezeigt. Ja, ich weiß, das ist eine gewollte sicherheitsbedingte Änderung gewesen, aber vielleicht lässt sich da ja trotzdem noch was machen?
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#19

Re: Programm von Dienst starten lassen (Jetzt aber wirklich

  Alt 23. Mai 2008, 11:10
CreateWTSQueryUserTokenEx funktioniert nur unter Windows 2000. Unter XP kann es funkzen, muss aber nicht. Unter Vista funktioniert es nicht!

Damit dieser Desktopwechsel unter Vista nicht auftritt, musst man die TokenSessionID (Property) auf die jeweilige ID des Users setzen und dann damit das Programm starten.

Delphi-Quellcode:
var T,t2 : TJwSecurityToken;
   S : TStartupInfo;
   P : TProcessInformation;
begin
  T := TJwSecurityToken.CreateTokenEffective(MAXIMUM_ALLOWED);
  T2 := TJwSecurityToken.CreateDuplicateExistingToken(T.TokenHandle, MAXIMUM_ALLOWED);
  //
  T2.TokenSessionId := 2;

  ZeroMemory(@S, Sizeof(S));
  S.cb := sizeof(S);
  CreateProcessAsUser(T2.TokenHandle,'C:\Windows\system32\cmd.exe',nil,nil,nil,false, 0, nil, nil, S,P);
  ...
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
CodeX

Registriert seit: 30. Okt 2004
475 Beiträge
 
Delphi 12 Athens
 
#20

Re: Programm von Dienst starten lassen (Jetzt aber wirklich

  Alt 23. Mai 2008, 20:06
Zitat von Dezipaitor:
CreateWTSQueryUserTokenEx funktioniert nur unter Windows 2000. Unter XP kann es funkzen, muss aber nicht. Unter Vista funktioniert es nicht!
Okay, gut zu wissen. Wobei CreateWTSQueryUserTokenEx bei mir (wie in meinem auskommentierten Beispiel) nur mit WtsGetActiveConsoleSessionID Sinn gemacht hat. Da letzteres aber erst ab XP existiert, habe ich das eben doch nicht verwendet.
Aber letztlich tut
UserToken := TJwSecurityToken.CreateCompatibilityQueryUserToken(MAXIMUM_ALLOWED, 'explorer.exe'); ja vollkommen das, was es soll. Nachteile sehe ich keine.


Dein Vista-Beispiel verstehe ich allerdings nicht. Ich schreibe doch da nicht wirklich eine 2 als TokenSessionId hinein? Jedenfalls funktioniert das Codeschnippsel bei mir auch nicht. Ich vermute, es liegt an der 2, weiß aber nicht, was ich da sonst übergeben soll. Klärst Du mich da bitte auf?
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 5     12 34     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:56 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz