Blazes
Blazes

Reputation: 4779

Prevent user process from being killed with "End Process" from Process Explorer

I noticed that GoogleToolbarNotifier.exe cannot be killed from Process Explorer. It returns "Access Denied". It runs as the user, it runs "Normal" priority, and it runs from Program Files.

How did they do it?

I think there might be a way to modify the ACL, or mark the process as 'critical', but I cannot seem to locate anything.

Update:

I found the answer with a good bit of digging. @Alex K. was correct in that PROCESS_TERMINATE permission was removed for the process, but I wanted to supply the answer in code:

static const bool ProtectProcess()
{
    HANDLE hProcess = GetCurrentProcess();
    EXPLICIT_ACCESS denyAccess = {0};
    DWORD dwAccessPermissions = GENERIC_WRITE|PROCESS_ALL_ACCESS|WRITE_DAC|DELETE|WRITE_OWNER|READ_CONTROL;
    BuildExplicitAccessWithName( &denyAccess, _T("CURRENT_USER"), dwAccessPermissions, DENY_ACCESS, NO_INHERITANCE );
    PACL pTempDacl = NULL;
    DWORD dwErr = 0;
    dwErr = SetEntriesInAcl( 1, &denyAccess, NULL, &pTempDacl );
    // check dwErr...
    dwErr = SetSecurityInfo( hProcess, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pTempDacl, NULL );
    // check dwErr...
    LocalFree( pTempDacl );
    CloseHandle( hProcess );
    return dwErr == ERROR_SUCCESS;
}

Upvotes: 17

Views: 19401

Answers (3)

Raghav Guar
Raghav Guar

Reputation: 61

I have tried to do it with the help of writing windows services ..and then making some changes

here is the link to write a simple windows service http://code.msdn.microsoft.com/windowsdesktop/CppWindowsService-cacf4948

and we can update Servicabase.cpp file with the following two statements..

fCanStop=FALSE; fCanShutdown=FALSE;

Upvotes: -4

Harry Johnston
Harry Johnston

Reputation: 36318

The code given in the question is misleading. It constructs a DACL with no allow entries and one deny entry; that might make sense if you were applying the DACL to a file with inheritance enabled, but in this case the deny entry is redundant. In the Windows access control model, if a DACL exists but contains no matching ACE, access is implicitly denied.

Here's my version, which applies an empty DACL, denying all access. (Note that it returns an error code rather than a boolean.)

DWORD ProtectProcess(void)
{
    HANDLE hProcess = GetCurrentProcess();
    PACL pEmptyDacl;
    DWORD dwErr;

    // using malloc guarantees proper alignment
    pEmptyDacl = (PACL)malloc(sizeof(ACL));

    if (!InitializeAcl(pEmptyDacl, sizeof(ACL), ACL_REVISION))
    {
        dwErr = GetLastError();
    }
    else
    {
        dwErr = SetSecurityInfo(hProcess, SE_KERNEL_OBJECT, 
                   DACL_SECURITY_INFORMATION, NULL, NULL, pEmptyDacl, NULL);
    }

    free(pEmptyDacl);
    return dwErr;
}

Upvotes: 10

Alex K.
Alex K.

Reputation: 175826

When running my copy of that has Deny set on the Terminate permission (Process Explorer shows this).

Presumably they call SetKernelObjectSecurity to change/remove the ACLs when their process loads.

Upvotes: 9

Related Questions