
Образ мышления: Assembler
То, что не удается запрограммировать на Ассемблере, приходится паять
Образ мышления: Assembler - RSS-канал
Образ мышления: Assembler - Карта сайта

Как запретить Windows переходить в спящий режим
26.10.2010 | Категория: Образ мышления: Assembler | Автор: ManHunter
В некоторых случаях требуется, чтобы на время работы вашего приложения компьютер постоянно оставался в активном состоянии, то есть не включался скринсейвер, не отключался монитор, система не переходила в спящий режим. Для этого надо "убедить" Windows, что за клавиатурой сидит реальный пользователь и проявляет какую-то активность, в этом случае все счетчики времени бездействия будут сбрасываться. Для программной имитации действий пользователя используются две функции: mouse_event для симуляции работы с мышкой мышки и, соответственно, keybd_event для клавиатуры. Также можно использовать более универсальную функцию SendInput, она позволяет симулировать не только мышку и клавиатуру, но и хардварные события. Есть еще более суровые варианты, связанные с ковырянием в реестре, изменением профилей электропитания, но их я рассматривать не буду.В прикладном приложении для имитации действий пользователя надо установить таймер, например, на секундный интервал, и в его функции-обработчике симулировать движение мыши. Нажатия кнопок мыши и клавиш на клавиатуре симулировать не надо, так как эти действия могут наложиться с действиями реального пользователя, а вот перемещение мышки на какое-нибудь незаметное расстояние будет в самый раз. Почитаем повнимательнее документацию к функции mouse_event. Координаты перемещения задаются в условных единицах - микки, которые высчитываются по формуле: 1 микки = (ширина или высота разрешения монитора) / 65535. Если не указан флаг MOUSEEVENTF_ABSOLUTE, то координаты считаются относительные, то есть от текущего положения курсора. Первоначальный вариант решения был в перемещении курсора на 1 микки от текущего положения курсора, а затем в возвращении его обратно. Но, к сожалению, на Windows XP этот способ все-таки двигал курсор (спасибо ezfalc0n за подсказку). Следующий вариант, вообще без движения, также сбрасывает счетчик времени бездействия системы, так что будем использовать именно его:
Code (Assembler) : Убрать нумерацию
- ; Симулировать событие от мышки, оставляя ее на месте
- invoke mouse_event,MOUSEEVENTF_MOVE,0,0,0,0
Читать статью целиком »
Просмотров: 13057 | Комментариев: 25

Экранная лупа на Ассемблере
15.10.2010 | Категория: Образ мышления: Assembler | Автор: ManHunter
Алгоритм реализации экранной лупы достаточно простой. Надо получить часть изображения рабочего стола и скопировать его с масштабированием в нужную область вашего приложения. Сделать это можно при помощи функции StretchBlt. Если посмотрите описание, то увидите, что для работы этой функции требуются следующие параметры: размеры результирующей области, размеры исходной области и контексты устройств (окон), в которых находятся области. А поскольку мы сейчас разрабатываем лупу, значит она должна увеличивать, то есть размеры исходного окна должны быть пропорционально меньше результирующего. Коэффициент пропорциональности и есть коэффициент увеличения лупы. При инициализации окна выполним предварительные расчеты:Code (Assembler) : Убрать нумерацию
- ...
- ; Получить контекст окна лупы
- invoke GetDlgItem,[hwnddlg],ID_ZOOM
- mov ebx,eax
- invoke GetDC,eax
- mov [wDC],eax
- ; Получить размеры окна лупы
- invoke GetClientRect,ebx,coord
- mov eax,[coord.right]
- sub eax,[coord.left]
- mov [dWidth],eax
- mov eax,[coord.bottom]
- sub eax,[coord.top]
- mov [dHeight],eax
- ; Получить контекст десктопа
- invoke GetDesktopWindow
- mov [hDesktop],eax
- invoke GetDC,eax
- mov [dDC],eax
- ...
Читать статью целиком »
Просмотров: 6307 | Комментариев: 6

Защищенное поле для ввода пароля
23.08.2010 | Категория: Образ мышления: Assembler | Автор: ManHunter
Как-то задумался о том, можно ли защититься от программ, которые показывают пароли за "звездочками"? Ведь это могут быть не только безобидные программы для восстановления забытых паролей, но и "троянские кони", похищающие вашу приватную информацию. Немного поэкспериментировал, оказалось, что защититься можно. Сперва немного теоретической информации о том, каким образом открываются пароли. Первый способ: сначала нужному полю EDIT посылается сообщение EM_SETPASSWORDCHAR с нулевыми параметрами, в результате чего с него снимается атрибут ES_PASSWORD. После этого текст пароля можно прочитать как визуально, так и через GetWindowText, WM_GETTEXT и т.п. Второй способ, более "пробивной", это внедрение в исследуемый процесс своей DLL, после чего с ее помощью текст пароля читается через сообщение WM_GETTEXT. Это делается потому, что в целях безопасности информацию из поля, закрытого "звездочками", через GetWindowText или WM_GETTEXT можно получить только из контекста процесса, который владеет окном.Чтобы защититься от программ первого типа, надо самостоятельно обрабатывать сообщение EM_SETPASSWORDCHAR и в обработчике подавлять его. Защититься от второго варианта сложнее, ведь если мы будем подавлять сообщение WM_GETTEXT, то мы и сами не сможем прочитать текст пароля. Значит надо каким-то образом различать "свои" сообщения WM_GETTEXT и "чужие". Признак "свой" можно сделать, например, указав в качестве длины буфера какое-нибудь заранее определенное уникальное значение, а затем в обработчике пропускать сообщения только с этим параметром. Установить собственный обработчик можно через субклассирование окна ввода, это мы уже разбирали в предыдущих статьях. Теперь от теории перейдем к практике.
Читать статью целиком »
Просмотров: 6158 | Комментариев: 10

Определение времени бездействия системы
05.08.2010 | Категория: Образ мышления: Assembler | Автор: ManHunter
Иногда приложениям требуется узнать время бездействия системы, то есть интервал времени, прошедший с момента когда пользователь последний раз пошевелил мышкой или нажал какую-нибудь кнопку на клавиатуре. Для определения время бездействия системы в системах Windows 2000 и старше используется функция API GetLastInputInfo. Она возвращает количество миллисекунд (тиков таймера), прошедшее от старта системы до момента последнего ввода. Время бездействия вычисляется как арифметическая разница между данными, возвращаемыми функцией GetTickCount и данными из GetLastInputInfo. В FASM, как обычно, ничего из нужных структур не определено, лезем в MSDN:Code (Assembler) : Убрать нумерацию
- section '.data' data readable writeable
- struct LASTINPUTINFO
- cbSize dd ? ; Размер структуры
- dwTime dd ? ; Время бездействия
- ends
- lii LASTINPUTINFO
Code (Assembler) : Убрать нумерацию
- ...
- ; Получить время последнего ввода
- mov [lii.cbSize],sizeof.LASTINPUTINFO
- invoke GetLastInputInfo,lii
- ; Получить текущее время в миллисекундах
- invoke GetTickCount
- ; EAX - время бездействия системы в миллисекундах
- sub eax,[lii.dwTime]
- ...
Читать статью целиком »
Просмотров: 8359 | Комментариев: 11

Получение списка иконок в трее
18.07.2010 | Категория: Образ мышления: Assembler | Автор: ManHunter
Иногда приложению требуется получить список иконок, находящихся в трее, а также список приложений, которые их туда разместили. Это может быть нужно для обнаружения некоторых скрывающихся приложений, для эмуляции кликов на иконках, ну или просто для спортивного интереса. В любом случае для получения списка иконок надо сделать следующее: найти в трее панель с иконками, при помощи сообщения TB_BUTTONCOUNT получить количество иконок, а затем через отправку сообщения TB_GETBUTTON получить всю необходимую информацию по каждой иконке. Теперь рассмотрим все шаги подробнее.Работать с вложенными окнами трея мы уже умеем, здесь практически то же самое, разница только в названиях классов дочерних окон.
Code (Assembler) : Убрать нумерацию
- ; Сегмент данных
- section '.data' data readable writeable
- ...
- class1 db 'Shell_TrayWnd',0 ; Название класса окна трея
- class2 db 'TrayNotifyWnd',0 ; Название класса панели уведомлений
- class3 db 'SysPager',0 ; Трей
- class4 db 'ToolbarWindow32',0 ; Панель с иконками
- ToolbarHandle dd ? ; Хэндл окна с иконками
- ...
- ; Сегмент кода
- section '.code' code readable executable
- ...
- ; Найти окно трея
- invoke FindWindow,class1,NULL
- or eax,eax
- jz exit_process
- ; Найти панель уведомлений
- invoke FindWindowEx,eax,NULL,class2,NULL
- or eax,eax
- jz exit_process
- ; Найти трей
- invoke FindWindowEx,eax,NULL,class3,NULL
- or eax,eax
- jz exit_process
- ; Найти панель иконок в трее
- invoke FindWindowEx,eax,NULL,class4,NULL
- or eax,eax
- jz exit_process
- ; Сохранить хэндл окна с иконками
- mov [ToolbarHandle],eax
- ...
Code (Assembler) : Убрать нумерацию
- ; Получить количество иконок в трее
- invoke SendMessage,eax,TB_BUTTONCOUNT,0,0
- or eax,eax
- jz exit_process
- ; Сохранить количество иконок в трее
- mov [IconsCount],eax
Читать статью целиком »
Просмотров: 9051 | Комментариев: 9
