2011-03-21 16 views
6

Tengo una aplicación de kiosco y tengo que deshabilitar el administrador de tareas para evitar siempre que cierre el programa por los usuarios.
Pero algunos usuarios necesitan que TaskManager cierre los programas colgantes.

Cualquier ayuda sería apropiada.

Sin embargo, estoy seguro de que hay una función en Windows para evitar el cierre de un proceso de programa, como cuando se intenta matar rundll.exe proceso. Quiero saber esa función si puedo llamarla con DllImportDenegar acceso al proceso del programa Kiosco

¿Alguien puede ayudarme con un truco?
¿Un truco?
¿Una función?
¿Alguna otra solución?

EDIT:

Al menos si no hay una manera de evitar que el proceso se cierre, necesito una manera de ocultarlo de la lista de procesos apareció en el administrador de tareas.

EDIT 2: no puedo encontrar la solución hasta el momento

+1

Como alternativa siempre se puede desactivar el Administrador de tareas –

+0

@Wiiliam No estoy seguro, algunos programas no pueden cerrarse a través de administrador de tareas, tales como la seguridad e incluso algunos virus –

+2

@ Mr.DDD Estos generalmente solo ocultan el proceso del administrador de tareas al interceptar las funciones de bajo nivel del sistema operativo que devuelven listas de procesos; aún es posible matarlos. – mdm

Respuesta

6

Un enfoque, si pudiera acceder al ID del proceso en un contexto administrativo, es denegar el permiso PROCESS_TERMINATE en el proceso a los usuarios finales. La finalización del proceso (a través del administrador de tareas u otros contextos) se otorga por defecto al propietario, pero se puede denegar explícitamente. Cuando se deniega, la finalización del proceso requeriría que el propietario cambie manualmente la ACL y luego finalice el proceso. Si el usuario no es ni el administrador ni el propietario del proceso, no podrá finalizar el proceso por la fuerza (por ejemplo, a través del Administrador de tareas), aunque se permitirá que el proceso se cierre normalmente.

El siguiente código pone una ACE denegación explícita en el proceso con el PID processid para los miembros del grupo Todos.

#include "Aclapi.h" 
#include "Sddl.h" 
DWORD RestrictTerminateOnProcessId(DWORD processid) 
{ 
    PACL dacl = NULL, newdacl = NULL; 
    HANDLE ph = NULL; 
    PSECURITY_DESCRIPTOR* desc = NULL; 
    PSID everyonesid = NULL; 
    ph = OpenProcess(WRITE_DAC | READ_CONTROL, false, processid); 
    if (!ph) goto cleanup; 

    if (ERROR_SUCCESS != GetSecurityInfo(ph, 
      SE_KERNEL_OBJECT, 
      DACL_SECURITY_INFORMATION, 
      NULL, 
      NULL, 
      &dacl, 
      NULL, 
      desc)) goto cleanup; 

    SID_IDENTIFIER_AUTHORITY WorldAuth = SECURITY_WORLD_SID_AUTHORITY; 
    if (!AllocateAndInitializeSid(
      &WorldAuth,1,SECURITY_WORLD_RID, 
      0,0,0,0,0,0,0,&everyonesid)) goto cleanup; 

    // begin copy dacl 
    _ACL_SIZE_INFORMATION si; 
    GetAclInformation(dacl, 
      &si, 
      sizeof(si), 
      AclSizeInformation); 

    DWORD dwNewAclSize = si.AclBytesInUse + 
      (2*sizeof(ACCESS_DENIED_ACE)) + (2*GetLengthSid(everyonesid)) - 
      (2*sizeof(DWORD)); 

    newdacl = (PACL)HeapAlloc(
      GetProcessHeap(), 
      HEAP_ZERO_MEMORY, 
      dwNewAclSize); 

    if (newdacl == NULL) goto cleanup; 

    if (!InitializeAcl(newdacl, dwNewAclSize, ACL_REVISION_DS)) 
      goto cleanup; 

    if (!AddAccessDeniedAce(newdacl, 
      ACL_REVISION_DS, 
      PROCESS_TERMINATE, 
      everyonesid)) goto cleanup; 

    for (int i = 0; i < si.AceCount; i++) 
    { 
      LPVOID pace = NULL; 
      if (!GetAce(dacl, i, &pace)) goto cleanup; 
      if (!AddAce(newdacl, ACL_REVISION_DS, 
        MAXDWORD, pace, ((PACE_HEADER)pace)->AceSize)) 
        goto cleanup; 
    } 

    // end copy dacl 

    if (!SetSecurityInfo(ph, 
      SE_KERNEL_OBJECT, 
      DACL_SECURITY_INFORMATION, 
      NULL, 
      NULL, 
      newdacl, 
      NULL)) goto cleanup; 
    SetLastError(0); 

cleanup: 
    DWORD ret = GetLastError(); 
    if (desc) LocalFree(desc); 
    if (newdacl) HeapFree(GetProcessHeap(), 0, (LPVOID)newdacl); 
    if (ph) CloseHandle(ph); 
    if (everyonesid) FreeSid(everyonesid); 
    return !ret; 
} 
2

Suena como que no puede evitar que un proceso de ser matado - ver this question y específicamente el link posted to an explanation.

No obstante, puede impedir que el usuario abra el administrador de tareas desde la barra de tareas (clic derecho -> abrir administrador de tareas), presionar Ctrl-Shift-Esc o escribir taskman en el símbolo del sistema usando la siguiente clave de registro:

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System\DisableTaskMgr 

