Search code examples
c#c++windowskioskwin32-process

Deny Access to Kiosk program process


I have a kiosk app and have to disable task manager always to prevent closing the program by users .
But some users need the TaskManager to close hanging programs.

Any help would be appropriated.

However, I am sure there is a function in windows to prevent closing a program's process , as when one attempt to kill rundll.exe process. I want to know that function if I can call it with DllImport

Can anyone help with a trick?
A hack?
A function?
Any other solution?

EDIT:

At least if there is not a way to prevent the process from being closed, I need a way to hide it from processes list appeared in the task manager.

EDIT 2: I can't find the solution so far


Solution

  • One approach, if you could access the process ID in an administrative context, is to deny the PROCESS_TERMINATE permission on the process to end users. Terminating the process (through task manager or other contexts) is by default granted to the owner, but can be explicitly denied. When it is denied, terminating the process would require the owner to manually change the ACL, and then terminate the process. If the user is neither an administrator nor the owner of the process, he will not be able to forcibly terminate the process (e.g., through Task Manager), although the process will be allowed to exit normally.

    The following code puts an explicit deny ACE on the process with the PID processid for members of the Everyone group.

    #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;
    }