ANTICHAT

ANTICHAT (https://forum.antichat.xyz/index.php)
-   Статьи (https://forum.antichat.xyz/forumdisplay.php?f=30)
-   -   Пишем бот Win программ. (Комикс в картинках). (https://forum.antichat.xyz/showthread.php?t=253765)

IIIMbIrA 17.01.2011 08:05

Разберём технологию написания бота. Когда мне понадобился такой бот, я похожей

статьи не нашёл (может плохо искал - теперь уже неважно). Бота я написал, пусть

будет теперь и статья.

Что нам понадобится?

1) Spy++ (Входит в состав MS Visual Studio).

2) Любая среда программирования, которая позволяет обращаться к Windows API. Лично я считаю

что работать с API и не иметь нормальных указателей - это не правильно. Поэтому я буду

пользоваться С++ Builder.

Будем писать бота для программы "МегаФон Интернет", которая будет автоматически рассылать

СМС. Точнее сказать программу то я уже написал давно, целей своих не добился (СМС-спам

рассылка), т. к. реальная скорость рассылки не превышает 10-15 СМС в минуту. Но полученный

опыт, как говориться, не пропьёшь.

Немного теории. Все элементы интерфеса программ Windows: кнопки, поля для ввода, меню, ...

все они являются окнами. Окну можно передавать сообщения функциями SendMessage(),

PostMessage(). Например SendMessage(ht, WM_LBUTTONDOWN, 0, 0) - нажатие левой кнопки

мыши на окне ht. Что такое ht? А это и есть главный описатель/указатель/идентификатор

окна - хэндл. Таким образом написание бота это поиск хэндлов нужных элементов и отправка

этим элементам нужных сообщений. Ещё важно напомнить что все окна в Windows выстроены в

древовидную структуру. Корень дерева - рабочий стол (его хэндл можно получить функцией

GetDesktopWindow()). Имея хэндл окна можно обратиться к соседнему окну справа, слева, выше

или ниже в дереве. Можно при желании обойти всё дерево. Это нам не понадобиться, а вот

определить положение нужного элемента относительно главного окна программы и затем

добраться до его хэндла, имея хэндл главного окна - это как раз то, чем и придётся

заниматься.

Начнём. Создаём проект и пишем такой код:

Код:

HWND ht
        ht = FindWindow(NULL, "МегаФон Интернет");

То есть ищем хэндл главного окна программы, по его имени.

Включаем Spy++.Находим там нашу программу.

http://s002.radikal.ru/i198/1101/0b/6dda61f2e235.jpg

Для отправки СМС нам нужно сначала нажать кнопку "Новое".

http://s61.radikal.ru/i172/1101/13/0e1f3c9e2d69.jpg

Ищем её смещение относительно главного окна. Для этого перебираем все окна поддерева нашей

программы. И задаём в Spy++ вести лог событий для окна. И будем выводить в этот лог

только сообщение нажатия левой кнопки мыши WM_LBUTTONDOWN. CTRL+M вкладка Messages.

На вкладке Window ставим галочку Child Window. Это значит, что в лог будет записываться

не только сообщения для выбранного окна, а для всего поддерева. Так мы быстрее доберёмся

до нужного элемента.

http://i003.radikal.ru/1101/d8/f26a51518082.jpg

Выбираем первое поддерево программы. Настраиваем лог, как я написал. Запускаем Spy++.

Нажимаем кнопку - ничего не пишется значит не то поддерево. Берём следующее поддерево.

Оп, вот оно сообщение.

http://s15.radikal.ru/i189/1101/ea/68370110d514.jpg

Дальше раскрываем поддерево и делаем всё тоже самое для его веток.

Так постепенно добираемся до самого нужного окна - кнопки "Новое". То есть мы нашли его

смещение относительно главного окна.

http://s014.radikal.ru/i329/1101/00/c8c6b9105241.jpg

Чтобы программно симитиривать нажатие левой кнопки мыши на кнопке "Новое", добираемся

до её хэндла. Будет выглядеть примерно так:

Код:

ht = FindWindow(NULL, "МегаФон Интернет");
        ht = GetWindow(ht, GW_CHILD);
        ht = GetWindow(ht, GW_HWNDNEXT);
          ht = GetWindow(ht, GW_CHILD);
          ht = GetWindow(ht, GW_HWNDNEXT);
          ht = GetWindow(ht, GW_CHILD);
            ht = GetWindow(ht, GW_CHILD);
            ht = GetWindow(ht, GW_HWNDNEXT);
            ht = GetWindow(ht, GW_HWNDNEXT);
            ht = GetWindow(ht, GW_HWNDNEXT);
            ht = GetWindow(ht, GW_HWNDNEXT);
            ht = GetWindow(ht, GW_HWNDNEXT);
            ht = GetWindow(ht, GW_CHILD);
              ht = GetWindow(ht, GW_CHILD);

GW_HWNDNEXT - получаем хэндл следующего окна на том же уровне дерева. GW_CHILD - получаем

хэндл первого окна, на следующем уровне дерева.

Отправляем сообщения:

Код:

SendMessage(ht, WM_LBUTTONDOWN, 0, 0);
        SendMessage(ht, WM_LBUTTONUP,  0, 0);

Кнопку нужно не только нажать но и отпустить.

После этого у нас выскакивает новое окно, которое так и называется "Новое". Ищем его в

трее Spy++. На этом окне нам нужно будет вбивать номера телефонов, текст самого

сообщения и нажимать кнопку "Отправить". Как нажимать кнопку объяснять ещё раз не буду.

Не буду объяснять и как найти хэндлы нужных элементов - всё как в первом случае. А вот

как вписать текст в поле для ввода объясню:

Код:

SendMessage(ht, WM_SETTEXT, 0, LPARAM("Превед!"));
Вот почти и всё, но не совсем. Прежде чем отправлять следуещее СМС, нужно дождаться

окончания отправки текущего СМС. Это называется интерактивность. Я это решил просто.

Пока окно "Новое" открыто, СМС ещё отправляется, когда окно закроется - СМС отправлено:

Код:

for(;;)
                if(FindWindow(NULL, "Новое") == NULL) break;

Вот и всё.

Конечно задачи ботов могут быть намного сложнее. Например если нужно не дожидаясь

завершения одного действия начинать второе - тогда нужны потоки. Определить завершение

действия тоже может быть сложной задачей. Например по завершению действия, какой нибудь

значёк может окраситься в другой цвет. Но если есть Spy++, зацепиться всегда есть за что.

Самое гавное забыл написать - есть программы для написания простого бота (типа

запись макроса в MS Word). Можете их нагуглить и скачать. Вот только проблему

интерактивности они не решают, потоки в них также не создашь.

Всем удачи!

yak 17.01.2011 09:47

Писал такого бота года три назад для прибивания надоедливого окошка, когда закачиваешь много шрифтов разом и для автоматического нажатия кнопки "удалить" при обнаружении вируса в каспере. Только я пользовался не Spy++, какой-то самопальной программой, исходники которой были на пиратском диске со студией. Эта софтина позволяла искать данные любого окна, наводя на него мышкой, а не перекапывая 9000 логов.

IIIMbIrA 17.01.2011 14:22

to yak

Да в общем и в Spy++ есть Finder Tool. Зажимаешь его мышью и наводишь на элементы управления. Но им можно до нужной кнопки и не добраться. Например если кнопка находится на Toolbar, но не является его CHILD WINDOW. Он найдёт только Toolbar, а кнопка будет в другом поддереве. Так что вопрос этот мутный и я сомневаюсь, что есть такая программа, которая прям от корня до самого элемента покажет весь путь при наведении мыши. Ведь элементы могут находиться один над другим и не факт, что тебе нужен именно самый верхний из них или самый нижний. Так что перебор всего дерева Spy++ может оказаться единственным выходом.

WALKMAN 25.01.2011 00:17

У меня вопрос. А бот будет работать если сама программа будет свернута, а физичесская мышка будет заниматься своими делами)

IIIMbIrA 27.01.2011 16:28

Цитата:

Сообщение от WALKMAN
У меня вопрос. А бот будет работать если сама программа будет свернута, а физичесская мышка будет заниматься своими делами)

1)При отправке окну сообщений оно скорее всего всё равно будет разворачивоться. (Есть решение - после отправки сообщений контролам, также программно сворачивать и главное окно. Не пробовал, но должно сработать).

2)Работа бота никак не затрагивает "физическую" мышку, даже курсор никуда не перемещается.


Время: 03:32