Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.53/47: Рейтинг темы: голосов - 47, средняя оценка - 4.53
0 / 0 / 0
Регистрация: 15.05.2016
Сообщений: 8

Запуск из службы

15.05.2016, 14:39. Показов 10087. Ответов 22
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте! Пытаюсь запустить из службы процесс в текущем пользователе из под другой учетной записи (Администратора). Процесс от текущего пользователя запускается, от имени Системы то же. Проблема только в запуске от другой учетной записи, процесс запускается, но он как бы мягко сказать "кастрирован"(Notepad при нажатии открыть не чего не происходит). Подскажите как добиться, как я понимаю у ACL разрешения процессу. Этот код партирован на Delphi, отрабатывает так же. Может и не правильно выразился. Чисто самоучка из Delphi, так что не судите строго.
Кликните здесь для просмотра всего текста

C++
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
#define _WIN32_WINNT 0x0501
 
#include <Windows.h>
#include <Userenv.h>
#include <AccCtrl.h>
#include <Aclapi.h>
#include <stdio.h>
#include <Sddl.h>
 
#define DESKTOP_ALL           (DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW | DESKTOP_CREATEMENU | DESKTOP_HOOKCONTROL | \
                            DESKTOP_JOURNALRECORD | DESKTOP_JOURNALPLAYBACK | DESKTOP_ENUMERATE | DESKTOP_WRITEOBJECTS | \
                            DESKTOP_SWITCHDESKTOP | STANDARD_RIGHTS_REQUIRED)
 
BOOL CreateMyDACL(SECURITY_ATTRIBUTES *);
 
wchar_t command[] = L"c:\\windows\\system32\\notepad.exe";
 
