Link to home
Start Free TrialLog in
Avatar of tradinfo
tradinfo

asked on

How to hide process under NT/2000/XP (VC++) ???

Hi,
i am searching sample code to hide my application of the view of taskmanager app (and other process viewers) under Windows NT/2000/XP.
A sample code in MSVC++ and points go to you.
Thanxxxxxx for your precious help !
Avatar of fl0yd
fl0yd

I'm just guessing here, but you are trying to create an application that is totally cloaked, i.e. noone will ever notice it's there. Now I'm asking myself why you are asking for this behaviour... could it be that you're trying to do something malicious to someone's system? Please tell us what you are after. The resemblance to a stealth fighter should be close enough, to make any reflecting human being reluctant to give away info.
Avatar of tradinfo

ASKER

i am working on a security application and the aim is to "protect the innocents" not "f**k everybody"...
And to have a real protection, I need a way to secure my own application first from "malicious" people who would like disable this app and try to pass through this app...
That's why i am asking you such a question. Nothing bad in my question, just a real question of a real coder for a real problem...
So thanxxx for all people who'll be able to answer my question and gimme a solution and a sample code...
send it to me by email if you don't want to give this solution to every one else :

{{obscenity masked and email address  removed -- DanRollins / EE Page Editor }}

thanx.
No offence intended. But I'd rather be safe than sorry. Just wanted to make sure what you're after. I came across your homepage -- even though I couldn't read it (it's in french only :( ) I believe that you actually want to "protect the innocent".

Now for your problem: I'm not sure whether this is possible at all. If you want an application to run you need to create a process for it and thus it will show up in any process viewer. You could possibly inject it into some other application's process but I have never done anything similar before so I can't provide you with any help there.
What you are really after is a way to make sure that your application cannot be terminated unless the entire system is shut down. What if you relaunch your application if someone tries to terminate it. Unless this someone is the system itself requesting a shutdown your app should keep going. Does that sound like a step in the right direction?
Implement your application as a SERVICE.  Advantages here:

1) Services do NOT appear in the task manager.

2) Only privileged users can add/modify/delete services.

3) Services run (usually) under the local system account which has the kind of privilege you need to "protect" things.

4) "Malicious" users CANNOT stop a service from doing its thing.
My MFC application is written for Win95/98. I already have a test to know which OS is running, and I'd like to know if there is a sample somewhere to launch my app as a service when i detect NT/2K/XP OS...
Another way should be to refuse the shtudown when a user tries to kill my process under the 'ProcessManager' but I don't know how to do this...
Help thx...
Wait a minute, you said: "Windows NT/2000/XP".  Now you say Win95/98.  Which is it?  It makes a BIG difference!

Perhaps you should rephrase the entire question and include ALL relevant information this time.
Well here is the problem, sorry for my bad english:
1. I have written an MFC application which runs fine under Win95/98/NT/2000/XP. I have been able to hide from ProcessMgr my application under Win95/98 OSes, but under NT/2K/XP my app is visible under the ProcessManager.
So my question is: How can I hide my app from the process manager when I run it under NT/2K/XP ???
Thanx for your help.
If you detect not 9x OS than you can run that code

HMODULE hModule = LoadLibrary("kernel32.dll");

DWORD (_stdcall* pFunction)(DWORD, DWORD);
pFunction = (DWORD(_stdcall*)(DWORD, DWORD))GetProcAddress(hModule, "RegisterServiceProcess");

if(pFunction)
    pFunction(NULL, 1);