Al establecerlo en 1 se desactiva el administrador de tareas, 0 lo habilita nuevamente.

Desde el símbolo del sistema, desactivar este modo:

reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System /v DisableTaskMgr /t REG_DWORD /d 1 /f 

Y puede renable con este comando:

reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System /v DisableTaskMgr /t REG_DWORD /d 0 /f 

También tendrá que encontrar una manera de evitar que el usuario escribiendo a esta clave en el registro, aunque en mi máquina con Windows 7 de 64 bits tuve que abrir una solicitud de comando de administrador antes de poder cambiar la clave.

Editar

Como se sugiere en los comentarios, podría interceptar una llamada de bajo nivel del sistema para modificar la lista de procesos reportados. This answer se le escapa, básicamente tendrá que escribir un rootkit en modo núcleo, probablemente implementado como un controlador de dispositivo. Es probable que esto solo funcione en Windows XP y en versiones posteriores debido a cambios en el kernel realizados en Vista y en adelante. Sin embargo, se puede hacer, un amigo mío creó un prototipo de esto para su disertación final de BSc.

También deberá tener en cuenta otros métodos de consulta de procesos: IIRC NtQuerySystemInformation no es la única forma en que se pueden enumerar los procesos.

+0

Gracias, pero ya sé cómo cerrar el administrador de tareas. Solo quiero una manera de evitar que el proceso sea asesinado. –

+1

Si está buscando alguna piratería de kernel, verifique mis ediciones. – mdm

5

Puede crear un servicio que se ejecute al arrancar. Luego, ingresa monitors when the user logs y comienza su programa. Desde allí, tiene dos opciones:

  1. Espere en el programa y revísela mientras la sesión del usuario persista.
  2. Ejecútelo bajo una cuenta de administrador y asegúrese de que los usuarios siempre estén ejecutando cuentas limitadas. La aplicación de privilegios de Windows debe hacer que su programa no se muera.

Si debe permitir a los usuarios privilegios administrativos (y pueden así matar su servicio), asegúrese de registrar su servicio para que SCM restarts it automatically.

Cualquier cosa más allá de eso requeriría algo de hacking de kernel, como dijo mdm, o sumergirse en territorio de rootkits. Lo cual te sugiero que evites.

Si por casualidad aún ejecuta Windows XP, en lugar de un servicio de sistema, puede registrar Winlogon notification package. Básicamente son inacabables, ya que se ejecutan en el contexto de winlogon.exe, que es la razón por la que estaban removed desde Vista y superior.

5

La forma correcta de hacer esto es:

Crear un usuario para la aplicación Quiosco. Digamos KioskUser Cree otros usuarios que hagan cosas en la computadora. Digamos Usuario1 NINGUNO de ellos debería ser administrador. No necesitan ser administradores ¿verdad? Ellos pueden tener privilegios, por supuesto.

Va a utilizar la cuenta de Usuario1 como de costumbre. Luego, ejecuta la aplicación Kiosk como KioskUser. (utilice el comando runas) - agregue la aplicación a la sesión y haga que sea visible (consulte los argumentos para obtener más información al respecto)

Mientras el Usuario1 está conectado y la aplicación Kiosk se ejecuta desde el KioskUser, el Usuario1 no puede matar el proceso.

No recomendaría "piratear" el sistema, ni cambiar algo en el registro. Además, puede hacer que la aplicación Kiosk sea un servicio y ejecutarlo bajo el usuario de Kiosk.

1

corto de la protección de su aplicación Quiosco con algún rootkit/controlador no se puede ... aunque los métodos que se necesitan para utilizar en este contexto son "malware como" así que ten cuidado ...

Aquí http://blogs.msdn.com/b/oldnewthing/archive/2004/02/16/73780.aspx se puede ver en un lado por qué esto es una tarea no es realmente posible y por otro lado las varias posibilidades que tendrían que defenderse ... que serían:

niegan PROCESS_TERMINATE
negar PROCESS_CREATE_THREAD
deny PROCESS_VM_WRITE
deny PROCESS_SUSPEND_RESUME
Además de cualquier defensa que pueda tener contra depuradores, otro asunto muy complicado.

0

Si bien no puede evitar que un usuario autorizado mate su proceso, puede evitar que los usuarios tengan los permisos necesarios para matar su proceso. Dicho esto, un administrador local siempre tendrá permiso para matar cualquier proceso. ¿Tiene la esperanza de evitar el cierre de su aplicación por parte de cualquier usuario o simplemente no administradores? Si lo primero, simplemente ejecutar el proceso bajo una cuenta de usuario dedicada puede ser suficiente para hacer el truco.

1

Lo siento por no publicar esto como un comentario (reputación insuficiente). Estoy usando la solución drfs, pero parece inducir una pérdida de memoria con la forma en que se usa GetSecurityInfo. He cambiado el código y se deshizo de la pérdida de memoria como esto:

Declaración:

PSECURITY_DESCRIPTOR desc = NULL; 

inicialización:

desc = (PSECURITY_DESCRIPTOR)GlobalAlloc(GMEM_FIXED, sizeof(PSECURITY_DESCRIPTOR)); 

Limpieza:

if (desc) GlobalFree(desc); 

Llamar:

GetSecurityInfo(ph, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &dacl, NULL, &desc) 

También encontré este artículo sobre el tema: http://i1.blogs.msdn.com/b/oldnewthing/archive/2012/12/12/10376639.aspx

Cuestiones relacionadas