int main(int argc, char **argv)
{
    HANDLE usertoken;
    STARTUPINFO sinfo;
    PROCESS_INFORMATION pinfo;
    HDESK desktop;
    EXPLICIT_ACCESS explicit_access;
 
    BYTE buffer_token_user[SECURITY_MAX_SID_SIZE];
    PTOKEN_USER token_user = (PTOKEN_USER)buffer_token_user;
    PSECURITY_DESCRIPTOR existing_sd;
    SECURITY_DESCRIPTOR new_sd;
    PACL existing_dacl, new_dacl;
    BOOL dacl_present, dacl_defaulted;
    SECURITY_INFORMATION sec_info_dacl = DACL_SECURITY_INFORMATION;
    DWORD dw, size, dwSize;
    HWINSTA window_station;
    
    LPVOID lpEnv;
    WCHAR szUserProfile[256] = L"";
    PROFILEINFO prInfo;
 
    if (!LogonUser(L"Admin", L"", L"Pass", LOGON32_LOGON_BATCH, LOGON32_PROVIDER_DEFAULT, &usertoken))
    {
        printf("LogonUser: %u\n", GetLastError());
        return 1;
    }
 
    ZeroMemory(&prInfo, sizeof(PROFILEINFO));
    prInfo.dwSize = sizeof(PROFILEINFO);
    prInfo.lpUserName = L"Admin";
    prInfo.dwFlags = PI_NOUI;
 
    if (!LoadUserProfile(usertoken, &prInfo))
    {
        printf("LoadUserProfile: %u\n", GetLastError());
        return 1;
    }
    
    if (!GetTokenInformation(usertoken, TokenUser, buffer_token_user, sizeof(buffer_token_user), &dw))
    {
        printf("GetTokenInformation(TokenUser): %u\n", GetLastError());
        return 1;
    }
 
    window_station = GetProcessWindowStation();
    if (window_station == NULL)
    {
        printf("GetProcessWindowStation: %u\n", GetLastError());
        return 1;
    }
 
    if (!GetUserObjectSecurity(window_station, &sec_info_dacl, &dw, sizeof(dw), &size) && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
    {
        printf("GetUserObjectSecurity(window_station) call 1: %u\n", GetLastError());
        return 1;
    }
 
    existing_sd = malloc(size);
    if (existing_sd == NULL)
    {
        printf("malloc failed\n");
        return 1;
    }
 
    if (!GetUserObjectSecurity(window_station, &sec_info_dacl, existing_sd, size, &dw))
    {
        printf("GetUserObjectSecurity(window_station) call 2: %u\n", GetLastError());
        return 1;
    }
 
    if (!GetSecurityDescriptorDacl(existing_sd, &dacl_present, &existing_dacl, &dacl_defaulted))
    {
        printf("GetSecurityDescriptorDacl(window_station): %u\n", GetLastError());
        return 1;
    }
 
    if (!dacl_present)
    {
        printf("no DACL present on window station\n");
        return 1;
    }
 
    explicit_access.grfAccessMode = SET_ACCESS;
    explicit_access.grfAccessPermissions = WINSTA_ALL_ACCESS | READ_CONTROL;
    explicit_access.grfInheritance = NO_INHERITANCE;
    explicit_access.Trustee.pMultipleTrustee = NULL;
    explicit_access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
    explicit_access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
    explicit_access.Trustee.TrusteeType = TRUSTEE_IS_USER;
    explicit_access.Trustee.ptstrName = (LPTSTR)token_user->User.Sid;
 
    dw = SetEntriesInAcl(1, &explicit_access, existing_dacl, &new_dacl);
    if (dw != ERROR_SUCCESS) {
        printf("SetEntriesInAcl(window_station): %u\n", dw);
        return 1;
    }
 
    if (!InitializeSecurityDescriptor(&new_sd, SECURITY_DESCRIPTOR_REVISION))
    {
        printf("InitializeSecurityDescriptor(window_station): %u\n", GetLastError());
        return 1;
    }
 
    if (!SetSecurityDescriptorDacl(&new_sd, TRUE, new_dacl, FALSE))
    {
        printf("SetSecurityDescriptorDacl(window_station): %u\n", GetLastError());
        return 1;
    }
 
    if (!SetUserObjectSecurity(window_station, &sec_info_dacl, &new_sd))
    {
        printf("SetUserObjectSecurity(window_station): %u\n", GetLastError());
        return 1;
    }
 
    free(existing_sd);
    LocalFree(new_dacl);
 
    desktop = GetThreadDesktop(GetCurrentThreadId());
    if (desktop == NULL)
    {
        printf("GetThreadDesktop: %u\n", GetLastError());
        return 1;
    }
 
    if (!GetUserObjectSecurity(desktop, &sec_info_dacl, &dw, sizeof(dw), &size) && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
    {
        printf("GetUserObjectSecurity(desktop) call 1: %u\n", GetLastError());
        return 1;
    }
 
    existing_sd = malloc(size);
    if (existing_sd == NULL)
    {
        printf("malloc failed\n");
        return 1;
    }
 
    if (!GetUserObjectSecurity(desktop, &sec_info_dacl, existing_sd, size, &dw))
    {
        printf("GetUserObjectSecurity(desktop) call 2: %u\n", GetLastError());
        return 1;
    }
 
    if (!GetUserObjectSecurity(desktop, &sec_info_dacl, existing_sd, 4096, &dw))
    {
        printf("GetUserObjectSecurity: %u\n", GetLastError());
        return 1;
    }
 
    if (!GetSecurityDescriptorDacl(existing_sd, &dacl_present, &existing_dacl, &dacl_defaulted))
    {
        printf("GetSecurityDescriptorDacl: %u\n", GetLastError());
        return 1;
    }
 
    if (!dacl_present)
    {
        printf("no DACL present\n");
        return 1;
    }
 
    explicit_access.grfAccessMode = SET_ACCESS;
    explicit_access.grfAccessPermissions = GENERIC_ALL | DESKTOP_ALL;
    explicit_access.grfInheritance = NO_INHERITANCE;
    explicit_access.Trustee.pMultipleTrustee = NULL;
    explicit_access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
    explicit_access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
    explicit_access.Trustee.TrusteeType = TRUSTEE_IS_USER;
    explicit_access.Trustee.ptstrName = (LPTSTR)token_user->User.Sid;
 
    dw = SetEntriesInAcl(1, &explicit_access, existing_dacl, &new_dacl);
    if (dw != ERROR_SUCCESS) {
        printf("SetEntriesInAcl: %u\n", dw);
        return 1;
    }
 
    if (!InitializeSecurityDescriptor(&new_sd, SECURITY_DESCRIPTOR_REVISION))
    {
        printf("InitializeSecurityDescriptor: %u\n", GetLastError());
        return 1;
    }
 
    if (!SetSecurityDescriptorDacl(&new_sd, TRUE, new_dacl, FALSE))
    {
        printf("SetSecurityDescriptorDacl: %u\n", GetLastError());
        return 1;
    }
 
    if (!SetUserObjectSecurity(desktop, &sec_info_dacl, &new_sd))
    {
        printf("SetUserObjectSecurity(window_station): %u\n", GetLastError());
        return 1;
    }
 
    free(existing_sd);
    LocalFree(new_dacl);
 
    
    dwSize = sizeof(szUserProfile) / sizeof(WCHAR);
    if (!GetUserProfileDirectory(usertoken, szUserProfile, &dwSize))
    {
        printf("GetUserProfileDirectory: %u\n", GetLastError());
        return 1;
    }
    
    if (!CreateEnvironmentBlock(&lpEnv, usertoken, FALSE))
    {
        printf("CreateEnvironmentBlock: %u\n", GetLastError());
        return 1;
    }
    //Здесь идет попытка передать SECURITY_ATTRIBUTES CreateProcessAsUserW
    SECURITY_ATTRIBUTES  sa;
 
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = FALSE;
 
    if (!CreateMyDACL(&sa))
    {
        // Error encountered; generate message and exit.
        printf("Failed CreateMyDACL\n");
        exit(1);
    }
 
    ///Здесь попытка подмены DefaultDacl в токене пользователя
        PSECURITY_DESCRIPTOR psd;
    ULONG cbsd = 0;
    TCHAR * szS = TEXT("D:")       // Discretionary ACL
        TEXT("(A;OICI;GA;;;BG)")     // Deny access to 
                                     // built-in guests
        TEXT("(A;OICI;GA;;;AN)")     // Deny access to 
                                     // anonymous logon
        TEXT("(A;OICI;GRGWGX;;;AU)") // Allow 
                                     // read/write/execute 
                                     // to authenticated 
                                     // users
        TEXT("(A;OICI;GA;;;BA)");    // Allow full control 
                                     // to administrators
    
    
    ConvertStringSecurityDescriptorToSecurityDescriptor(szS, SDDL_REVISION, &psd, &cbsd);
    
    BOOL fDaclPresent = FALSE, fDaclDef = FALSE;
    TOKEN_DEFAULT_DACL dacl;
    GetSecurityDescriptorDacl(psd, &fDaclPresent, &dacl.DefaultDacl, &fDaclDef);
    
    SetTokenInformation(usertoken, TokenDefaultDacl, &dacl, sizeof(dacl));
 
    ZeroMemory(&sinfo, sizeof(sinfo));
    sinfo.cb = sizeof(sinfo);
    sinfo.lpDesktop = L"winsta0\\default";
    ZeroMemory(&pinfo, sizeof(pinfo));
 
    /*if (!CreateProcessWithTokenW(usertoken, LOGON_WITH_PROFILE, command, command, CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT, lpEnv, szUserProfile, &sinfo, &pinfo))
    {
        printf("CreateProcess: %u\n", GetLastError());
        return 1;
    }*/
    if (!CreateProcessAsUserW(usertoken, command, command, &sa, &sa, NULL, CREATE_DEFAULT_ERROR_MODE | CREATE_UNICODE_ENVIRONMENT, lpEnv, szUserProfile, &sinfo, &pinfo))
    {
        printf("CreateProcess: %u\n", GetLastError());
        return 1;
    }
    DestroyEnvironmentBlock(lpEnv);
    if (!UnloadUserProfile(usertoken, prInfo.hProfile))
    {
        printf("UnloadUserProfile: %u\n", GetLastError());
        return 1;
    }
    //RevertToSelf;
    CloseHandle(usertoken);
    CloseHandle(pinfo.hProcess);
    CloseHandle(pinfo.hThread);
    
    if (NULL != LocalFree(sa.lpSecurityDescriptor))
    {
        // Error encountered; generate message and exit.
        printf("Failed LocalFree\n");
        exit(1);
    }
 
    return 0;
}
 
BOOL CreateMyDACL(SECURITY_ATTRIBUTES * pSA)
{
    // Define the SDDL for the DACL. This example sets 
    // the following access:
    //     Built-in guests are denied all access.
    //     Anonymous logon is denied all access.
    //     Authenticated users are allowed 
    //     read/write/execute access.
    //     Administrators are allowed full control.
    // Modify these values as needed to generate the proper
    // DACL for your application. 
    TCHAR * szSD = TEXT("D:")       // Discretionary ACL
        TEXT("(A;OICI;GA;;;BG)")     // Deny access to 
                                     // built-in guests
        TEXT("(A;OICI;GA;;;AN)")     // Deny access to 
                                     // anonymous logon
        TEXT("(A;OICI;GRGWGX;;;AU)") // Allow 
                                     // read/write/execute 
                                     // to authenticated 
                                     // users
        TEXT("(A;OICI;GA;;;BA)");    // Allow full control 
                                     // to administrators
 
    if (NULL == pSA)
        return FALSE;
 
    return ConvertStringSecurityDescriptorToSecurityDescriptor(
        szSD,
        SDDL_REVISION_1,
        &(pSA->lpSecurityDescriptor),
        NULL);
}

0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.05.2016, 14:39
Ответы с готовыми решениями:

Запуск процесса из службы
Есть служба, работающая от SYSTEM, которой разрешено взаимодействовать с рабочим столом. Она запускает &quot;notepad.exe&quot; от имени...

Создание и запуск службы
Товарищи помогите пожалуйста разобраться с проблемой запуска службы Windows. При попытке запуска выдаёт ошибку -...

Остановка и запуск службы(сервиса) из другой службы или из приложения не используя консоль
Добрый день! Компилятор Embarcadero XE8 Скажите, как можно остановить и запустить некую службу(сервис) зная его имя (например...

22
Эксперт С++
 Аватар для _lunar_
3701 / 2836 / 451
Регистрация: 03.05.2011
Сообщений: 5,193
Записей в блоге: 21
24.10.2021, 03:03
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Morgot Посмотреть сообщение
Какие апи для старта процесса из сервиса?
CreateService с прямым указанием имени учетки TEXT("NT AUTHORITY\\NetworkService"), TEXT("NT AUTHORITY\\LocalService") или TEXT(".\\LocalSystem")
затем StartService и ControlService(... SERVICE_CONTROL_STOP ...) -> сервис закрывается, процесс им порожденный остаётся.
это всё утрировано, функции чтобы это всё провернуть у меня колоссальных размеров.

но тут есть два аспекта:
1. запускаемый процесс должен стартовать как системный
2. для NetworkService и LocalService исполняемый файл должен находится в системных папках (Windows\System32), либо в общих для всех учеток папках _tgetenv(TEXT("PUBLIC"))
2
0 / 0 / 0
Регистрация: 16.03.2023
Сообщений: 1
24.03.2024, 18:09
Уважаемые Гуру

Убежденный говорит что необходимо добавить Sid
2. Токен запущенного приложения почему-то не содержит SID группы "Локальный вход" (S-1-2-0).

Как его правильно добавить? Пробую это сделать функцией AdjustTokenGroups следующим образом:

C++
1
2
3
4
5
6
7
TOKEN_GROUPS TokenGroups, OldTokenGroups;
DWORD OldSize2 = 0;
OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hProcessToken);
ConvertStringSidToSid("S-1-2-0",  &TokenGroups.Groups[0].Sid);
TokenGroups.GroupCount = 1;
TokenGroups.Groups[0].Attributes = SE_GROUP_ENABLED;
AdjustTokenGroups(hProcessToken, FALSE,  &TokenGroups, sizeof(TokenGroups), &OldTokenGroups, &OldSize2);
Все проходит без ошибок, но группа не добавляется процессу.

Добавлено через 5 часов 57 минут
Пробовал добавлять Sid через функцию SetTokenInformation - то же не добавляет. И не ругается. Кто-нибудь может подскажет рабочий метод?

Добавлено через 21 минуту
И так то же не работает...((

C++
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
TOKEN_GROUPS TokenGroupss, OldTokenGroups;
PTOKEN_GROUPS  ptg;
DWORD dwLength = 0;
PTOKEN_GROUPS groups;
PSID group1,group2;
PSID_AND_ATTRIBUTES pSid;
ConvertStringSidToSidA("S-1-5-32-545", &group2);
ConvertStringSidToSidA("S-1-5-6", &group1);
groups = (PTOKEN_GROUPS)GetTokenInformation(hNewToken, TokenGroups, ptg, dwLength, &dwLength);
pSid = groups->Groups;
for (int i = 0; i < groups->GroupCount; ++i, pSid++)
    {
        PISID piSid = (PISID)pSid->Sid;
        if (piSid->SubAuthority[piSid->SubAuthorityCount - 1] ==
                    DOMAIN_ALIAS_RID_USERS) {
            pSid->Sid = group1;
            pSid->Attributes = SE_GROUP_ENABLED;
        }
        else if (piSid->SubAuthority[piSid->SubAuthorityCount - 1] ==
                        SECURITY_WORLD_RID) {
                pSid->Sid = group2;
                pSid->Attributes = SE_GROUP_ENABLED;
            }
        else {
            pSid->Attributes &= ~SE_GROUP_USE_FOR_DENY_ONLY;
            pSid->Attributes &= ~SE_GROUP_ENABLED;
        }
    }
0
Чугунные скороходы
 Аватар для ARRAYBOW
17 / 16 / 3
Регистрация: 25.12.2022
Сообщений: 367
09.05.2024, 19:02
Цитата Сообщение от max380 Посмотреть сообщение
Понял...не то.
У notepad из system32 и SYSWOW64 разная разрядность, может из-за нехватка памяти, укажи точный путь (%WINDIR%\system32\notepad.exe)

Добавлено через 1 час 21 минуту
Цитата Сообщение от ARRAYBOW Посмотреть сообщение
может из-за нехватка памяти
* может из-за этого нехватка памяти
Неправильно написал)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
09.05.2024, 19:02

D7, запуск службы из под службы, возможно ли такое?
Hello All. Необходимо написать службу которая будет через определенное время (каждые 5 минут) проверять существует (зарегистрирована) ли...

Запуск службы
доброго времени суток. при попытке запуска службы Mapшpyтизaция и yдaлeнный дocтyп вылезло вот что!!! что это подскажите!!!!!!

Запуск приложения из службы
Здарствуйте програмисты, помогите решить такой вопрос. У меня есть написаная мной служба. Я должен сделать так чтобы службы вызывала...

Запуск процесса из службы
Подскажите у меня проект службы Windows, в настройках службы стоит галка &quot;Разрешить взаимодействие с рабочим столом&quot; но при этом...

Запуск приложения из службы
Здорово ребята. Почему не работает этот кусок кода в windows службе? Process p = new Process(); p.StartInfo.FileName =...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
23
Ответ Создать тему
Новые блоги и статьи
Транслитерация текста с кириллицы на латиницу (вариант №2)
Maks 13.11.2026
Обновленная версия ранее созданной обработки. Добавлено: - Проверка исходного текста на кириллицу, через обращение к стандартной функции "ТолькоКириллицаВСтроке" из общего модуля. . .
Часы с термометром и праздничным календарем
yariko 12.11.2026
Сегодня мы рассмотрим как можно сделать отличные многофункциональные часы. Итак, поставим конкретную задачу: разработать часы с календарем, двумя термодатчиками, выводом поздравительных сообщений. . .
Транслитерация текста с кириллицы на латиницу (вариант №1)
Maks 11.11.2026
Решил облегчить жизнь себе и коллегам админам при создании электронных почтовых ящиков для пользователей, в результате написал обработку "Транслитерация текста" с кириллицы на латиницу, а в ней. . .
Книги по геймдизайну, левел-дизайну, игровым механикам и проектированию игрового опыта
8Observer8 08.11.2026
Содержание блога | English Version 1. 2003 - 06 - Designing Virtual Worlds (1st Edition) Автор: Richard A. Bartle | Объем: 768 стр. Ссылки: Amazon . . .
Родители токсичные абьюзеры по отношению к своим детям ругают их оскорбляют не любят
zorxor 08.11.2026
Жить в атмосфере постоянных оскорблений, критики и холодности со стороны родителей — это тяжелое и болезненное испытание, которое оставляет глубокие эмоциональные раны. Токсичное и абьюзивное. . .
Как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Ответ от Джемени ИИ.
zorxor 08.11.2026
Джемени, как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Многие люди, возвращаясь домой, сразу переодеваются в максимально свободную одежду или вовсе предпочитают. . .
Паттерн очереди действий/команд (Action / Command Queue). Система очереди действий и кат-сцен с SDL3 Callbacks, cglm и OpenGL
8Observer8 07.11.2026
Содержание блога | English Version Руководство для начинающих по реализации паттерна очереди действий/ команд (Action / Command Queue) на C++ (C++20) с использованием официального SDL3 Callbacks. . .
Проверка полного ФИО в типовом справочнике
Maks 07.11.2026
Решение реализовано в конфигурации КА2, на примере справочника "КонтактныеЛицаПартнеров". Задача: Запрет инициалов. Не допускаеть использование сокращений вида "И. И. ", "И. И. ", "И И" и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru