Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.02.2009, 15:15   #1
123321
 
Регистрация: 09.12.2007
Сообщений: 5
По умолчанию Перехват функций

Проблема в следующем.
Пишу на vc 2005 под XP программу которая в диспетчере задач скрывает свой процесс.
Решил пойти в лоб, получил указатель на диспечер задач, далее указатель на ListCntl (Процессы). С помощью SendMessage там можно удалять любую строку, но функции GetItemText, FindItem при выполнение программы выдают ошибку.
Есть другой способ удалить свой процесс путем перехвата функции Hook_NtQuerySystemInformation. Проблема в том, что с перехватом никогда не работал, так что жду совета.
Перелапатил весь интернет, много примеров на Delphi, даже на этом форуме, но с этим языком не дружу.
Если есть другие предложения по скрытию процесса, то буду рад.
Одно пожелание, чтобы не использовались подключаемые dll библиотеки и без регистрации драйверов.
123321 вне форума Ответить с цитированием
Старый 09.02.2009, 15:48   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
но функции GetItemText, FindItem при выполнение программы выдают ошибку.
Ошибка видимо невидимая? Текст ее что привести не посчастливится?
Да и код свой показать не лишне будет
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 09.02.2009, 16:53   #3
123321
 
Регистрация: 09.12.2007
Сообщений: 5
По умолчанию

код следующий
Код:
// найдем и уничтожим  строку в диспечере задач
// ищем диспетчер задач и вызываем функцию поиска дочерних окон 
	HWND Wnd_DZ;
	Wnd_DZ = ::FindWindow(0,_T("Диспетчер задач Windows"));
	if(Wnd_DZ)
	{
		EnumChildWindows(Wnd_DZ,&EnumChildWnd,0);
                      	
	}
// код самой процедуры:
BOOL CALLBACK EnumChildWnd(HWND hwnd,	LPARAM lParam	)
{
	if (hwnd==0)return TRUE;
	WCHAR WinZag[100] =_T(" ");
	SendMessage(hwnd, WM_GETTEXT,100 , (LPARAM)&WinZag);
	CString Str_Temp=WinZag; // запоминаем загорловок окна
	if(Str_Temp == _T("Процессы"))
	{
		CWnd wd;
		wd.m_hWnd = hwnd;
		
		//ListView_DeleteItem( hwnd,0); // удаляем строку
                       //int hh = ListView_GetItemCount(   hwnd);
                         // эти две функции отлично работают
		LPCTSTR lpszmyString;
		lpszmyString = _T("kav.exe");
		LVFINDINFO info;
		info.flags = LVFI_PARTIAL|LVFI_STRING;
		info.psz = lpszmyString;
		int m_Item = ListView_FindItem(hwnd, -1,  &info);
                      // возвращаем номер строки процесса касперского
	}

	return TRUE;
}
На выполнение команды ListView_FindItem(hwnd, -1, &info) Диспетчер задач вылетает. vc не возвращает код ошибки.

Модератор: тег CODE

Последний раз редактировалось MaTBeu; 09.02.2009 в 22:23.
123321 вне форума Ответить с цитированием
Старый 09.02.2009, 17:01   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Где-то я уже подобное слышал. Кому-то уже посоветовали не морочить голову с диспетчером таким образом.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 09.02.2009, 17:06   #5
123321
 
Регистрация: 09.12.2007
Сообщений: 5
По умолчанию

Так я и хочу по другому. Есть предложения?
123321 вне форума Ответить с цитированием
Старый 15.02.2009, 10:54   #6
StormBS
Новичок
Джуниор
 
Регистрация: 09.02.2009
Сообщений: 2
По умолчанию

Немного помучился и решил свою проблему несколькими способами.
Пересмотрев все сообщения, которые принимает ListCntl, оказалось, что все не так просто. Проблема возникает, если мы пытаемся передать в качестве параметра адрес на какую-либо область памяти. К примеру, чтобы удалить себя из списка можно воспользоваться сообщением LVM_DELETEITEM. Но его первый параметр это индекс элемента, который нужно удалить. А необходимо спрятать только один процесс, оставив остальные. Тут возникает естественный вопрос о том, как узнать свой индекс из списка. Для этого используется сообщение LVM_GETITEM, но его второй параметр это указатель на структуру с требуемой информацией. Если вы попытаетесь воспользоваться им, указав на область памяти вашего приложения, то это вызовет ошибку и возможно крушение менеджера. Если бы вы имели высокие права, то для этих целей можно было бы выделить область памяти внутри диспетчера задач, но увы, их нет…

После длительных поисков меня заинтересовало сообщение LVM_GETITEMSTATE, которое возвращает информацию о некоторых свойствах элемента как правду или ложь. Например, чтобы узнать выделен 5-й элемент или нет, достаточно исполнить:

i
Код:
f( SendMessage( hSysList,LVM_GETITEMSTATE, 5 , LVIS_SELECTED ) )
{ // да выделен… }
Теперь немного объясню, чем именно оно меня заинтересовало. Дело в том, что если вы просматриваете список процессов, то можете с легкостью находить интересующие вас процессы просто набирая первую часть его имени. Этот механизм позволяет делать удобную навигацию по спискам, но кроме этого может пригодиться для наших целей. Если вы еще не догадались, что я имею в виду, то вспомните о сообщении WM_CHAR. Оно сообщает окну о нажатии той или иной клавиши. А если нам известно, что нужно прятать процесс “ICQ.EXE”, значит необходимо послать диспетчеру последовательность символов: “I”,”C”,”Q”,”.”,”E”,”X”,”E”. После этого выделенным станет нужный элемент, а узнать его индекс можно последовательно спрашивая каждый элемент активен ли он. И если мы нашли выделенный, значит это “ICQ.EXE” и его нужно удалить.

Код:
void TypeName( HWND hControl,char* chString )
{
for(int index=0;index<int(strlen(chString));++index)
SendMessage( hControl, WM_CHAR, chString[index],0x00210001);
}
TypeName( hSysList, (char*)lpProcess );
printf( "Disclosing index of \'%s\'\n", lpProcess );
int intLeftItemsCount = (int)SendMessage( hSysList, LVM_GETITEMCOUNT, 0, 0 );
while( intLeftItemsCount )
{
if( SendMessage( hSysList,LVM_GETITEMSTATE, intLeftItemsCount, LVIS_SELECTED ) )
{
SendMessage( hSysList, LVM_DELETEITEM, intLeftItemsCount, 0 );
printf( "\'%s\' deleted from the list\n", lpProcess );
break;
}
--intLeftItemsCount;
}
Правда есть небольшая проблема, после первого же обновления списка процессов “ICQ.EXE” снова станет виден. Я вышел из этой проблемы радикально. В меню диспетчера есть меню для настройки частоты обновления списка. Поскольку соответствующие меню активизируются через сообщения WM_COMMAND, то ничто не мешает принудительно послать команду окну, так как если бы это сделал локальный пользователь.
Код:
const LPARAM IDM_PAUSED = 40025;
SendMessage( hTaskMan, WM_COMMAND, IDM_PAUSED, 0 );
printf( "List updating disabled\n" );
Воспользовавшись этими наработками вы можете с легкостью спрятать свой процесс. Только следует заметить, что перед манипуляциями с окном его лучше спрятать (SW_HIDE) еще до его появления на экране.
Спасибо Digital Scream за подсказку.
Чуть позже вылажу решение скрытия процесса с помощью глобального хука.


Модератор: тег CODE

Последний раз редактировалось MaTBeu; 15.02.2009 в 11:10.
StormBS вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
обновление в блоге - Перехват API функций. Основы Pblog Обсуждение статей 0 20.01.2009 10:40
Перехват API функций satana Win Api 4 21.08.2007 20:12
хттп перехват infected Работа с сетью в Delphi 1 09.07.2007 07:58
перехват трафика Roman Работа с сетью в Delphi 6 27.06.2007 08:51
Перехват Апи-функций доступа к файловой сиcтеме Coffein Win Api 3 18.06.2007 20:27