Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   API de Windows (https://www.clubdelphi.com/foros/forumdisplay.php?f=7)
-   -   Sabes si un proceso es de sistema o no (https://www.clubdelphi.com/foros/showthread.php?t=75666)

fide_uci 10-09-2011 22:24:38

Sabes si un proceso es de sistema o no
 
Hola amigos, mi pregunta es la siguiente.

Necesito obtener la lista de procesos que se estan ejecutando en el sistema y poder obtener tambien el privilegio que tiene cada uno. O sea saber si un proceso corre como sistema o como el usuario que esta actualmente logueado. Uso Delphi 7 y Windows 7. Alguna idea ?

fide_uci 11-09-2011 01:26:48

Ninguna respuesta !. Por favor necesito ayuda !

Casimiro Notevi 11-09-2011 01:45:14

Amigo fide_uci, te recuerdo nuestra guía de estilo, gracias.

No hace ni tres horas que has puesto la pregunta, aquí no hay nadie de guardia trabajando, ni cobrando tampoco, evidentemente.
Es sábado, fin de semana, la mayor parte de la gente no accede al ordenador.

Si necesitas ayuda sobre ese tema, de momento, te recuerdo que tenemos una opción "Buscar" donde podrás encontrar lo que buscas.
Además, en nuestro FTP, hay incluso programas completos que trabajan con los datos que tú estás buscando.
Date una vuelta por allí y mira si lo encuentras.

Gracias.

fide_uci 11-09-2011 20:33:06

Ajaja Casimiro disculpame. Es que a veces uno anda desesperado buscando una solucion y bueno se presipita. Disculpame voy a ser mas cuidadoso con estos detalles.

Un saludo..

Casimiro Notevi 11-09-2011 21:19:54

Gracias, amigo :)

No sé si lo que buscas puede ser esto.

EDITO: me equivoqué de enlace, está aquí.

fide_uci 12-09-2011 00:36:26

A ver primero que todo muchas gracias. Pero bueno en verdad ya yo se como obtener la lista de procesos en ejecucion. Lo que en verdad busco es como saber en que ambito se ejecuta cada proceso. Si es como usuario y como sistema.

escafandra 12-09-2011 11:55:20

Código Delphi [-]
function EnablePrivilege(name: String; Enable: boolean): boolean;
var
   hToken: Cardinal;
   priv: TOKEN_PRIVILEGES;
begin
   priv.PrivilegeCount:= 1;
   priv.Privileges[0].Attributes:= 0;
   if Enable then priv.Privileges[0].Attributes:= SE_PRIVILEGE_ENABLED;
   LookupPrivilegeValue(nil, PCHAR(name), priv.Privileges[0].Luid);
   OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, hToken);
   AdjustTokenPrivileges (hToken, FALSE, priv, sizeof(priv), nil, PDWORD(nil)^);
   Result:= (GetLastError = ERROR_SUCCESS);
   CloseHandle (hToken);
end;

function GetProcessOwner(ProcessId: DWORD; var User, Domain: String): boolean;
var
  hToken, hProcess, cbBuf, UserSize, DomainSize: Cardinal;
  pSidUser: ^SID_AND_ATTRIBUTES;
  SidNU: SID_NAME_USE;
begin
  Result:= false;
  EnablePrivilege('SeDebugPrivilege', true);
  hProcess:= OpenProcess(PROCESS_QUERY_INFORMATION, false, ProcessId);
  if hProcess <> 0 then
  begin
    if OpenProcessToken(hProcess, TOKEN_QUERY, hToken) then
    begin
      GetTokenInformation(hToken, TokenUser, nil, 0, cbBuf);
      GetMem(pSidUser, cbBuf);
      GetTokenInformation(hToken, TokenUser, pSidUser, cbBuf, cbBuf);
      CloseHandle(hToken);
      UserSize:= 0;
      DomainSize:= 0;
      LookupAccountSid(nil, pSidUser.Sid, nil, UserSize, nil, DomainSize, SidNU);
      if (UserSize <> 0) or (DomainSize <> 0) then
      begin
        SetLength(User, UserSize);
        SetLength(Domain, DomainSize);
        Result:= LookupAccountSid(nil, pSidUser.Sid, PCHAR(User), UserSize, PCHAR(Domain), DomainSize, SidNU);
      end;
    end;
     CloseHandle(hProcess);
  end;
  EnablePrivilege('SeDebugPrivilege', false);
