Einzelnen Beitrag anzeigen

Solstice Projekt

Registriert seit: 30. Aug 2020
5 Beiträge
 
#1

ChildProcess als AppContainer, wie?

  Alt 31. Aug 2020, 10:11
Grüsseuch!

Mein Problem ist wie im Titel aufgezeigt. Nachdem mein eigener Versuch nicht geklappt hat ...
... hab' ich mir von überall aus dem Internet die notwendigen KleinstTeile zusammen gesucht.

Das Ergebnis funktioniert zwar noch immer nicht,
aber die einzige FehlerMeldung kommt vom letzten Befehl, CreateProcessA.

Ich hoffte, mehrere paar Augen würden helfen,
oder dass vielleicht jemand mit Erfahrung weiß, warum es nicht funktioniert.

Win10, FreePascal 304, x64.

Delphi-Quellcode:
Program AppContainer;
Uses Windows,JWAWinNT,JWAWinError;

Type
  PROC_THREAD_ATTRIBUTE_LIST = Pointer;

  STARTUPINFOEX = packed record
    StartupInfo: TStartupInfo;
    lpAttributeList: PROC_THREAD_ATTRIBUTE_LIST;
  end;
  PSTARTUPINFOEX = ^STARTUPINFOEX;

   SECURITY_CAPABILITIES = Record
                        _AppSid: PSID;
                        _Caps : PSID_AND_ATTRIBUTES;
                        _CapCount : DWord;
                        Reserved : DWord;
                     End;
   PSECURITY_CAPABILITIES = ^SECURITY_CAPABILITIES;

Const
   EXTENDED_STARTUPINFO_PRESENT    = $00080000;
   PROC_THREAD_ATTRIBUTE_NUMBER = $0000FFFF;
   PROC_THREAD_ATTRIBUTE_THREAD = $00010000; // Attribute may be used with thread creation
   PROC_THREAD_ATTRIBUTE_INPUT = $00020000; // Attribute is input only
   PROC_THREAD_ATTRIBUTE_ADDITIVE = $00040000; // Attribute may be "accumulated," e.g. bitmasks, counters, etc.
   ProcThreadAttributeSecurityCapabilities = 9;
Var
   PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES : DWord_Ptr;
   SecCaps : SECURITY_CAPABILITIES;
   Caps : PSID_AND_ATTRIBUTES;
   Pi : PROCESS_INFORMATION;
   Si : STARTUPINFOEX;
   _Result : HResult;
   Size : Size_T;
   App : PSID;

function CreateAppContainerProfile(_containername,_displayname,_description : PCWStr; _capabilities : PSID_AND_ATTRIBUTES; _capabilitycount : DWord; _AppSid : PSID) : HResult; stdcall; external 'userenv.dll';
function DeriveAppContainerSidFromAppContainerName(_containername : PCWStr; _AppSid : PSID) : HResult; stdcall; external 'userenv.dll';
function FreeSid(_sid : PSID) : Pointer; stdcall; external 'advapi32.dll';

function InitializeProcThreadAttributeList(lpAttributeList: PROC_THREAD_ATTRIBUTE_LIST; dwAttributeCount, dwFlags: DWORD; lpSize: Pointer): Boolean;
   stdcall; external 'kernel32.dll';
function UpdateProcThreadAttribute(lpAttributeList: PROC_THREAD_ATTRIBUTE_LIST; dwFlags : DWord; _Attribute: DWord_Ptr; pValue:Pointer; cbSize: Cardinal; pPreviousValue: Pointer; pReturnSize: PCardinal) : Boolean;
   stdcall; external 'kernel32.dll';

Function ProcThreadAttributeValue(_number : DWord; _thread,_input,_additive : Boolean) : DWord_Ptr;
Begin
   ProcThreadAttributeValue := (((_number) and PROC_THREAD_ATTRIBUTE_NUMBER) or
                             (byte(_thread <> False) * PROC_THREAD_ATTRIBUTE_THREAD) or
                             (byte(_input <> FALSE) * PROC_THREAD_ATTRIBUTE_INPUT) or
                             (byte(_additive <> FALSE) * PROC_THREAD_ATTRIBUTE_ADDITIVE));
End;

Begin
   writeln; writeln; writeln;

   Si.StartupInfo.cb := sizeof(StartUpInfo);
   FillChar(SecCaps,sizeof(SecCaps),0);

   _Result := CreateAppContainerProfile('testa','testb','testc',Caps,0,@App);
   writeln('Error: ',GetLastError);
   SetLastError(0);
   writeln(_Result = S_OK,' ',_Result = E_ACCESSDENIED,' ',_Result = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), ' ',_Result = E_INVALIDARG);
   
   if (_Result = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) = True) then
   Begin
      _Result := DeriveAppContainerSidFromAppContainerName('testa',@App);
      writeln('Error: ',GetLastError);
      SetLastError(0);
      writeln(qword(App),' ',_Result = S_OK,' ',_Result = E_INVALIDARG);
   End;

   SecCaps._AppSid := App;

   writeln(InitializeProcThreadAttributeList(nil, 1, 0, @Size));
   writeln('Error: ',GetLastError);
   SetLastError(0);
   writeln(Size);

   GetMem(Si.lpAttributeList,Size);

   writeln(InitializeProcThreadAttributeList(@Si.lpAttributeList, 1, 0, @Size));
   writeln('Error: ',GetLastError);
   SetLastError(0);

   PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES := ProcThreadAttributeValue(ProcThreadAttributeSecurityCapabilities, FALSE, TRUE, FALSE);
   writeln(PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES);

   writeln(UpdateProcThreadAttribute(@Si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES,@SecCaps,sizeof(SecCaps),nil,nil));
   writeln('Error: ',GetLastError);
   SetLastError(0);

   writeln(CreateProcessA(nil,AnsiString('b:\pas\blabla.exe '), nil, nil, False,EXTENDED_STARTUPINFO_PRESENT, nil,nil,Si.startupinfo, Pi));
   writeln('Error: ',GetLastError);
   SetLastError(0);
End.
Ausgegeben wird:

Code:
Error: 0
FALSE FALSE TRUE FALSE
Error: 0
22821408 TRUE FALSE
FALSE
Error: 122
48
TRUE
Error: 0
131079
TRUE
Error: 0
FALSE
Error: 87
Anmerkung: Error 122 ist von der API so vorgesehen.

In der einen Variante, die ich fand, in welcher das Programm ausgeführt wird,
gab mir UpdateProc** einen Fehler 31... (ERROR_GEN_FAILURE, A device attached to the system is not functioning)
...mit dem ich nichts anfangen kann.

Zusätzlich sei gesagt, dass ich nicht mal mit Sicherheit sagen, ob *irgendein* Programm jemals als AppContainer ausgeführt wird.
Angeblich soll Calculator.exe ein Solches sein, aber ProcMon bestätigt dies nicht.

Fehler 87, übrigens, sagt aus, dass der Parameter inkorrekt ist.
Es sagt mir aber nicht, *welcher* Parameter inkorrekt ist.

Ich bitte um eure Hilfe.
Das Ziel: Einen KindProzess mit den geringstmöglichen Privilegien und Rechten, also sandboxed, ausführen.

Danke!


Edit: Irgendwie war ich nicht fertig.

Geändert von Solstice Projekt (31. Aug 2020 um 14:17 Uhr)
  Mit Zitat antworten Zitat