LVM_FINDITEM from task manager.

I am creating an application which queries windows using pdm to find out specifics for memory usage, processes, etc. and then has flags for when criteria are met.  It also monitors what windows are open, etc. and will be deployed in call centers on call agents computers and is meant as an application to help managers see what all their agents are doing and what resources they are using.  One of the requirements we have heard is for the user to be unaware of the application, which is easy for the most part but it still shows up in the processes list under task manager.  I know this is going to raise up questions of why I want to remove the item from the task manager but it is for a legitimate purpose for which the company whose computers this application is going onto will be aware of what all the application will do and will put it on there willingly.  With that said I am trying to use LVM_FINDITEM.  Here is my code that I have wrote into a really basic test app to try to do it:


#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <commctrl.h>
using namespace std;
#define TASKMGR_FIND_TIMER  101

string m_status;
BOOL CALLBACK EnumChildProcedure(HWND hWnd,LPARAM lParam)
{
      char name[256];
      GetWindowText(hWnd,name,256);

      char ClassName[256];
      GetClassName(hWnd,ClassName,256);
      
      int test = 0x1000 + 28;
      if((strcmp(ClassName,"SysListView32")==0)&&(strcmp(name,"Processes")==0))
      {
            DWORD pid;
            GetWindowThreadProcessId(hWnd, &pid);
            HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS, false, (DWORD)pid);

            if(proc > 0)
            {
                  DWORD written;

                  LVFINDINFO info;
                  
                  ZeroMemory(&info, 0, sizeof(LVFINDINFO));
                  info.flags = LVFI_STRING | LVFI_PARTIAL;
                  info.lParam = NULL;
                  info.vkDirection = VK_DOWN;
                  info.psz = (LPCSTR)"HideTaskManager.exe";
                  
                  //LPVOID m_hBufferMem = VirtualAllocEx(proc, 0, 255, MEM_COMMIT, PAGE_READWRITE);
                  LPVOID address = VirtualAllocEx(proc, 0, sizeof(info), MEM_COMMIT, PAGE_READWRITE);
                  WriteProcessMemory(proc,address,&info,sizeof(LVFINDINFO),&written);
                  int iIndex = ::SendMessage(hWnd, LVM_FINDITEM, -1, (LPARAM)address);
                  if(iIndex > 0)
                        ::SendMessage(hWnd, LVM_DELETEITEM, iIndex, 0);                        
            }
      }

      if((strcmp(ClassName,"SysListView32")==0)&&(strcmp(name,"Tasks")==0))
      {
            ::SendMessage(hWnd,0x1000 + 28,(WPARAM)5,0);
      }

      if(name==NULL)
            return FALSE;
      return TRUE;
}

void DetectTM()
{
      HWND hWnd = NULL;
      hWnd = ::FindWindow(NULL,"Windows Task Manager");
      if(!hWnd)
      {
            m_status = "Status : Task Manager NOT found";
            return;
      }                  
      m_status = "     Status : Task Manager Found     ";
    EnumChildWindows(hWnd,EnumChildProcedure,NULL);
}


int _tmain(int argc, _TCHAR* argv[])
{
      bool hasFound = false;
      while(!hasFound)
      {
            DetectTM();
            cout << m_status.c_str() << endl;
            m_status = "";
            Sleep(1000);
      }
      return 0;
}


I have tried googling and hunting through forums but to no avail.  If anyone could please offer help I would be most appreciative.  Thanks in advance.

Matt
cc_devAsked:
Who is Participating?
 
mrwad99Connect With a Mentor Commented:
Matt

I have been playing with this as not knowing the answer was bugging me :o)

The problem lies in the fact that you are passing a pointer to a string in your LPFINDINFO structure:

>> info.psz = (LPCSTR)"HideTaskManager.exe";

You correctly allocate memory for your LVFINDINFO in the context of the task manager process, but fail to allocate memory for this string also.  So when the SendMessage gets called, you are passing a valid LVFINDINFO that contains an invalid location as the psz member.  Do this instead:

TCHAR szBuff [ 128 ];
_tcscpy_s ( szBuff, _T("HideTaskManager.exe") );
LPVOID szText = VirtualAllocEx ( proc, 0, sizeof ( szBuff ), MEM_COMMIT, PAGE_READWRITE );
BOOL b = WriteProcessMemory( proc, szText, &szBuff, sizeof ( szBuff ), &written );

ZeroMemory ( &info, sizeof ( LVFINDINFO ) );      // Only two parameters here: you had three!
info.flags = LVFI_STRING;
info.lParam = NULL;
info.vkDirection = VK_DOWN;
info.psz = ( LPCSTR ) szText;  // !!

// etc

I tried this and it worked for me :)
0
 
mrwad99Commented:
Still looking at your code, but have you looked at

http://www.codeproject.com/KB/system/Hack_Windows_Task_Manager.aspx

?
0
 
mrwad99Commented:
PS

>> if(iIndex > 0)

must be

if(iIndex > -1 )

as the original code will not work if the item is located first in the list (i.e. at index 0!)
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
cc_devAuthor Commented:
Wow.  That made me feel quite silly ;).  Thanks for the help.  That worked like a charm.
0
 
cc_devAuthor Commented:
Thanks again!
0
 
mrwad99Commented:
No problem; glad to help, and welcome to EE :)
0
All Courses

From novice to tech pro — start learning today.