end;

Ejemplo:

Código Delphi [-]
var
  User, Domain: String;
begin
   GetProcessOwner(StrToInt(Edit1.Text), User, Domain);
   Label1.Caption := User;
   Label2.Caption := Domain;
end;


Saludos.

fide_uci 12-09-2011 13:04:44

WoW, es justo lo que necesito. Voy a probarlo ahora mismo y en cuanto lo pruebe te digo pero se ve exacto a lo que me hace falta. Gracias desde ya escafandra.

fide_uci 12-09-2011 13:44:35

Uff lo probe y es exactamente lo que necesitaba. Todo es por que hay un virus que ejecuta el proceso svchost como usuario y entonces necesito obtener el svchost que se ejecute como usuario para poder tumbarlo de la memoria y deshacer todos los cambios que el virus ejecuta sobre el sistema.

Casimiro Notevi 12-09-2011 16:24:09

:confused::confused::confused::confused::confused::confused: ¿Y por qué no quitas el virus?

roman 12-09-2011 16:29:42

Y yo añadiría: ¿y por qué no ves quién es el usuario en la lista de procesos de windows (ctrl+alt+supr)?

// Saludos

escafandra 12-09-2011 17:07:42

Tienes una utilidad muy buena para sustituir al TaskManager, el Process Explorer v15.04 de Systernals que te informa de lo que buscas para localizar tu virus. Te dice también la ruta desde la que se ejecutó cada proceso con lo que localizas con facilidad al intruso.

Saludos.

escafandra 12-09-2011 17:27:09

Releyendo me he dado cuenta de que el anterior código que publiqué contiene un error de princiapiante (las prisas:p). Localizo memoria pero no la libero...:o

Como no puedo editarlo, lo republico dejando la chapuza previa.
Código Delphi [-]
function GetUserAndDomainFromPID(ProcessId: DWORD; var User, Domain: String): boolean;
var
  hToken, hProcess, cbBuf, UserSize, DomainSize: Cardinal;
  pSidUser: ^SID_AND_ATTRIBUTES;
  SidNU: SID_NAME_USE;
begin
  Result:= false;
  EnablePrivilege('SeDebugPrivilege', true);
  hProcess:= OpenProcess(PROCESS_QUERY_INFORMATION, false, ProcessId);
  if hProcess <> 0 then
  begin
    if OpenProcessToken(hProcess, TOKEN_QUERY, hToken) then
    begin
      GetTokenInformation(hToken, TokenUser, nil, 0, cbBuf);
      GetMem(pSidUser, cbBuf);
      GetTokenInformation(hToken, TokenUser, pSidUser, cbBuf, cbBuf);
      CloseHandle(hToken);
      UserSize:= 0;
      DomainSize:= 0;
      LookupAccountSid(nil, pSidUser.Sid, nil, UserSize, nil, DomainSize, SidNU);
      if (UserSize <> 0) or (DomainSize <> 0) then
      begin
        SetLength(User, UserSize);
        SetLength(Domain, DomainSize);
        Result:= LookupAccountSid(nil, pSidUser.Sid, PCHAR(User), UserSize, PCHAR(Domain), DomainSize, SidNU);
      end;
      FreeMem(pSidUser);
    end;
    CloseHandle(hProcess);
  end;
  EnablePrivilege('SeDebugPrivilege', false);
end;

Saludos.

ecfisa 12-09-2011 17:42:29

Hola.

