Jump to content


Photo

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


  • Please log in to reply
1 reply to this topic

#1 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4107 posts
  • LocationMadrid - España

Posted 18 September 2011 - 04:10 PM

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
  • 2137 posts

Posted 19 September 2011 - 06:25 AM

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


Saludos
  • 0




IP.Board spam blocked by CleanTalk.