Go back to main cluster
Computer science
Programs
Miscellaneous things to download
Programming
My adventures with Delphi
How to get in touch with me
Miscellaneous things to downloadPrograms
Wersja polska  
Checking whether the administrator is a process creator

I wrote Killer and launched it on my computer. After a few weeks of using it I came to a conclusion that turning the service on and off all the time is quite annoying. I figured that it would be good if Killer was able to detect whether the administrator is trying to mess up or is this a user. As it is known every process in Windows NT has its owner. It can be seen best in WinFrame and in Windows NT TSE. Processes which belong to different users may be launched simultaneously. Thus it is sufficient to detect whether the process owner is the administrator and if so then no action is taken.
I was thinking for a long time and finally I found a solution in MSDN. It is a bit strange, but it doesn't matter ;-). It consists on getting the SID of administrators group and check if process creator belongs to that group.
I assume I already have the process handle at the moment. It is not its ID but its handle. It can be retreived for the current process using GetCurrentProcess function.
  hProcess := GetCurrentProcess;
The first step is to take the token of that process using OpenProcessToken function. In order to read the information inside the token the above function ought to be called with TOKEN_QUERY access.
  OpenProcessToken(hProcess, TOKEN_QUERY, hToken);
That's the way to obtain token's handle. One may say that a token represents a user. With the handle itself there is nothing to be done, because one needs to get information about it. The whole work can be done by means of GetTokenInformation function. Thanks to that function one may take any information about a user. What we are interested in - these are the groups he or she belongs to.
var
  dwSize     : Cardinal;
  dwResult   : LongBool;
  dwError    : Cardinal;
  pGroupInfo : PTokenGroups;
  hToken     : THandle
  SIDAuth    : SID_IDENTIFIER_AUTHORITY;
{...}
  SIDAuth  := SECURITY_NT_AUTHORITY;
  dwSize   := 0;
  dwResult := GetTokenInformation(hToken, TokenGroups, nil, dwSize, dwSize);
  if not dwResult then
     begin
       dwError := GetLastError;
       if dwError<>ERROR_INSUFFICIENT_BUFFER then Exit;
     end;
  pGroupInfo := GlobalAllocPtr(GPTR, dwSize);
  if not GetTokenInformation(hToken, TokenGroups, pGroupInfo, dwSize, dwSize) then
     Exit;
In the effect we get TTokenGroups structure, in which group table is placed. Each table elements contains a SID to the particular group.
	pGroupInfo^.Groups[i].Sid
Now it is sufficient to check if administrator group exists amongst all those groups the user belongs to. EqualSid. But we still need administrator group SID. It can be obtained using AllocateAndInitializeSid function.
  if not AllocateAndInitializeSid(SIDAuth, 2,
                                  SECURITY_BUILTIN_DOMAIN_RID,
                                  DOMAIN_ALIAS_RID_ADMINS,
                                  0, 0, 0, 0, 0, 0,
                                  SID) then Exit;
Now one needs to compare SIDs and it is clear who was the process creator. It is also good to see if the group being compared is not off.
  if (pGroupInfo^.Groups[i].Attributes and SE_GROUP_ENABLED)<>0 then Exit;

That's all. Of course it would be nice to free memory after allocated SID and the structure. These are the functions that can proof to be helpful :-) FreeSid and GlobalFreePtr.

And now, I owe some explanation. If you try to copy this code it wouldn't be compiled. And it is happening because Borland did not translate all the Windows header files. Therefore there is lack for many constants - especially those concerning Windows NT. The module with those constants is located in Killer which everyone can download from Download cluster.

Michał B±kowski




Warning: gzopen(): cannot open a zlib stream for reading and writing at the same time! in /home/michalek/html/english/common/counter.php3 on line 11

Warning: gzwrite(): supplied argument is not a valid stream resource in /home/michalek/html/english/common/counter.php3 on line 31

Warning: gzclose(): supplied argument is not a valid stream resource in /home/michalek/html/english/common/counter.php3 on line 32
This is the no. 49622 visit since March 14, 2001

© Copyright 1999-2005, Michał B±kowski