Sólo por curiosidad, ayer estuve probando una función que encontré buscando en la web, para obtener el dominio y nombre.
Pero aunque obtengo el dominio y nombre del usuario, me muestra cadena vacía cuando el nombre se trata de usuario es 'SYSTEM' o 'SERVICIO LOCAL'.

Agrego la prueba que hice, por si alguien sabe el por qué no muestra esos datos.
Código Delphi [-]
...
uses TlHelp32;

type
  TProcessEntry32Array = array of TProcessEntry32;
  
  PTokenUser = ^TTokenUser;
  TTokenUser = packed record
    User: SID_AND_ATTRIBUTES;
  end;

function GetProcess: TProcessEntry32Array;
var
  Found : Boolean;
  SnapHandle : THandle;
  pr32 : TProcessEntry32;
begin
  SnapHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
  pr32.dwSize := Sizeof(ProcessEntry32);
  Found := Process32First(SnapHandle, pr32);
  while Found do
  begin
    SetLength(Result, Length(Result)+1);
    Result[Length(Result)-1] := pr32;
    Found := Process32Next(SnapHandle, pr32);
  end;
  CloseHandle(SnapHandle);
end;

{ Esta es la función que encontré }
function GetProcessUserName(ProcessID: Cardinal; out DomainName, UserName: string): Boolean;
var
  ProcHandle, ProcToken: THandle;
  InfoSize, UserNameSize, DomainNameSize: Cardinal;
  User: PTokenUser;
  Use: SID_NAME_USE;
  DomainNameArray, UserNameArray: array[0..255] of Char;
begin
  Result := False;
  DomainName := '';
  UserName := '';
  ProcHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, ProcessID);
  if ProcHandle = 0 then
    Exit;
  try
    if not OpenProcessToken(ProcHandle, TOKEN_QUERY, ProcToken) then
      Exit; 
    try
      GetTokenInformation(ProcToken, TokenUser, nil, 0, InfoSize);
      User := AllocMem(InfoSize * 2); 
      try
        if GetTokenInformation(ProcToken, TokenUser, User, InfoSize * 2, InfoSize) then
        begin 
          DomainNameSize := SizeOf(DomainNameArray);
          UserNameSize := SizeOf(UserNameArray);
          Result := LookupAccountSid(nil, User^.User.Sid, UserNameArray,
            UserNameSize, DomainNameArray, DomainNameSize, Use);
          if Result then
          begin 
            SetString(DomainName, DomainNameArray, StrLen(DomainNameArray));
            SetString(UserName, UserNameArray, StrLen(UserNameArray));
          end; 
        end; 
      finally
        FreeMem(User);
      end; 
    finally
      CloseHandle(ProcToken);
    end;
  finally
    CloseHandle(ProcHandle);
  end; 
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
  ProcList: TProcessEntry32Array;
  Un,Dn: string; // nombre,dominio
begin
  ProcList := GetProcess;
  ListBox1.TabWidth:= 100;
  for i:=0 to Length(ProcList)-1 do
  begin
    GetProcessUserName(ProcList[i].th32ParentProcessID, Un, Dn);
    ListBox1.Items.Add(string(ProcList[i].szExeFile)+
       Chr(9)+ Un + Chr(9) + Dn);
  end;
end;
Algo se me esta escapando y no sé que es... :rolleyes:

Un saludo.

Edito: La aplicación consta de un TButton y un TListBox solamente.

escafandra 12-09-2011 17:50:46

No he probado ese código, pero quizás se solucione dando privilegios debug a la aplicación.

Saludos.

ecfisa 12-09-2011 17:54:35

Cita:

Empezado por escafandra (Mensaje 411859)
No he probado ese código, pero quizás se solucione dando privilegios debug a la aplicación.

Saludos.

Supongo entonces que habría que agregarle la función que pusiste más arriba (EnablePrivilege), ¿ No es así ?

Saludos.

fide_uci 12-09-2011 18:36:10

