Текущий архив: 2008.06.15;
Скачать: CL | DM;
Вниз
CreateProcessAsUser не открисовывает окно запущеного приложения Найти похожие ветки
← →
DelphiN! © (2007-09-27 07:45) [0]Запускаю процесс посредством функции CreateProcessAs следующим образом :
function MyCreateProcess(Path,User,Pass: String): Boolean;
const
SE_ASSIGNPRIMARYTOKEN_NAME = "SeAssignPrimaryTokenPrivilege";
SE_INCREASE_QUOTA_NAME = "SeIncreaseQuotaPrivilege";
SE_TCB_NAME = "SeTcbPrivilege";
function EnablePrivilege(lpPrivilegeName: PChar):Boolean;
var
hToken: dword;
NameValue: Int64;
tkp: TOKEN_PRIVILEGES;
ReturnLength: dword;
begin
Result:=false;
OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken);
if not LookupPrivilegeValue(nil, lpPrivilegeName, NameValue) then
begin
CloseHandle(hToken);
exit;
end;
tkp.PrivilegeCount := 1;
tkp.Privileges[0].Luid := NameValue;
tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, false, tkp, SizeOf(TOKEN_PRIVILEGES), tkp, ReturnLength);
if GetLastError() <> ERROR_SUCCESS then
begin
CloseHandle(hToken);
exit;
end;
Result:=true;
CloseHandle(hToken);
end;
var
sti:TStartupInfo;
pi:TProcessInformation;
usertoken:THandle;
st:pointer;
Params,Clean_Path: String;
begin
if not LogonUser(PChar(User),".",PChar(Pass),LOGON32_LOGON_INTERACTIVE ,LOGON32_PROVIDER_DEFAULT,usertoken) then
begin
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER+FORMAT_MESSAGE_FROM_SYSTEM,0,GetLastError,LANG_NEUTRAL,@st,0,0);
ShowMessage(pchar(st));
end;
ZeroMemory(@sti,Sizeof(sti));
EnablePrivilege(SE_INCREASE_QUOTA_NAME);
EnablePrivilege(SE_ASSIGNPRIMARYTOKEN_NAME);
sti.wShowWindow := 1;
Clean_Path := ExtractPathWithOutParams(Path);
Params := ExtractPathParams(Path);
if not CreateProcessAsUser(usertoken,PChar(Clean_Path),PChar(Params),0,0,false,0,0,0,st i,pi) then
begin
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER+FORMAT_MESSAGE_FROM_SYSTEM,0,GetLastError,LANG_NEUTRAL,@st,0,0);
ShowMessage(pchar(st));
end;
end;
MyCreateProcess("C:\WINDOWS\SYSTEM32\CALC.EXE","Admin","pass");
Данный код запускается калькулятор WINDOWS, однако его окно не прорисовано.
Как решить данную проблему?
← →
Сергей М. © (2007-09-27 09:00) [1]By default, the new process is non-interactive, that is, it runs on a desktop that is not visible and cannot receive user input.
см. Get/SetProcessWindowStation
← →
Игорь Шевченко © (2007-09-27 10:08) [2]В startupinfo имя desktop-а прописать не поможет ?
← →
DelphiN! © (2007-09-27 10:46) [3]
> Игорь Шевченко © (27.09.07 10:08) [2]
Не помогает
Мне необходимо запустить процесс из службы с правами пользовательского аккаунта, служба работает под пользователем SYSTEM.
Данный способ запускает процесс из службы, под пользовательским аккаунтом (смотрел в диспетчере задач), однако у запущенного процесса нет привелегий пользовательского аккаунта, так как он как и служба не может обращаться к сетевым ресурсам(проверял на процессе у которого нет окна).
С этим кодом бьюсь уже неделю, может быть можно как то иначе решить данную проблему? Или что мне нужно сделать с данным кодом чтобы он работал как полагается?
CreateProcessWithLogonW из под службы к сожалению не работает
Нашел пример использования функции CreateProcessAsUser на C, однако к сожалению в С я не силен, а пример достаточно запутанный и громоздкий (
http://win32.mvps.org/security/lu_cpau_gui.cpp
Также есть пример на сайте майкрософта, однако он не меньшего размера и тоже на С.
http://msdn2.microsoft.com/en-us/library/aa379608.aspx
Нашел перевод майкросовтовского примера на Делфи, однако переведено лишь половина кода, далее сообщение обрывается (
http://www.delphikingdom.com/asp/answer.asp?IDAnswer=1899
Больше в интернете примеров на Делфи не нашел (
← →
clickmaker © (2007-09-27 11:51) [4]
> CreateProcessWithLogonW из под службы к сожалению не работает
то есть?
← →
DelphiN! © (2007-09-27 11:57) [5]
> clickmaker © (27.09.07 11:51) [4]
Если служба работает под пользователем SYSTEM при попытки запустить процесс под другим пользователем через функцию CreateProcessWithLogonW функция возвращает ошибку 5 - Access Denied
из MSDN :
Windows XP SP2 and Windows Server 2003: You cannot call CreateProcessWithLogonW from a process that is running under the LocalSystem account, because the function uses the logon SID in the caller token, and the token for the LocalSystem account does not contain this SID. As an alternative, use the CreateProcessAsUser and LogonUser functions.
← →
Eraser © (2007-09-27 12:43) [6]примерно так
stUser: // Текущая терминальная сессия с правами текущего юзера.
begin
if (Win32MajorVersion = 5) and (Win32MinorVersion = 0) then
begin
// 2K: вызов другово способа
Exit;
end
else
begin
// WinXP и выше: используем спец. ф-цию.
if not WTSQueryUserToken(SessionId, hToken) then
begin
dwReturned := GetLastError;
if dwReturned = ERROR_NOT_LOGGED_ON then
Exit;
AppendLog("Error #16 @" + IntToStr(GetLastError));
Exit;
end;
end;
try
if not DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, nil, SecurityIdentification,
TokenPrimary, hNewToken) then
begin
AppendLog("Error #17 @" + IntToStr(GetLastError));
Exit;
end;
if not CreateEnvironmentBlock(lpEnvironment, hNewToken, false) then
begin
AppendLog("Error #18 @" + IntToStr(GetLastError));
Exit;
end;
// Запуск процесса.
si.lpDesktop := "winsta0\default";
if CreateProcessAsUserW(hNewToken, nil, PWideChar(APath),
nil, nil, false, CREATE_UNICODE_ENVIRONMENT,
lpEnvironment, nil, si, pi) then
begin
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
end
else
begin
AppendLog("Error #19 @" + IntToStr(GetLastError));
Exit;
end;
finally
if hToken <> 0 then
CloseHandle(hToken);
if hNewToken <> 0 then
CloseHandle(hNewToken);
if lpEnvironment <> nil then
DestroyEnvironmentBlock(lpEnvironment);
end;
end;
← →
Eraser © (2007-09-27 12:45) [7]в зависимости от ОС механизм запуска может сильно меняться, но тем не менее обрати внимание на CreateEnvironmentBlock.
← →
DelphiN! © (2007-09-28 08:21) [8]
> Eraser © (27.09.07 12:45) [7]
Громадное спасибо! Все работает!
← →
DelphiN! © (2007-09-28 08:47) [9]Нет, к сожалению работает не все.
Использую следующий код для запуска приложений из под LocalSystem аккаунта:
function WTSQueryUserToken(SessionId:pDWord;phToken:pHandle):bool;stdcall;external "wtsapi32.dll";
procedure StartAsUser(const CmdLine: string);
var
h: THandle;
s: _StartupInfoA;
p: _Process_Information;
begin
WTSQueryUserToken(nil, @h);
s.cb := SizeOf(s);
s.lpReserved:=nil;
s.lpDesktop:=PChar("");
s.lpTitle:=nil;
s.dwFlags:=STARTF_USESHOWWINDOW;
s.wShowWindow:=SW_Show;
s.cbReserved2:=0;
s.lpReserved2:=nil;
CreateProcessAsUser(h, nil, PChar(CmdLine),
nil, nil, false, CREATE_DEFAULT_ERROR_MODE, nil, nil, s, p);
CloseHandle(p.hThread);
CloseHandle(p.hProcess);
CloseHandle(h);
end;
StartAsUser("C:\Runer\Runer.exe RunAs::Admin::pass,Program::C:\WINDOWS\REGEDIT.EXE");
Программа Runer.exe запускается и пытается запустить программу C:\WINDOWS\REGEDIT.EXE через ф-ию CreateProcessWithLogonW под указанным ей в параметрах пользователем, однако при этом Runer.exe выдает ошибку
---------------------------
Runer: Runer.exe - Ошибка приложения
---------------------------
Инструкция по адресу "0x7c913144" обратилась к памяти по адресу "0x00404c55". Память не может быть "written".
"ОК" -- завершение приложения
"Отмена" -- отладка приложения
---------------------------
ОК Отмена
---------------------------
Если выполнить команду C:\Runer\Runer.exe RunAs::Admin::pass,Program::C:\WINDOWS\REGEDIT.EXE из командной строки под тем же пользователем под которым Runer.exe запускается через ф-ию StartAsUser, то программа выполняется без ошибок.
Вот процедура запуска приложения, которую использует Runer.exe
function MyCreateProcess(Path,WorkingDir,User,Pass: String; Alias: String): Boolean;
var
sa: STARTUPINFO;
pi: PROCESS_INFORMATION;
WLogin,WPass,WPath,WFolder: PWideChar;
Folder: String;
lz: Cardinal;
err: array[0..512] of Char;
begin
ZeroMemory(@Sa,Sizeof(sa));
sa.cb := SizeOf(tstartupinfo);
sa.dwFlags := STARTF_USESHOWWINDOW;
sa.wShowWindow := SW_SHOWDEFAULT;
sa.lpReserved := nil;
sa.lpDesktop := nil;
sa.lpTitle := nil;
{New(WLogin); StringToWideChar(WinAccountLogin,WLogin,Length(WinAccountLogin)+1);
New(WPass); StringToWideChar(WinAccountPass,WPass,Length(WinAccountPass)+1);
New(WPath); StringToWideChar(Path,WPath,Length(Path)+1);
Folder := MyExtractFilePath(Path); New(WFolder); StringToWideChar(Folder,WFolder,Length(Folder)+1); }
GetMem(WLogin, Length(User) * SizeOf(WLogin) + 1);
StringToWideChar(User, WLogin, Length(User) * SizeOf(WLogin) + 1);
GetMem(WPass, Length(Pass) * SizeOf(WPass) + 1);
StringToWideChar(Pass, WPass, Length(Pass) * SizeOf(WPass) + 1);
GetMem(WPath, Length(Path) * SizeOf(WPath) + 1);
StringToWideChar(Path, WPath, Length(Path) * SizeOf(WPath) + 1);
Folder := ExtractFilePath(Path);
GetMem(WFolder, Length(Folder) * SizeOf(WFolder) + 1);
StringToWideChar(Folder, WFolder, Length(Folder) * SizeOf(WFolder) + 1);
CreateProcessWithLogonW(WLogin, nil, WPass, 0,
nil, WPath,0, nil, nil, sa, pi);
err := "";
lz := GetLastError;
if lz <> 0 then
begin
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nil, lz, 0, @err, 512, nil);
MessageBox(0,PChar(String("Error "+IntToStr(lz)+". "+err)),"",0);
end;
Dispose(WLogin);
Dispose(WPass);
Dispose(WPath);
Dispose(WFolder);
end;
end;
В чем может быть дело?
← →
Eraser © (2007-09-28 12:08) [10]
> DelphiN! © (28.09.07 08:47) [9]
> function WTSQueryUserToken(SessionId:pDWord;phToken:pHandle):
> bool;stdcall;external "wtsapi32.dll";
function WTSQueryUserToken(SessionId: ULONG; var phToken: HANDLE): BOOL; stdcall;
найди 10 отличий, особенно обрати внимение на 1 параметр.
> WTSQueryUserToken(nil, @h);
?
PS
на всякий случай:
где именно
> Runer.exe выдает ошибку
?
← →
DelphiN! © (2007-09-28 13:48) [11]
> Eraser © (28.09.07 12:08) [10]
Поправил на
function WTSQueryUserToken(SessionId:ULONG;phToken:pHandle):bool;stdcall;external "wtsapi32.dll";
WTSQueryUserToken(0, @h);
Результат тот же ...
Где именно Runer.exe выдает ошибку сказать не могу, но видимо при вызове функции CreateProcessWithLogonW, так как другие приложения, не использующие данную функцию ошибки при запуске не выдают ...
← →
Eraser © (2007-09-28 14:41) [12]
> DelphiN! © (28.09.07 13:48) [11]
почти наверняка в какой-то из параметров не правильный параметр передается, инче бы такой ошибки не было. т.е. ошибка по сути формальная скорее всего.
← →
DelphiN! © (2007-09-28 14:52) [13]
> Eraser © (28.09.07 14:41) [12]
Ошибка не формальная, так как ф-ия CreateProcessWithLogonW не выполняется
← →
Eraser © (2007-09-28 14:54) [14]
> DelphiN! © (28.09.07 14:52) [13]
а что выполняется? неужели сложно отладчиком пройтись или хотя бы простенькое логирование сделать?
← →
SLoW.AlfaMoon.Com (2007-09-28 16:58) [15]Вот эта функция
procedure RunApp(str: pchar);
var
struc1: PSTARTUPINFO;
struc2: PROCESS_INFORMATION;
begin
getmem(struc1, sizeof(TSTARTUPINFO));
struc1^.lpDesktop := PChar("winsta0\default");
struc1^.dwFlags := STARTF_USESHOWWINDOW;
struc1^.wShowWindow := SW_SHOW;
CreateProcess(nil, str, nil, nil, False,
NORMAL_PRIORITY_CLASS,
nil, nil, struc1^, struc2);
end;
Нормально все запускает. Без геморроев.
← →
Eraser © (2007-09-28 17:08) [16]только с утечкой памяти.
← →
SLoW.AlfaMoon.Com (2007-10-01 11:02) [17]
> Eraser
только с утечкой памяти.
Не спорю. Впрочем, в качестве наброска идеи сойдет.
← →
User1999 (2007-10-04 01:51) [18]WinExec(eui.dll_)
← →
SLoW.AlfaMoon.Com (2007-10-04 11:32) [19]User1999 (04.10.07 01:51) [18]
WinExec(eui.dll_)
Расшифруйте. Хотя, на 99% уверен, что Вы не поняли вопроса или не знакомы с этой областью.
Страницы: 1 вся ветка
Текущий архив: 2008.06.15;
Скачать: CL | DM;
Память: 0.53 MB
Время: 0.015 c