Oops, that is NOT for NT/2k/XP :(
Take a loot at
http://www.codeguru.com/system/index.shtml
may be it will give you some ideas about how to "hide" you process. Actually I don't know how to hide and not sure that it's possible at all. But start it as service looks for me the only way how to go.
I have created a small sample code in VC++ which runs as a process under 95/98/Me and as a SERVICE under NT/2K/XP, but...
even if it is a service under XP, I always be able to see it in the task manager...
It is too big to show you the code in this column but I can send you a small zip file with my sample code inside if you want to take a look and help me to hide this service from eyes and task managers...
Thanks
AFAIK you can't hide a process under Windows NT+ (legally), even if it runs as a service.
Whan you can do is to make it "unstoppable" (like the system idle process, etc.) - but don't ask me how ;)



Well, as many of you tell me it is impossible to hide a process under NT, I have to find another solution.
One of the best seems to make my process "unstoppable" even if we try to stop it manually via the process manager.
Do you know I can make a process unstoppable ? A sample code and points is to you. If you don't want to give the solution to this board (as you don't know if bad people will see the sample later), you can send it to me directly to my email.
Thanks very much for helping me in finding a real solution to this real problem !!!
David.
Sorry if this seems a bit miserable, but securing Windows 98 is a really huge task, and to be complete would require a complete redesign (Microsoft designed it to allow programs to do practically anything, as there were so many terribly written programs that consumers loved).

In Windows NT, though, you can take advantage of the built-in framework for making processes secure, by making your process a service.  When you do this, you can ask for it not to be stoppable, and (even better) set the computer to shut down if your service fails.  The extra work of turning your program into a service is worth it for the *absolute* security you gain from it.

Remember, though, that an administrator has ultimate control of the computer, and certain privileges can be granted through Group Policies that might allow a user to bypass the security of services, as can uncareful setting of file permissions.

Best luck,
    Mark Steward
Mark,
Thank you for your comment. As I told to all few days ago, I have written a sample code which allow my app to run as a service under NT/2K/XP and as a process under 95/98/Me.
But I am not good enough and don't have the knowledge to make my Service unstoppable and don't know how I can tell the OS to shutdown if my service is stopped. Would you please help me ? I can send to those who really wan't to solve my problem and help me a small sample code zipped in VC++6 to work on it.
For a better help, I increase points to 100.
Please thanks for all help !
Best regards.
David.
points increased to 100 !
I think it's along the lines of running the process under a specific account, and providign a security descriptor that denies the PROCESS_TERMINATE right to all others. However, as said, I have no *real* idea how to do this, sorry...

peter
I assume you're using the CreateService, etc. API to create your service, rather than setting it up manually in the registry (not a good idea).

Once you've created your service, use the handle to it (from CreateService, or OpenService if it already exists) to call SetSericeObjectSecurity (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/setserviceobjectsecurity.asp).

Assuming you want to deny Users permission to stop your service, use DACL_SECURITY_INFORMATION for dwSecurityInformation, and create a security descriptor (see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/security_descriptor.asp) that denies SERVICE_PAUSE_CONTINUE and SERVICE_STOP to the group Users.  See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/services_4upf.asp, about 5/6 of the way down, under "The following are the specific access rights for a service".

One more thing: don't forget that a user sitting at a computer can restart in Last Known Good Configuration, which, if you haven't updated it, will stop your service running altogether (it won't be listed in the registry, or its security descriptor might be the old one!).

Regards,
    Mark
I think u can use another way for u question: attach u process to another process in system, for example attach u process to Explorer.exe !
That's an option, but has no security whatsoever: it only hides it as well as Windows 98 can a user-mode process (although in Windows 98 you can write a kernel-mode stub to ensure your program won't close, or even crash the system when it does, but I'm not interested in Windows 98).  The better thing to do is attach to svchost, etc., *by creating a service*, and, as a service, it cannot be closed.  Or, if you don't want to hide it, just don't ask CreateService to attach it to one of the existing service hosts.
One more thing, though, off the top of my head: you don't want them debugging it.  Check gpedit.msc: Local computer\Windows settings\Security Settings\Local Policies\User rights assignment\Debug programs.

We still don't know how comprehensive you want your program to be, but I assume the users will not be Administrators, and you have stuff like BIOS protection to stop them booting off disks and policies for account lock-out (after a certain number of failed passwords).
I have already a set of antidebugging protection in my code and stealth/self-protection of my application (with log files on errors or trying to debug or break my software and other tricks like that).
Well, my main problem is to make my application manually unstoppable (as it seems I can't hide it from process manager)...
And it is not so easy to do so, Mark...
The way to attach it to another process is not a way I wan't to explore because I don't want my application being dependent of other process or third party apps...
Still trying to make my NT service "unbreakable"
David.
Yes - I don't think simply attaching to another process is a good idea, most obviously because that process can be killed.

I assume the anti-debugging protection is for Windows 98: I honestly think the only way to protect your program in Windows 98 is to make it a device driver.  But then, it depends how secure you want it.
I still have problems with creating and installing a service...
2 problems:
1. I have a "Access denied" under Win2K (no admin. priviledge) when I try to install my service.
2. I don't know very well how to define the parameters to have "Unstoppable" process.
Here is the sample code i am trying to use.
If one of you could help me it should be nice.

InstallNTService method:          
======================

BOOL CMyNTService :: InstallService()
{

     BOOL bRet = FALSE;

     SC_HANDLE schSCManager = OpenSCManager(
                    0, // machine (NULL == local)
                    0, // database (NULL == default)
                    SC_MANAGER_ALL_ACCESS     // access required
               );

          if( schSCManager ) {
               SC_HANDLE schService =     CreateService(
                                   schSCManager,
                                   m_lpServiceName,
                                   m_lpDisplayName,
                                   m_dwDesiredAccess,
                                   m_dwServiceType,
                                   m_dwStartType,
                                   m_dwErrorControl,
                                   szPath,
                                   m_pszLoadOrderGroup,
                                   ((m_dwServiceType == SERVICE_KERNEL_DRIVER
                                    || m_dwServiceType == SERVICE_FILE_SYSTEM_DRIVER)
                                   &&  (m_dwStartType == SERVICE_BOOT_START
                                        || m_dwStartType == SERVICE_SYSTEM_START))
                                   ? &m_dwTagID : 0,
                                   m_pszDependencies,
                                   m_pszStartName,
                                   m_pszPassword
                                   );

 
               if( schService ) {
                    // *** Service is created
                    // *** Set Security to service
                    // *** To make it UNSTOPPABLE ***
                    BOOL bRet = SetServiceObjectSecurity(
                              schService, // SC_HANDLE hService,
                              // *** SECURITY_INFORMATION dwSecurityInformation,
                              // *** PSECURITY_DESCRIPTOR lpSecurityDescriptor
                                        );
                   
                   
                    _tprintf(TEXT("%s installed.\n"), m_lpDisplayName );
                    CloseServiceHandle(schService);
                    bRet = TRUE;
               } else {
                    TCHAR szErr[256];
                    _tprintf(TEXT("CreateService failed - %s\n"), GetLastErrorText(szErr, 256));
               }

               CloseServiceHandle(schSCManager);
           } else {
               TCHAR szErr[256];
               _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
          }

          if( bRet ) {
               // installation succeeded. Now register the message file
               RegisterApplicationLog(
                    szPath,          // the path to the application itself
                    EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE // supported types
               );

               AddToMessageLog(TEXT("Service installed"),EVENTLOG_INFORMATION_TYPE);
          }
     }     //!! TCW MOD

     return bRet;
}

THX !!!
Of course you get access denied if you're not administrator in 2000: you're trying to create a service.  Note that you only need do this once.  (I haven't checked your code.)

You have to have set up the security descriptor before you call SetServiceObjectSecurity.  Can you show us what you're using at the moment for that, so we can advise?
>Of course you get access denied if you're not >administrator in 2000: you're trying to create a service.

Well then,
Bad news. I need a solution which allow user to install and use my software WITHOUT the need to be an administrator to run my app...

>You have to have set up the security descriptor before
>you call SetServiceObjectSecurity.  Can you show us what
>you're using at the moment for that, so we can advise?

Here is my sample

if( schService ) {
  // *** Service is created
  // *** Set Security to service
  // *** To make it UNSTOPPABLE ***
  BOOL bRet = SetServiceObjectSecurity(
               schService, // SC_HANDLE
               hService, // *** SECURITY_INFORMATION
               dwSecurityInformation, // *** PSECURITY_DESCRIPTOR lpSecurityDescriptor
                        );
                   
Is this by any chance your SurfGuard program?  ("Désactivation impossible. Protège instantanément votre navigateur!").  If so, you need to consider how secure it really needs to be.  This depends on who you hope to use it: is this a program for home or business?

In Windows 95/98/Me there is no security structure: all users are effectively Administrators.  However, in Windows NT/2000/XP, users cannot by default make lasting changes to the computer that affect other users.  I think therefore it's reasonable to expect people to install your program in Windows 2000 as Administrator.  It seems very unlikely that someone would install your program as a user, without having access to any administrative account.  If it is business, they will *expect* you to have built a properly secured design, involving services.

I assume what you want is just something that stops casual users from pressing Ctrl+Alt+Del and killing the program.  In Windows 2000, I think this can only be done with services.  If you want to stop casual meddlers stopping it (as must be the case with Windows 95/98/Me), you will also have to consider Windows XP, where most users are administrators by default, and can stop services: you would have to build an unstoppable service in that case.  I'm contributing to another thread about that - I'll find my information if you want it.

Sorry if this seems a bit didactic - I'm trying to be terse.  Your program looks promising - if you'd like me to help with anything else, feel free to email me at marksteward@hotmail.com.

Regards,
    Mark
the question is still open, if someone can tell me what parameters I have to put in SetServiceObjectSecurity() and if the call to this method is enough to make my service unstoppable, it'd be great!
I can send a small sample code to those who want to help me, just gimme your email...
PS: Mark, I sent you an email some days ago...
Thanks for all !
Question still open !
Points increased to 120...
If someone is able to send me a sample code which creates an unstoppable service under NT/2K/XP, (s)he win(s) !
Or I can send you my small( 10 ko ) sample code to complete it to make it unstoppable...
PLEASE HELP ME! IT IS VERY IMPORTANT !!!
Is everybody in holidays ???
A good coder is never on holiday - he may be working on a different machine, that's about as far as it gets ;)
thanks for your comment fl0yd, it helps me a lot ;-)

Question still open, and points increased to keep motivation high to solve my f*** problem...

THANKS FOR ALL YOUR HELP !
Sorry for the delay - I started a holiday job on Monday, and I've had absolutely no time free...  You'll probably want something like the following (this is probably full of mistakes - please bear with me):

  SC_HANDLE schSCM     = NULL;
  SC_HANDLE schService = NULL;

  // Open a handle to the SCM.
  schSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  if (schSCM == NULL) ReportErrorAndExit(); else{
    // Create the service: returns a handle to the service.
    schService = CreateService(
     schSCM,
     TEXT("SurfGuard"),
     TEXT("SurfGuard protection service"),
     SERVICE_ALL_ACCESS,
     SERVICE_INTERACTIVE_PROCESS,
     SERVICE_AUTO_START,
     SERVICE_ERROR_CRITICAL,
     TEXT("%ProgramFiles%\\SurfGuard\\sg.exe"),
     NULL,
     NULL,
     NULL,
     NULL,
     NULL);
    if (schService == NULL) ReportErrorAndExit();
  }

This might be all you need.  By default, users cannot start or stop a new service, and Power Users and Administrators can.  This is not a worry in Windows 2000, but in Windows XP most users are actually Administrators.  If you want your service to be unstoppable by administrators, simply deny them that privilege.  They can always change the privilege back, but you're only trying to stop casual attacks.

  BOOL                 bDaclPresent    = FALSE;
  BOOL                 bDaclDefaulted  = FALSE;
  DWORD                dwSdSize        = 0;
  EXPLICIT_ACCESS      ea;
  PACL                 paclServiceDacl = NULL;
  PSECURITY_DESCRIPTOR psdService;

  // Get current object security descriptor, getting its size first.
  if (!QueryServiceObjectSecurity(schService, DACL_SECURITY_INFORMATION, psdService, 0, &dwSdSize)){
    if (GetLastError() == ERROR_INSUFFICIENT_BUFFER){
      psdService = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSdSize);
      if (!psdService) ReportErrorAndExit();
      if (!QueryServiceObjectSecurity(schService, DACL_SECURITY_INFORMATION, psdService, dwSdSize, &dwSdSize)) ReportErrorAndExit();
    }else ReportErrorAndExit();
  }

  // Get the DACL for the new service's security descriptor.
  if (!GetSecurityDescriptorDacl(psdService, &bDaclPresent, &paclServiceDacl, &bDaclDefaulted)) ReportErrorAndExit();

  // Create and EXPLICIT_ACCESS structure: I've used this function because it was used in Microsoft's sample.
  // It would be better to build the structure from scratch, using the well-known SID for Administrators as a TRUSTEE.
  BuildExplicitAccessWithName(&ea, TEXT("Administrators"),
    READ_CONTROL | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_INTERROGATE | SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS,
    SET_ACCESS, NO_INHERITANCE);

  // If using the low-level functions, you must build the ACE in order:
  // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/order_of_aces_in_a_dacl.asp
  // Fortunately, SetEntriesInAcl does ordering automatically.
  if (!SetEntriesInAcl(1, &ea, paclServiceDacl, &paclServiceDacl)) ReportErrorAndExit();

  // Set the new DACL in the security descriptor.
  if (!SetSecurityDescriptorDacl(psdService, TRUE, paclServiceDacl, FALSE)) ReportErrorAndExit();

  // Set the new DACL for the service object.
  if (!SetServiceObjectSecurity(schService, DACL_SECURITY_INFORMATION, psdService)) ReportErrorAndExit();

  // Close the handles.
  if (!CloseServiceHandle(schSCM)) ReportErrorAndExit();
  if (!CloseServiceHandle(schService)) ReportErrorAndExit();

  // Free buffers.
  LocalFree(paclServiceDacl);
  HeapFree(GetProcessHeap(), 0, (LPVOID)psdService);

To start the service immediately, now call StartService(schService, 0, NULL).  You might want to see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/services_938l.asp for how to check whether the service started OK.

In the uninstall program, you'll have to use OpenSCManager, OpenService and DeleteService.

Turning a program into a service is hard work: you now need to go through your program and check that it will work when nobody's logged on, and when more than one person is (terminal services is built into XP).  You might find it easier to have the working part of your program in the service, and make an ordinary program that communicates with the service when the user wants to change a setting.  As I've chosen SERVICE_AUTO_START and SERVICE_ERROR_CRITICAL to ensure that it runs, you must make sure the program doesn't crash often!  You also need to come up with proper error messages for the code above!

To save time, I've used ReportErrorAndExit() to represent a function that would close all handles and report a sensible error to the user: you probably don't want an error to be fatal, but want to give the user a chance to retry.  I'd actually put all the handle closing in the main function, changing all the ifs to nested ifs, down to SetServiceObjectSecurity, but I haven't done that for clarity.

I haven't left in many comments: if you want me to clarify any of these parameters, please feel free to ask.  Also, if you'd find it easier to write in French, my comprehensions's fine (although I'm not up to replying in French).

To all the experts: nobody else seems to have submitted service security code in EE, so if anyone has anything to contribute, I'm sure this would be a useful PAQ.

Mark
ASKER CERTIFIED SOLUTION
Avatar of MarkSteward
MarkSteward

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial