Ir al contenido


Foto

[MULTILENGUAJE] Conocer el usuario y el domino de un proceso


  • Por favor identifícate para responder
1 respuesta en este tema

#1 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 18 septiembre 2011 - 04:10

Solía realizar esta tarea abriendo el proceso y después usar la la API OpenProcessToken para obtener el SID y usarlo en LookupAccountSid. Pero este sistema no funciona para algunos procesos y no obtiene los de usuarios distintos por problema de privilegios en la API OpenProcessToken.

He implementado una función que evita el problema. Se basa en la enumeración con la poco conocida WTSEnumerateProcesses. El código en delphi es el siguiente:


delphi
  1. type
  2. WTS_PROCESS_INFO = record
  3.   SessionId: DWORD;    // session id
  4.   ProcessId: DWORD;    // process id
  5.   pProcessName: LPSTR; // name of process
  6.   pUserSid: PSID;      // user's SID
  7. end;
  8. PWTS_PROCESS_INFO = ^WTS_PROCESS_INFO;
  9.  
  10. TA_WTS_PROCESS_INFO = array of WTS_PROCESS_INFO;
  11. PTA_WTS_PROCESS_INFO = ^TA_WTS_PROCESS_INFO;
  12.  
  13. function WTSEnumerateProcessesA(hServer: Cardinal; Reserved: DWORD; Version: DWORD;
  14.   var ppProcessInfo: PWTS_PROCESS_INFO; var pCount: DWORD): BOOL; stdcall external 'Wtsapi32.dll';
  15. procedure WTSFreeMemory(pMemory: Pointer); stdcall external 'Wtsapi32.dll';
  16.  
  17. implementation
  18.  
  19. function GetUserAndDomainFromPID(ProcessId: Cardinal; var User, Domain: String): boolean;
  20. var
  21.   snu: SID_NAME_USE;
  22.   pProcessInfo: TA_WTS_PROCESS_INFO;
  23.   nProc,UserSize, DomainSize: Cardinal;
  24. begin
  25.   Result:= false;
  26.   nProc:= 0;
  27.   UserSize:= 0;
  28.   DomainSize:= 0;
  29.  
  30.   if WTSEnumerateProcessesA(0, 0, 1, PWTS_PROCESS_INFO(pProcessInfo), nProc) then
  31.   begin
  32.     repeat dec(nProc) until (nProc <= 0) or (ProcessId = pProcessInfo[nProc].ProcessId);
  33.     LookupAccountSid(nil, pProcessInfo[nProc].pUserSid, nil, UserSize, nil, DomainSize, snu);
  34.     if (UserSize <> 0) or (DomainSize <> 0) then
  35.     begin
  36.       SetLength(User, UserSize);
  37.       SetLength(Domain, DomainSize);
  38.       Result:= LookupAccountSid(nil, pProcessInfo[nProc].pUserSid, @User[1], UserSize, @Domain[1], DomainSize, snu);
  39.     end;
  40.     WTSFreeMemory(pProcessInfo);
  41.   end;
  42. end;


Con un ejemplo de uso:

delphi
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   User, Domain: String;
  4. begin
  5.   GetUserAndDomainFromPID(StrToInt(Edit1.Text), User, Domain);
  6.   Label1.Caption:= User;
  7.   Label2.Caption:= Domain;
  8. end;


La versión C/C++ Builder sería como sigue:

cpp
  1. #include <wtsapi32.h>
  2. #pragma link "Wtsapi32.lib"
  3.  
  4. bool GetUserAndDomainFromPID(DWORD ProcessId, String &User, String &Domain)
  5. {
  6.   SID_NAME_USE snu;
  7.   bool Result = false;
  8.   PWTS_PROCESS_INFO pProcessInfo;
  9.   DWORD nProc = 0;
  10.   DWORD UserSize=0, DomainSize=0;
  11.  
  12.   if(WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pProcessInfo, &nProc)){
  13.     while(--nProc > 0 && ProcessId != pProcessInfo[nProc].ProcessId);
  14.     LookupAccountSid(NULL, pProcessInfo[nProc].pUserSid, NULL, &UserSize, NULL, &DomainSize, &snu);
  15.     if(UserSize && DomainSize){
  16.       User.SetLength(UserSize);
  17.       Domain.SetLength(DomainSize);
  18.       Result = LookupAccountSid(NULL, pProcessInfo[nProc].pUserSid, &User[1], &UserSize, &Domain[1], &DomainSize, &snu);
  19.     }
  20.     WTSFreeMemory(pProcessInfo);
  21.   }
  22.  
  23.   return Result;
  24. }


Y un ejemplo similar al de delphi:

cpp
  1. void __fastcall TForm1::Button1Click(TObject *Sender)
  2. {
  3.   String User, Domain;
  4.   GetUserAndDomainFromPID(StrToInt(Edit1->Text), User, Domain);
  5.   Label1->Caption = User;
  6.   Label2->Caption = Domain;
  7. }


Con esto conseguimos los datos de todos los procesos con una excepción, los que corresponden al proceso con Pid = 0. Todos sabemos que ese proceso es el proceso inactivo del sistema ([System Process]) cuyo usuario es SYSTEM y el dominio NT AUTHORITY

Espero que sea de utilidad.


Saludos.
  • 0

#2 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.137 mensajes

Escrito 19 septiembre 2011 - 06:25

Gracias escafandra, como de costumbre, muy buen código.  (y) (y)


Saludos
  • 0




IP.Board spam blocked by CleanTalk.