Что нового

[Мышь, клавиатура] Проблема с программным рисованием мышью

D1MA12

Новичок
Сообщения
1
Репутация
0
Недавно нашел довольно полезную приватную программу для работы с социальными сетями. У этой программы есть демо версия, которая включает в себя все функции полной, только с одним исключением: через некоторое количество времени после запуска выскакивает окошко, в котором необходимо пройти проверку. Суть проверки заключаться в соединении в поле для рисования некоторых точек.
Программа должна работать на протяжении длительного времени, соответственно таких проверок нужно проходить до 100 за день. Мне это надоело и я решил найти способ обойти эту защиту. Сначала были перепробованы популярные автокликеры такие, как AutoIt и Clickermann. Clickermann не смог даже активировать это окно и все клики и движения мыши, которые он создавал, вообще не действовали на это окно. AutoIt с помощью функции WinActivate смог активировать окно, но после этого ни одна функция, связанная с движением или кликами мыши не работала. Это выглядело как будто скрипт просто завис. Потом я прочитал про сообщения Windows и программную эмуляцию мыши и попытался создать свой собственный автокликер на C++. Способов было не много, всего 2: с помощью SendMessage или с помощью SendInput(слышал про mouse_event, но он уже устаревший).
Сначала использовав spy++ просмотрел список сообщений, которые принимает окно, там же и узнал, что заголовок окна рисования, это System.Drawing.Bitmap. Пытался отсылать такие же сообщения, но окно никак не реагировало:
Код:
SendMessage(mainWin, WM_NCHITTEST, NULL, (LPARAM)MAKELONG(642, 706));
SendMessage(mainWin, WM_NCHITTEST, NULL, (LPARAM)MAKELONG(642, 706));

SendMessage(mainWin, WM_LBUTTONDOWN, NULL, (LPARAM)MAKELONG(10, 10));
Sleep(100);
SendMessage(mainWin, WM_MOUSEMOVE, NULL, (LPARAM)MAKELONG(50, 50));
Sleep(100);
SendMessage(mainWin, WM_LBUTTONUP, NULL, (LPARAM)MAKELONG(50, 50));
Хотя если это отослать в тот же Paint, то линия рисуется.
Далее я захотел попробовать второй способ и написав такой код:
Код:
INPUT input;
input.type = INPUT_MOUSE;
input.mi.mouseData = 0;
input.mi.dx = 620 * (65536 / GetSystemMetrics(SM_CXSCREEN)); 
input.mi.dy = 95 * (65536 / GetSystemMetrics(SM_CYSCREEN)); 
input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN;
SendInput(1, &input, sizeof(input));
Sleep(50);

for (int i = 0; i < 120; i++)
{
input.type = INPUT_MOUSE;
input.mi.mouseData = 0;
input.mi.dx = (500+i) * (65536 / GetSystemMetrics(SM_CXSCREEN)); 
input.mi.dy = 95* (65536 / GetSystemMetrics(SM_CYSCREEN));
input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
SendInput(1, &input, sizeof(input));
Sleep(50);
}

input.type = INPUT_MOUSE;
input.mi.mouseData = 0;
input.mi.dx = 620 * (65536 / GetSystemMetrics(SM_CXSCREEN));
input.mi.dy = 95 * (65536 / GetSystemMetrics(SM_CYSCREEN)); 
input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTUP;
SendInput(1, &input, sizeof(input));
Sleep(50);
Если этот код выполнить при главном окне Paint, то линия рисоваться будет, а окошко искомой программы даже не активируется.
Немного погуглив, я нашел причину такого поведения:
1) Программа использует DirectInput, т.е берет все произошедшие действия прямо с драйвера устройства.
Либо
2) Все вышеуказанные эмулированные действия активируют флаги LLKHF_INJECTED и LLKHF_LOWER_IL_INJECTED, с помощью которых приложение очень легко может проверить эти действия на эмуляцию. Поиски решения зашли в тупик.

Но через неделю, я решил переместить это приложение на сервер, чтобы проходить проверки с любого места. Приложение спокойно работало и я проходил его проверки со смартфона сидя на диване и смотря телевизор. И тут меня осенило - на серверных компьютерах ведь нет мыши и все действия и так эмулируются драйвером RDP!
mysh_udal_stola.png

У меня было два варианта - написать свой RDP или попробовать пройти круг заново, начиная с автокликкеров.
Я с них и начал, и самый первый меня не подвел: AutoIt перестал зависать и преспокойно эмулировал движения и клики мыши в этом злосчастном окошке. Создание программы, для соединения точек я описывать не буду, это не так важно. Также напишу, что я понимаю, что человек не может соединять точки мышью идеальными прямыми, поэтому моя программа это учитывает и делает помехи.

А теперь суть проблемы:
Когда я своей мышью рисую линию, то она получается где-то в 2 раза тоньше, чем та линия, которая рисуется с помощью AutoIt. Прямые линии идентичны, но если линия "косит", то программная делается в 2 раза больше.
Вот ниже примеры моего ввода мышкой и программного(если что, левое и правое изображение созданы при разном положении точек, что надо соединить):
Polnyi.jpg

Рисую я таким образом:
Код:
;~ Тут код обнаружения окошка на котором рисуем

_FileReadToArray ( $sFilePath,$aArray) ;~ Координаты для отрисовки линии находяться в файле
$iUbound = UBound($aArray)

MouseMove($aArray[1],$aArray[2]);~ Перемещаем кусор на первую точку
Sleep(100)
MouseClick("left")
Sleep(100)
MouseDown("left")
 For $i = 1 To $iUbound-2 Step 2
	MouseMove($aArray[$i],$aArray[$i+1],20) ;~ Рисуем точку
 Next
Sleep(100)
MouseUp("left");


В итоге проверку программа пройти не может. Может кто-то стыкался с такой проблемой и подскажет решение.
 
Верх