OpenProcess() with PROCESS_SET_INFORMATION on protected processes

D

Daniel Albuschat

Hi there,

with the help of the TaskManager, I can change the process-affinity of
the svchost.exe processes. I need to click "Processes of all users"
and confirm the UAC-dialog, first, then it "just works" the set
the affinity.

I tried to do the same from within an application, which I start
via "Run as Administrator":

I find the process with "svchost.exe"-names and OpenProcess() it with
PROCESS_SET_INFORMATION. Well, the permission is denied, although
I am admin.

I could imagine that this is by design: Even administrators should not
be able to mess with protected processes. But how/why is the TaskManager
able to do this, then? Does it communicate with a kernel-module which
does the job, perhaps?

Regards,
Daniel Albuschat
 
G

Guest

The only thing I can think of without seeing the code is that you are trying
to set the mask to an illegal one and the error message is somehow
misleading. Did you call GetProcessAffinityMask first to make sure you are
setting the process mask to a subset of that?

There is one other option and that is that you are not actually elevated
properly, but then you should get an access denied error on the call to
OpenProcess. You are sure that the error is returned from
SetProcessAffinityMask and not OpenProcess right?

There are some processes you can't change the affinity on, but I would
expect that you are trying this on a process you own.
 
D

Daniel Albuschat

Jesper said:
The only thing I can think of without seeing the code is that you are trying
to set the mask to an illegal one and the error message is somehow
misleading. Did you call GetProcessAffinityMask first to make sure you are
setting the process mask to a subset of that?

There is one other option and that is that you are not actually elevated
properly, but then you should get an access denied error on the call to
OpenProcess. You are sure that the error is returned from
SetProcessAffinityMask and not OpenProcess right?

There are some processes you can't change the affinity on, but I would
expect that you are trying this on a process you own.

No no, I obviously don't even get to the SetProcessAffinityMask() call,
because OpenProcess() failed, as I described in the original post.

And no, I don't call it on processes that I own, I call it on
svchost.exe processes. And the question is why I can set the process-
affinity with TaskManager, but not from within an elevated (Run as
Administrator) program. I would happily accept the fact that I can't
set the affinity of a protected process, but what I am struggling with
is why TaskManager can do it, but I can not.

You probably want to re-read my original post.

So here's the C++ code (compile it with UNICODE):

#include <Windows.h>
#include <Tlhelp32.h>
#include <Psapi.h>
#include <wstring>
using namespace std;

wstring SysErrorMessage(DWORD error);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR
lpCmdLine, int nShowCmd) {
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
PROCESSENTRY32 process;
process.dwSize = sizeof(PROCESSENTRY32);
if( Process32First(snapshot,&process) ) {
do {
if( wcscmp(process.szExeFile,L"svchost.exe") == 0 ) {
HANDLE proc =
OpenProcess(PROCESS_SET_INFORMATION,FALSE,process.th32ProcessID);
if( proc != 0 )
SetProcessAffinityMask(proc,1);
else {
MessageBox(0,(L"Could not open process:
\n"+SysErrorMessage(GetLastError())).c_str(),L"Error",MB_OK);
}
CloseHandle(proc);
}
} while(Process32Next(snapshot, &process));
} else
MessageBox(0,SysErrorMessage(GetLastError()).c_str(),L"Error",MB_OK);
CloseHandle(snapshot);
}

wstring SysErrorMessage(DWORD error) {
TCHAR *buf = 0;
DWORD len = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER|

FORMAT_MESSAGE_FROM_SYSTEM,0,error,LANG_USER_DEFAULT,reinterpret_cast<TCHAR*>(&buf),0,0);
if( len == 0 )
return L"";
wstring result(buf);
return result;
}

Thanks for your answers so far,

Daniel
 
G

Guest

I obviously ought to re-read your original post. Had I done that I probably
would have noticed that the problem is the line in the documentation for
OpenProcess that you missed:
To open a handle to another another local process and obtain full access
rights, you must enable the SeDebugPrivilege privilege. For more information,
see Changing Privileges in a Token.

To open handles to processes you don't own you have to enable the debug
privilege. In other words, to solve the problem, add this code before you
start opening process handles:
TOKEN_PRIVILEGES tp;
LUID luid;

if ( !LookupPrivilegeValue(
NULL, // lookup privilege on local system
L"SeDebugPrivilege", // privilege to lookup
&luid ) ) // receives LUID of privilege
{
printf("LookupPrivilegeValue error: %u\n", GetLastError() );
return FALSE;
}

tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

// Enable the privilege or disable all privileges.
HANDLE currProc = GetCurrentProcess();
HANDLE procToken;
if(!OpenProcessToken(currProc,TOKEN_ADJUST_PRIVILEGES,&procToken))
{
_tprintf(L"\nOpenProcessToken failed with error
%s.",SysErrorMessage(GetLastError()));
return -1;
}

if ( !AdjustTokenPrivileges(
procToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL) )
{
_tprintf(L"\nAdjustTokenPrivileges error: %s\n",
SysErrorMessage(GetLastError()) );
return FALSE;
}

CloseHandle(procToken);
CloseHandle(currProc);


Yes, I know that's not the cleanest code I've ever written, but I hacked it
up quickly while the kids were pestering me to go play with them instead of
with the computer.
 
D

Daniel Albuschat

Jesper said:
I obviously ought to re-read your original post. Had I done that I probably
would have noticed that the problem is the line in the documentation for
OpenProcess that you missed:
To open a handle to another another local process and obtain full access
rights, you must enable the SeDebugPrivilege privilege. For more information,
see Changing Privileges in a Token.

Wow, you're my saviour :D
Thank you very much, I indeed missed that part, or rather didn't realise
that it applied to my problem. My application now successfully sets all
the affinity-masks correctly.
I feel bad that you took the time and answered my post instead of
playing with your children. :)

Thanks again,

Daniel Albuschat
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top