Bueno primero que todo muchas gracias a todas las personas que me han ayudado. Les digo que mi programa deberia ser capaz de leer el registro de windows en busca de una clave. Si dicha clave existe entonces deberia leer otra clave del registro y eliminar dichas claves asi como el virus que se guarda en %Windir%\svchost.exe

Para poder hacer todo esto yo necesitaba tumbarlo de la memoria ya que estaba en ejecucion. Es por ello que estuve pidiendo la informacion mencionada antes. A proposito el virus que menciono, al 6to reinicio de la PC despues de que el la infecta, te jode los discos duros poniendole ATA Password y dejandolo bloqueado, siendo imposible de desbloquear de forma comun.

escafandra 12-09-2011 18:50:04

Cita:

Empezado por ecfisa (Mensaje 411860)
Supongo entonces que habría que agregarle la función que pusiste más arriba (EnablePrivilege), ¿ No es así ?

Eso es. ;)

Cita:

Empezado por fide_uci (Mensaje 411793)
...Todo es por que hay un virus que ejecuta el proceso svchost como usuario y entonces necesito obtener el svchost que se ejecute como usuario para poder tumbarlo de la memoria...

La ruta del virus seguro que es distinta a la del sistema. No hace mucho he lidiado con un virus de pendrive con el mismo nombre (svchost.exe) pero que se localiza en la ruta C:\Documents and Settings\USUARIO\Datos de programa. Toma atributos de oculto, de solo lectura y de sitema con lo que no lo puedes borrar con el explorador sin antes quitar el atributo de sistema y eliminar su proceso...

Saludos.

fide_uci 12-09-2011 20:24:26

Si entiendo. Bueno pues el muy descarado que te digo se guarda en la carpeta Windows (C:\Windows) y no se pone oculto ni nada. Lo que si a las 6 veces te deja el disco inserbible, a las 6 veces de reiniciar la PC desde que el se instalo por primera vez.

escafandra 18-09-2011 23:25:48

Aunque el objetivo de este tema está cumplido, me gustaría añadir algo.

No he terminado de estar contento con la función que expuse para obtener el usuario y dominio de un proceso. El motivo es que no se obtienen los datos de todos los procesos cuando éstos son de mas de un usuario y sobre todo si se ejecuta como usuario no administrador por un problema de privilegios en la API OpenProcessToken. He implementado otra función con APIs menos conocidas que evitan el uso de la anterior:
Código Delphi [-]
type
WTS_PROCESS_INFO = record
  SessionId: DWORD;    // session id
  ProcessId: DWORD;    // process id
  pProcessName: LPSTR; // name of process
  pUserSid: PSID;      // user's SID
end;
PWTS_PROCESS_INFO = ^WTS_PROCESS_INFO;

TA_WTS_PROCESS_INFO = array of WTS_PROCESS_INFO;
PTA_WTS_PROCESS_INFO = ^TA_WTS_PROCESS_INFO;

function WTSEnumerateProcessesA(hServer: Cardinal; Reserved: DWORD; Version: DWORD;
  var ppProcessInfo: PWTS_PROCESS_INFO; var pCount: DWORD): BOOL; stdcall external 'Wtsapi32.dll';
procedure WTSFreeMemory(pMemory: Pointer); stdcall external 'Wtsapi32.dll';

implementation

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;

El ejemplo de uso es sencillo:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
var
  User, Domain: String;
begin
  GetUserAndDomainFromPID(StrToInt(Edit1.Text), User, Domain);
  Label1.Caption:= User;
  Label2.Caption:= Domain;
end;

Ahora si, conseguimos los datos de todos los procesos con una excepción, el proceso que corresponde a un Pid = 0 que todos sabemos que es el proceso inactivo del sistema ([System Process]) cuyo usuario es SYSTEM y el dominio NT AUTHORITY


Espero que sea de utilidad.

Saludos.


La franja horaria es GMT +2. Ahora son las 17:22:03.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi