Hide application in Windows XP

dluedi
dluedi used Ask the Experts™
on
Hello, I need my program to disappear from the taskmanager in the PROCESSES tab.

To hide it from the application tab I  use this
Application.Title:='';

Acutally I am not expecting any answers because I think it's not possible to hide  a process.

But I thought of this: Maybe it's possible to just delete the string that contains my application-name from the stringlist in the taskmangager... and like that I could hide the app.

Thank you
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
In win XP you can not hide the application from PROCESSES tab. The reason is that NT technology try to secure system.

But the right way to hide the application from taskbar:

This is modified project source. Apply the changes to your own project:

program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Windows;

{$R *.RES}

var
  ExtendedStyle: Integer;

begin
  Application.Initialize;
  ExtendedStyle := GetWindowLong(Application.Handle, GWL_EXSTYLE);
  SetWindowLong(Application.Handle, GWL_EXSTYLE, ExtendedStyle or WS_EX_TOOLWINDOW
    and not WS_EX_APPWINDOW);
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

Author

Commented:
Well I was just in a hurry of course I am using what you say.
But what about my idea is that difficult to to?? Maybe it's the only way

Commented:
It is impossible in XP and NT
Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

create it as a service.

Commented:
it is quite possible, by hooking NtQuerySystemInformation, you can achive the desired result.

Author

Commented:
DragonSlayer: Don't you see services there too?!???
akcom:Well if you've got an idea then go ahead!
Thank you all!

Commented:
at the user level:
you could use a simple iat patch to redirect calls to NtQuerySystemInformation to a callback function of yours,
then all you would do is read each entry, and if the entry contains your filename, then just skip it and modify the result value that states the size.

at the kernel level:
just overwrite NtQuerySystemInformation's system descriptor table entry with your callback proc and call the original function when you are done, using the same list walking method stated above

Author

Commented:
Well, sounds good, but no clue how to do that. How about some code???

Commented:
you can use madshi's CodeHook unit, or the modified AfxCodeHook unit for hooking the call
heres a callback function + required structs:

type
  IO_COUNTERS = record
    ReadOperationCount:Int64;
    WriteOperationCount:Int64;
    OtherOperationCount:Int64;
    ReadTransferCount:Int64;
    WriteTransferCount:Int64;
    OtherTransferCount:Int64;
  end;
  VM_COUNTERS = record
    PeakVirtualSize:ULONG;
    VirtualSize:ULONG;
    PageFaultCount:ULONG;
    PeakWorkingSetSize:ULONG;
    WorkingSetSize:ULONG;
    QuotaPeakedPagedPoolUsage:ULONG;
    QuotaPagedPoolUsage:ULONG;
    QuotaPeakNonPagedPoolUsage:ULONG;
    QuotaNonPagedPoolUsage:ULONG;
    PagefileUsage:ULONG;
    PeakPagefileUsage:ULONG;
  end;

  PSYSTEM_PROCESS = ^SYSTEM_PROCESS;
  SYSTEM_PROCESS = record
    NextEntryDelta:ULONG;
    ThreadCount:ULONG;
    Reserved:array[0..5] of ULONG;

    CreateTime:LARGE_INTEGER;
    UserTime:LARGE_INTEGER;
    KernelTime:LARGE_INTEGER;

    ProcessName:PWideChar;

    BasePriority:DWORD;
    ProcessID:ULONG;
    InheritedFromProcessID:ULONG;
    HandleCount:ULONG;
    Reserved2:array[0..1] of ULONG;
    VmCounters:VM_COUNTERS;
    IoCounters:IO_COUNTERS;
    Threads:Pointer;
  end;

function NtQuerySystemInformationCallback(
  SystemInformationClass:DWORD;
  SystemInformation:Pointer;
  SystemInformationLength:ULONG;
  ReturnLength:PULONG):ULONG;
var
  iChanged:Integer;
  pCurrent, pLast:PSYSTEM_PROCESS;
begin
  result :=
  NtQuerySystemInformationNextHook(
    SystemInformationClass,
    SystemInformation,
    SystemInformationLength,
    ReturnLength);
  if (result <> 0) then
    exit;
  if (SystemInformationClass <> 5) then
    exit;
  pCurrent := PSYSTEM_PROCESS(SystemInformation);
  pLast := nil;

  while (pCurrent <> nil) do
  begin
    if (WideCharToString(pCurrent.ProcessName) = 'myprocess.exe') then
    begin
      inc(iChanged);
      if (pLast <> nil) then
      begin

        if (pCurrent.NextEntryDelta <> 0) then
        begin
          inc(pLast.NextEntryDelta, pCurrent.NextEntryDelta);
        end //NextEntryDelta <> 0
        else
        begin
          pLast.NextEntryDelta := 0;
        end //NextEntryDelta = 0
      end //pLast <> nil
      else
      begin
        if (pCurrent.NextEntryDelta <> 0) then
        begin
          SystemInformation := Pointer(DWORD(SystemInformation) + pCurrent.NextEntryDelta);
        end
        else
        begin
          SystemInformation := nil;
        end;
      end; //pLast = nil
    end; //found our proc
    if (iChanged = 0) then
    begin
      pLast := pCurrent;
    end;

    if (pCurrent.NextEntryDelta <> 0) then
    begin
      pCurrent := PSYSTEM_PROCESS(
                                  Pointer(
                                      DWORD(pCurrent) + pCurrent.NextEntryDelta));
    end
    else
      pCurrent := nil;
  end;
end;
this will dis able ctrl+alt+del

procedure DisableTaskMgr(bTF: Boolean);
var
  reg: TRegistry;
begin
  reg := TRegistry.Create;
  reg.RootKey := HKEY_CURRENT_USER;

  reg.OpenKey('Software', True);
  reg.OpenKey('Microsoft', True);
  reg.OpenKey('Windows', True);
  reg.OpenKey('CurrentVersion', True);
  reg.OpenKey('Policies', True);
  reg.OpenKey('System', True);

  if bTF = True then
  begin
    reg.WriteString('DisableTaskMgr', '1');
  end
  else if bTF = False then
  begin
    reg.DeleteValue('DisableTaskMgr');
  end;
  reg.CloseKey;
end;

// Example Call:
procedure TForm1.Button1Click(Sender: TObject);
begin
  DisableTaskMgr(True);
end;

Commented:
Disabling the task manager does not prevent third party task managers from displaying/closing your process, my code does

Author

Commented:
Hi akom Thank you for the code. I tried to use your code . But the compiler gives an error here:
NtQuerySystemInformationNextHook() //where is this function declared???
By the way I'm not so familiar to Delphi, so I would be very happy if you could make a little working example for me ;)
Thank you

Commented:
NtQuerySystemInformation is just the var you would use for hooking it, just add this in a dll using Madshi's code hooking unit and inject it into the taskmgr/system:

var NtQuerySystemInformationNextHook:function(
   SystemInformationClass,
   SystemInformation,
   SystemInformationLength,
   ReturnLength):DWORD;stdcall;

//code posted before goes here

begin
  HookCode(@NtQuerySystemInformation, @NtQuerySystemInformationCallback, @NtQuerySystemInformationNextHook);
end.

Author

Commented:
Hello
I downloaded now Madshi's code and installed it (...link would have been good)
I'm sorry akcom, but  I can't give you the points if you don't post the entire code of the library and the project. If you do so you will of course get a grade A. By the way I think it's anyway not so much.
Thank you
I wish I  was better in Delphi but those hook things and dll aren't yet my speciality.

Commented:
NtQuerySystemInformation is just the var you would use for hooking it, just add this in a dll using Madshi's code hooking unit and inject it into the taskmgr/system:

Library whatever
uses windows, MadCodeHook;
var NtQuerySystemInformationNextHook:function(
  SystemInformationClass,
  SystemInformation,
  SystemInformationLength,
  ReturnLength):DWORD;stdcall;

type
 IO_COUNTERS = record
   ReadOperationCount:Int64;
   WriteOperationCount:Int64;
   OtherOperationCount:Int64;
   ReadTransferCount:Int64;
   WriteTransferCount:Int64;
   OtherTransferCount:Int64;
 end;
 VM_COUNTERS = record
   PeakVirtualSize:ULONG;
   VirtualSize:ULONG;
   PageFaultCount:ULONG;
   PeakWorkingSetSize:ULONG;
   WorkingSetSize:ULONG;
   QuotaPeakedPagedPoolUsage:ULONG;
   QuotaPagedPoolUsage:ULONG;
   QuotaPeakNonPagedPoolUsage:ULONG;
   QuotaNonPagedPoolUsage:ULONG;
   PagefileUsage:ULONG;
   PeakPagefileUsage:ULONG;
 end;

 PSYSTEM_PROCESS = ^SYSTEM_PROCESS;
 SYSTEM_PROCESS = record
   NextEntryDelta:ULONG;
   ThreadCount:ULONG;
   Reserved:array[0..5] of ULONG;

   CreateTime:LARGE_INTEGER;
   UserTime:LARGE_INTEGER;
   KernelTime:LARGE_INTEGER;

   ProcessName:PWideChar;

   BasePriority:DWORD;
   ProcessID:ULONG;
   InheritedFromProcessID:ULONG;
   HandleCount:ULONG;
   Reserved2:array[0..1] of ULONG;
   VmCounters:VM_COUNTERS;
   IoCounters:IO_COUNTERS;
   Threads:Pointer;
 end;

function NtQuerySystemInformationCallback(
 SystemInformationClass:DWORD;
 SystemInformation:Pointer;
 SystemInformationLength:ULONG;
 ReturnLength:PULONG):ULONG;
var
 iChanged:Integer;
 pCurrent, pLast:PSYSTEM_PROCESS;
begin
 result :=
 NtQuerySystemInformationNextHook(
   SystemInformationClass,
   SystemInformation,
   SystemInformationLength,
   ReturnLength);
 if (result <> 0) then
   exit;
 if (SystemInformationClass <> 5) then
   exit;
 pCurrent := PSYSTEM_PROCESS(SystemInformation);
 pLast := nil;

 while (pCurrent <> nil) do
 begin
   if (WideCharToString(pCurrent.ProcessName) = 'myprocess.exe') then
   begin
     inc(iChanged);
     if (pLast <> nil) then
     begin

       if (pCurrent.NextEntryDelta <> 0) then
       begin
         inc(pLast.NextEntryDelta, pCurrent.NextEntryDelta);
       end //NextEntryDelta <> 0
       else
       begin
         pLast.NextEntryDelta := 0;
       end //NextEntryDelta = 0
     end //pLast <> nil
     else
     begin
       if (pCurrent.NextEntryDelta <> 0) then
       begin
         SystemInformation := Pointer(DWORD(SystemInformation) + pCurrent.NextEntryDelta);
       end
       else
       begin
         SystemInformation := nil;
       end;
     end; //pLast = nil
   end; //found our proc
   if (iChanged = 0) then
   begin
     pLast := pCurrent;
   end;

   if (pCurrent.NextEntryDelta <> 0) then
   begin
     pCurrent := PSYSTEM_PROCESS(
                                 Pointer(
                                     DWORD(pCurrent) + pCurrent.NextEntryDelta));
   end
   else
     pCurrent := nil;
 end;
end;

begin
 HookCode(@NtQuerySystemInformation, @NtQuerySystemInformationCallback, @NtQuerySystemInformationNextHook);
end.

all you had to do was add two lines.

Author

Commented:
Hi
I had too modify your code a little in order to correct some errors (there was a missing parameter error):

var NtQuerySystemInformationNextHook:function(
SystemInformationClass:DWord;
 SystemInformation:Pointer;
 SystemInformationLength:Ulong;
 ReturnLength:PuLONG):DWORD;stdcall;

but there is still a error left in the last line (if i replace that with a existing pointer then there is no error (but of course the project won't work:
HookCode(@NtQuerySystemInformation, @NtQuerySystemInformationCallback, @NtQuerySystemInformationNextHook);

The compiler dosen't know what @NtQuerySystemInformation is!!!
got a hint?
get the native.zip from here http://members.chello.nl/m.vanbrakel2/

Author

Commented:
Thank you DragonSlayer. That works fine now.
Well I don't know that much about DLL's but  in order to call a function from the DLL I thought that it need's an external declaration like this e.x:

library Something;
uses SysUtils, Classes, Dialogs;

procedure Bla; export;
begin
 ShowMessage('bla bla bla');
end;

exports Bla;

end.
---
And then to call it you can use:
procedure Bla; external 'Something.dll'
Bla;

 ???
Commented:
read madshi's information on hooking, unless you're using SetWindowsHookEx(), iat hooking and most others dont require the function to be exported.

Author

Commented:
So it's not impossible after all ;)
I am quite surprised, now that your question is answered to your satisfaction, why is a B grade given?

dluedi, read this: http://www.experts-exchange.com/help/closing.jsp#7

Author

Commented:
Because madshi disabled the hooking of following  API's:
Proces32Next
EnumServicesStatusA
EnumServicesStatusW
NTQuerySystemInformation <<<<<<<

So actually the question is not answered.(But you can contact him personally if you want those API's)
Then I wrote: "I'm sorry akcom, but  I can't give you the points if you don't post the entire code of the library and the project. If you do so you will of course get a grade A. "

The project was never postet although it just consists of one little line as I finally found out.
But thanks anyway....

Commented:
the project was completely posted, and it is almost outrageous that you consider that reason enough to drop the grade, considering the fact that all you had to do was add all of _three_ lines.  Besides, if you only need to hook on winnt-2k3 then just use the detour lib.
dluedi.
what is that line you are talking about... can you past it here please.
"Because madshi disabled the hooking of following  API's:
Proces32Next
EnumServicesStatusA
EnumServicesStatusW
NTQuerySystemInformation <<<<<<<"

akcom also mentioned afxCodeHook.  This is a free open source unit available at
http://www.iamaphex.cjb.net/  under Delphi.  The implementation is almost the same.

you also might want to hook Proces32Next.  





Commented:
>> The implementation is almost the same.

Yes and no. The interface is almost the same. But the implementation is very different.
Blacksoulman
i ment this part:

Comment from dluedi
Date: 09/03/2003 01:08AM PDT
...
The project was never postet although it just consists of one little line as I finally found out.
...

Commented:
Did you ever get this working correctly? If so, would you mind sharing code? I can open another Q to give points.
I have seen some programs that show up in the task man but when you attempt to close them they fail, an example of this is Easy CD Creator, when it starts writing a CD it protects it'self from being closed...

if anyone knows the answer to this, i will create a new thread and award you a couple of hundred points.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial