Blog. Just Blog

Быстрый поиск

Введите фрагмент названия статьи для поиска

Экранная лупа на Ассемблере

15.10.2010 | Категория: Образ мышления: Assembler | Автор: ManHunter
Алгоритм реализации экранной лупы достаточно простой. Надо получить часть изображения рабочего стола и скопировать его с масштабированием в нужную область вашего приложения. Сделать это можно при помощи функции StretchBlt. Если посмотрите описание, то увидите, что для работы этой функции требуются следующие параметры: размеры результирующей области, размеры исходной области и контексты устройств (окон), в которых находятся области. А поскольку мы сейчас разрабатываем лупу, значит она должна увеличивать, то есть размеры исходного окна должны быть пропорционально меньше результирующего. Коэффициент пропорциональности и есть коэффициент увеличения лупы. При инициализации окна выполним предварительные расчеты:
  1.         ...
  2.         ; Получить контекст окна лупы
  3.         invoke  GetDlgItem,[hwnddlg],ID_ZOOM
  4.         mov     ebx,eax
  5.         invoke  GetDC,eax
  6.         mov     [wDC],eax
  7.  
  8.         ; Получить размеры окна лупы
  9.         invoke  GetClientRect,ebx,coord
  10.         mov     eax,[coord.right]
  11.         sub     eax,[coord.left]
  12.         mov     [dWidth],eax
  13.         mov     eax,[coord.bottom]
  14.         sub     eax,[coord.top]
  15.         mov     [dHeight],eax
  16.  
  17.         ; Получить контекст десктопа
  18.         invoke  GetDesktopWindow
  19.         mov     [hDesktop],eax
  20.         invoke  GetDC,eax
  21.         mov     [dDC],eax
  22.         ...
Как теперь запустить экранную лупу? Здесь есть два варианта: при получении сообщения от мыши и по таймеру. У каждого способа свои достоинства и недостатки. Если обрабатывать сообщения мыши, то требуется инжект вспомогательной dll во все процессы, а экран лупы будет обновляться только при движении мыши. Это существенно снизит нагрузку на систему, но если окно под курсором будет обновляться, а курсор останется неподвижным, то лупа получит только тот кадр, который был при последнем движении курсора. Обновление по таймеру создаст дополнительную нагрузку на систему, но при этом изображение в лупе будет в точности соответствовать текущему состоянию окна под курсором. Оба способа имеют место быть, каждый под свои задачи.

Читать статью целиком »
Просмотров: 6162 | Комментариев: 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 и "чужие". Признак "свой" можно сделать, например, указав в качестве длины буфера какое-нибудь заранее определенное уникальное значение, а затем в обработчике пропускать сообщения только с этим параметром. Установить собственный обработчик можно через субклассирование окна ввода, это мы уже разбирали в предыдущих статьях. Теперь от теории перейдем к практике.

Читать статью целиком »
Просмотров: 6039 | Комментариев: 10

Определение времени бездействия системы

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

Читать статью целиком »
Просмотров: 8129 | Комментариев: 11

Получение списка иконок в трее

18.07.2010 | Категория: Образ мышления: Assembler | Автор: ManHunter
Иногда приложению требуется получить список иконок, находящихся в трее, а также список приложений, которые их туда разместили. Это может быть нужно для обнаружения некоторых скрывающихся приложений, для эмуляции кликов на иконках, ну или просто для спортивного интереса. В любом случае для получения списка иконок надо сделать следующее: найти в трее панель с иконками, при помощи сообщения TB_BUTTONCOUNT получить количество иконок, а затем через отправку сообщения TB_GETBUTTON получить всю необходимую информацию по каждой иконке. Теперь рассмотрим все шаги подробнее.

Работать с вложенными окнами трея мы уже умеем, здесь практически то же самое, разница только в названиях классов дочерних окон.
  1. ; Сегмент данных
  2. section '.data' data readable writeable 
  3. ...
  4. class1  db 'Shell_TrayWnd',0    ; Название класса окна трея
  5. class2  db 'TrayNotifyWnd',0    ; Название класса панели уведомлений
  6. class3  db 'SysPager',0         ; Трей
  7. class4  db 'ToolbarWindow32',0  ; Панель с иконками
  8.  
  9. ToolbarHandle   dd ?            ; Хэндл окна с иконками
  10. ...
  11. ; Сегмент кода
  12. section '.code' code readable executable
  13.         ...
  14.         ; Найти окно трея
  15.         invoke  FindWindow,class1,NULL
  16.         or      eax,eax
  17.         jz      exit_process
  18.  
  19.         ; Найти панель уведомлений
  20.         invoke  FindWindowEx,eax,NULL,class2,NULL
  21.         or      eax,eax
  22.         jz      exit_process
  23.  
  24.         ; Найти трей
  25.         invoke  FindWindowEx,eax,NULL,class3,NULL
  26.         or      eax,eax
  27.         jz      exit_process
  28.  
  29.         ; Найти панель иконок в трее
  30.         invoke  FindWindowEx,eax,NULL,class4,NULL
  31.         or      eax,eax
  32.         jz      exit_process
  33.  
  34.         ; Сохранить хэндл окна с иконками
  35.         mov     [ToolbarHandle],eax
  36.         ...
