Hola tengo problemas al extraer la informacón de la lista de procesos ejecutados por el usuario q esten elevados a nivel adnimistrador en w10
Obtener lista de procesos ejecutados como administrador
#1
Escrito 02 febrero 2017 - 03:32
#2
Escrito 02 febrero 2017 - 05:57
Esta función te devuelve del usuario y dominio que creó un proceso:
function GetUserAndDomainFromPID(ProcessId: Cardinal; var User, Domain: String): boolean; var snu: SID_NAME_USE; pProcessInfo: TA_WTS_PROCESS_INFO; nProc,UserSize, DomainSize: Cardinal; begin Result:= false; nProc:= 0; UserSize:= 0; DomainSize:= 0; if WTSEnumerateProcessesA(0, 0, 1, PWTS_PROCESS_INFO(pProcessInfo), nProc) then begin repeat dec(nProc) until (nProc <= 0) or (ProcessId = pProcessInfo[nProc].ProcessId); LookupAccountSid(nil, pProcessInfo[nProc].pUserSid, nil, UserSize, nil, DomainSize, snu); if (UserSize <> 0) or (DomainSize <> 0) then begin SetLength(User, UserSize); SetLength(Domain, DomainSize); Result:= LookupAccountSid(nil, pProcessInfo[nProc].pUserSid, @User[1], UserSize, @Domain[1], DomainSize, snu); end; WTSFreeMemory(pProcessInfo); end; end;
Esta función te informa si el usuario del proceso actual es administrador:
function IsAdmin: boolean; var scManager: SC_HANDLE; begin scManager:= OpenSCManagerW(nil, nil, SC_MANAGER_ALL_ACCESS); if scManager <> 0 then CloseServiceHandle(scManager); Result:= scManager <> 0; end;
Esta otra te permite saber si un proceso fue creado por un usuario que pertenece a un grupo, está escrita en C:
BOOL BelongGroup(char *Group, int PID) { HANDLE hProcess, hAccessToken; UCHAR InfoBuffer[1024]; PTOKEN_GROUPS ptgGroups = (PTOKEN_GROUPS)InfoBuffer; DWORD dwInfoBufferSize; SID_NAME_USE snuInfo; UCHAR szAccountName[256], szDomainName[256]; DWORD dwAccountNameSize, dwDomainNameSize; UINT x; hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, PID); if(!OpenProcessToken(hProcess,TOKEN_READ,&hAccessToken)) return(FALSE); if(!GetTokenInformation(hAccessToken,TokenGroups,InfoBuffer, 1024, &dwInfoBufferSize)) return(FALSE); for(x=0;x<ptgGroups->GroupCount;x++){ dwAccountNameSize = 256; dwDomainNameSize = 256; LookupAccountSid(NULL, ptgGroups->Groups[x].Sid, szAccountName, &dwAccountNameSize, szDomainName, &dwDomainNameSize, &snuInfo); if(!strcmp(szAccountName, Group) && !strcmp(szDomainName,"BUILTIN")) return(TRUE); } return(FALSE); }
Usada de esta forma, sabrás si es del grupo de administradores:
if(BelongGroup("Administradores", 10376)) Beep(1000, 100);
Saludos.
#3
Escrito 03 febrero 2017 - 07:29
No e probado el codigo todavia pero por lo q entendi de lo q explica usted eso me devuelve si el usuario con q se ejecuta es administrador o no, lo q necesito es saber si la aplicacion fue elevada a nivel de administrador con "Ejecutar como administrador", en el administrador de tareas te da esa informacion si es elevada o no, el usuario q va a ser esto siempre va ser del grupo administrativo. Ahora voy a porbar su codigo.
Saludos
#4
Escrito 03 febrero 2017 - 09:45
Buscando encontre esta función creo q es lo q necesito
function RunningAsAdmin: boolean; var hToken, hProcess: THandle; pTokenInformation: pointer; ReturnLength: DWord; TokenInformation: TTokenElevation; begin hProcess := GetCurrentProcess; try if OpenProcessToken(hProcess, TOKEN_QUERY, hToken) then try TokenInformation.TokenIsElevated := 0; pTokenInformation := @TokenInformation; GetTokenInformation(hToken, TokenElevation, pTokenInformation, sizeof(TokenInformation), ReturnLength); result := (TokenInformation.TokenIsElevated > 0); finally CloseHandle(hToken); end; except result := false; end; end;
#5
Escrito 03 febrero 2017 - 10:10
Editado por Agustin Ortu, 03 febrero 2017 - 10:11 .
#6
Escrito 03 febrero 2017 - 11:08
Buscando encontre esta función creo q es lo q necesito
delphi
function RunningAsAdmin: boolean; var hToken, hProcess: THandle; pTokenInformation: pointer; ReturnLength: DWord; TokenInformation: TTokenElevation; begin hProcess := GetCurrentProcess; try if OpenProcessToken(hProcess, TOKEN_QUERY, hToken) then try TokenInformation.TokenIsElevated := 0; pTokenInformation := @TokenInformation; GetTokenInformation(hToken, TokenElevation, pTokenInformation, sizeof(TokenInformation), ReturnLength); result := (TokenInformation.TokenIsElevated > 0); finally CloseHandle(hToken); end; except result := false; end; end;
Esa función habla del proceso actual. Para eso, prefiero tratar de crear un servicio (OpenSCManagerW) pues solo los administradores pueden y precisa poco código.
Para saber si una app diferenre a la actual, se ejecuta con permisos de administrador prefiero comprobar si el usuario ese administrador con la función C que te mostré. Cuando tenga un rato te la traduzco, si no puedes.
Saludos.
#7
Escrito 03 febrero 2017 - 11:16
Por que ocultar las excepciones?
Personalmente prefiero no usar excepciones en código de bajo nivel. Son "devoradoras" especialmente cuando el tamaño es crítico. Otras veces son catastróficas como en la inyección directa y shellcodes.
Saludos.
#8
Escrito 03 febrero 2017 - 11:22
Tenia idea de usar la funcion q encontre cambiando hProcess := GetCurrentProcess; por el Handle del proceso q voy a utilizar, haber si me explico mejor con respecto a lo q nesesito y si estoy en lo correcto o no.
A partir de W Vista si no estoy herrado hay aplicaciones q aunque el usuario por el q se este trabajando se del grupo administrador nesesitan Ejecutarse como Administrador, es decir yo tengo un usuario admin y ejecute una aplicación con esta opcion esta en un nivel administrativo del sistema, eso es lo q quiero detectar.
#9
Escrito 03 febrero 2017 - 11:34
Sí abres el proceso a tratar con OpenProcess te servirá. Debes hacer pruebas para ver si detecta privilegios elevados. Debería funcionar correctamente.
No puedo hacer pruebas pues no dispongo de PC a mano en este momento.
Saludos.
#10
Escrito 03 febrero 2017 - 12:20
Eso me pasa por no citar. En realidad era mas que nada por este codigo publicado por Dante, mensaje #4
function RunningAsAdmin: boolean; var hToken, hProcess: THandle; pTokenInformation: pointer; ReturnLength: DWord; TokenInformation: TTokenElevation; begin hProcess := GetCurrentProcess; try if OpenProcessToken(hProcess, TOKEN_QUERY, hToken) then try TokenInformation.TokenIsElevated := 0; pTokenInformation := @TokenInformation; GetTokenInformation(hToken, TokenElevation, pTokenInformation, sizeof(TokenInformation), ReturnLength); result := (TokenInformation.TokenIsElevated > 0); finally CloseHandle(hToken); end; except result := false; end; end;
Siempre que veo un try-except con el except que "se come" u oculta la excepcion me dan escalofrios. En esa funcion el try-except esta totalmente de gusto
#11
Escrito 03 febrero 2017 - 06:28
Yo lo implementaría así:
function RunningAsAdmin(PID: integer): boolean; const TokenElevation = 20; var hToken, hProcess: THandle; ReturnLength: DWORD; TokenInformation: TTokenElevation; begin Result:= false; hProcess:= OpenProcess(PROCESS_QUERY_INFORMATION, false, PID); if hProcess <> 0 then begin if OpenProcessToken(hProcess, TOKEN_QUERY, hToken) then begin TokenInformation.TokenIsElevated := 0; GetTokenInformation(hToken, TTokenInformationClass(TokenElevation), @TokenInformation, sizeof(TTokenElevation), ReturnLength); Result:= (TokenInformation.TokenIsElevated > 0); CloseHandle(hToken); end; CloseHandle(hProcess); end; end;
Probada en delphi 7 y debe ser ejecutada desde un proceso ejecutado como administrador.
Saludos.
#12
Escrito 03 febrero 2017 - 06:48
En Builder 5 lo haría de este modo:
#define TokenElevation 20 typedef struct _TOKEN_ELEVATION { DWORD TokenIsElevated; } TOKEN_ELEVATION, *PTOKEN_ELEVATION; BOOL RunningAsAdmin(int PID) { HANDLE hToken, hProcess; DWORD ReturnLength; TOKEN_ELEVATION TokenInformation = {0}; hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, false, PID); if(hProcess){ if(OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)){ TokenInformation.TokenIsElevated = 0; GetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS)TokenElevation, &TokenInformation, sizeof(TOKEN_ELEVATION), &ReturnLength); CloseHandle(hToken); } CloseHandle(hProcess); } return TokenInformation.TokenIsElevated > 0; }
Saludos.