Теперь у нас есть хэндл окна панели инструментов с иконками в трее. Получим количество иконок в панели.
  1.         ; Получить количество иконок в трее
  2.         invoke  SendMessage,eax,TB_BUTTONCOUNT,0,0
  3.         or      eax,eax
  4.         jz      exit_process
  5.  
  6.         ; Сохранить количество иконок в трее
  7.         mov     [IconsCount],eax
Количество иконок тоже есть. Осталось перебрать их в цикле и получить всю необходимую информацию. Для этого используется сообщение TB_GETBUTTON и структура TBBUTTON для получения результата. Однако, если сейчас попробовать послать окну панели сообщение TB_GETBUTTON, то в результате не получим ничего. Почему? Потому что память, в которую будут записываться данные, обязательно должна принадлежать процессу, который является владельцем окна трея (обычно это explorer.exe).

Читать статью целиком »
Просмотров: 8893 | Комментариев: 9

Windows 7 Taskbar API на Ассемблере

30.06.2010 | Категория: Образ мышления: Assembler | Автор: ManHunter

Progress Bars и Overlay Icons

Продолжаю потихоньку осваивать внутренности Windows 7. В новой системе появилась такая приятная фича интерфейса, как отображение прогресса выполнения какого-нибудь действия прямо на кнопке приложения в панели задач. Впервые я увидел это в программе Total Commander при копировании и переносе файлов, сразу очень захотелось узнать как это делается и научиться делать самому. К сожалению, во всех доступных мне интернетах были найдены только примеры для Delphi, .NET и прочих языков высокого уровня. Пришлось лезть в отладчик и запасаться железным терпением, зато в результате получилось вполне рабочее решение. Для управления элементами панели задач в Windows 7 используется COM-интерфейс ITaskBarList3. Как обычно, никаких описаний в FASM нет, и все необходимое нужно искать самому или портировать с других языков.
  1. ; GUID {56FDF344-FD6D-11D0-958A-006097C9A090}
  2. CLSID_TaskbarList       dd 056FDF344h
  3.                         dw 0FD6Dh
  4.                         dw 011D0h
  5.                         db 095h, 08Ah, 000h, 060h, 097h, 0C9h, 0A0h, 090h
  6.  
  7. ; GUID {EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF}
  8. IID_ITaskbarList3       dd 0EA1AFB91h
  9.                         dw 09E28h
  10.                         dw 04B86h
  11.                         db 090h, 0E9h, 09Eh, 09Fh, 08Ah, 05Eh, 0EFh, 0AFh
  12.  
  13. ; ITaskbarList3 Interface
  14. SetProgressValue        = 4*09
  15. SetProgressState        = 4*10
  16. RegisterTab             = 4*11
  17. UnregisterTab           = 4*12
  18. SetTabOrder             = 4*13
  19. SetTabActive            = 4*14
  20. ThumbBarAddButtons      = 4*15
  21. ThumbBarUpdateButtons   = 4*16
  22. ThumbBarSetImageList    = 4*17
  23. SetOverlayIcon          = 4*18
  24. SetThumbnailTooltip     = 4*19
  25. SetThumbnailClip        = 4*20
  26.  
  27. ; Типы прогрессбаров на панели задач
  28. TBPF_NOPROGRESS         = 0
  29. TBPF_INDETERMINATE      = 1
  30. TBPF_NORMAL             = 2
  31. TBPF_ERROR              = 4
  32. TBPF_PAUSED             = 8
  33.  
  34. ; Константы для работы с объектом
  35. CLSCTX_INPROC_SERVER    = 1
  36. S_OK                    = 0
Хотя сейчас будут использоваться только три функции, я привел полное описание методов COM-интерфейса ITaskbarList3, оно пригодится чуть позже.

Читать статью целиком »
Просмотров: 7975 | Комментариев: 6

01 ... 59 60 61 62 63 64 65 ... 72
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.08 сек. / MySQL: 3 (0.0201 сек.) / Память: 4.5 Mb
Наверх