Blog. Just Blog

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

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

Прячем ярлыки на рабочем столе

05.08.2020 | Категория: Образ мышления: Assembler | Автор: ManHunter
Очередная мелкая развлекушка на Ассемблере. Сегодня будем прятать все ярлыки на рабочем столе. Нам не понадобится никаких громоздких структур, объектов, интерфейсов и прочей паранормальщины. И что хорошо, фактически все ярлыки остаются на своих местах, ничего не надо потом восстанавливать, ведь при прятании просто скрывается дочерний элемент окна десктопа, в котором ярлыки находятся.
  1. ; Сегмент данных
  2. section '.data' data readable writeable
  3.  
  4. szProg db 'ProgMan',0
  5.  
  6. ; Сегмент кода
  7. section '.code' code readable executable
  8.         ...
  9.         invoke  FindWindow,szProg,NULL
  10.         invoke  GetWindow,eax,GW_CHILD
  11.         invoke  GetWindow,eax,GW_CHILD
  12.         ; Сохранить хэндл окна с ярлыками
  13.         mov     ebx,eax
  14.         ; Ярлыки показываются?
  15.         invoke  IsWindowVisible,ebx
  16.         or      eax,eax
  17.         jne     @f
  18.         ; Нет, показать
  19.         invoke  ShowWindow,ebx,SW_SHOW
  20.         jmp     loc_exit
  21. @@:
  22.         ; Да, скрыть
  23.         invoke  ShowWindow,ebx,SW_HIDE
  24. loc_exit:
При запуске первым делом ищется окно с названием класса "ProgMan", затем поочередно находятся его первое дочернее окно и дочернее окно этого окна. Именно в нем находится Listbox со всеми ярлыками. Затем проверяется видимость этого окна. Если ярлыки отображаются, то они будут спрятаны, ну и наоборот. Если повесить такую программу на какую-нибудь горячую клавишу, то получится этакий ультра-лайтовый вариант блокировки компьютера, чтобы временно скрыть содержимое рабочего стола от излишне любопытных глаз, не запрещая при этом возможность работы за компьютером. Или можно использовать как программу-шутку для пугания юзеров. Естественно, после перезагрузки все возвращается на свои места.

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

Перехват и обработка изменения заголовка окна другого приложения

03.08.2020 | Категория: Образ мышления: Assembler | Автор: ManHunter
В предыдущих примерах обработки системных событий мы рассматривали глобальные события, которые происходят во всей системе. Чтобы завершить эту тему, хотелось бы рассказать о системных событиях, ограниченных конкретным приложением. В качестве примера возьмем перехват и обработку изменения заголовка окна какого-нибудь приложения. Немного констант, некоторые из которых вы уже знаете.
  1. EVENT_OBJECT_NAMECHANGE = 0x800C
  2. WINEVENT_OUTOFCONTEXT   = 0x0000
  3. OBJID_WINDOW            = 0x0000
  4. CHILDID_SELF            = 0x0000
Процесс установки хука немного отличается по используемым параметрам. Чтобы связать обработчик с конкретным процессом, сперва надо получить идентификаторы этого процесса и потока. Для дочерних процессов это вообще не проблема, а для стороннего придется воспользоваться функцией GetWindowThreadProcessId, ведь хэндл обрабатываемого окна мы знаем. В SetWinEventHook указываем полученные идентификаторы.
  1.         ; Найти нужное окно
  2.         invoke  FindWindow,NULL,szName
  3.         ; Сохранить хэндл найденного окна
  4.         mov     [hExample],eax
  5.  
  6.         ; Получить идентификаторы процесса и потока, относящиеся к окну
  7.         invoke  GetWindowThreadProcessId,[hExample],pID
  8.         mov     [tID],eax
  9.  
  10.         ; Установить хук на системные события
  11.         invoke  SetWinEventHook,EVENT_OBJECT_NAMECHANGE,\
  12.                 EVENT_OBJECT_NAMECHANGE,NULL,WinEventProc,\
  13.                 [pID],[tID],WINEVENT_OUTOFCONTEXT
А вот обработчик изменился не сильно. Проверяем, что изменяемый объект - окно, что это действительно нужное нам окно, после этого каким-то образом реагируем на изменение его заголовка.
  1. proc WinEventProc hWinEventHook:DWORD, event:DWORD, hwnd:DWORD,\
  2.                   idObject:DWORD, idChild:DWORD, idEventThread:DWORD,\
  3.                   dwmsEventTime:DWORD
  4.         pusha
  5.         ; Изменяемый объект - окно?
  6.         cmp     [idObject],OBJID_WINDOW
  7.         jne     .loc_ret
  8.  
  9.         ; Изменяется само окно?
  10.         cmp     [idChild],CHILDID_SELF
  11.         jne     .loc_ret
  12.  
  13.         ; Точно-точно изменяется?
  14.         cmp     [event],EVENT_OBJECT_NAMECHANGE
  15.         jne     .loc_ret
  16.  
  17.         ; И меняется именно нужное окно?
  18.         mov     eax,[hwnd]
  19.         cmp     eax,[hExample]
  20.         jne     .loc_ret
  21.         ... 
  22.         ...
  23.         ; Выполняются какие-то действия по факту события
  24.         ... 
  25.         ... 
  26. .loc_ret:
  27.         popa
  28.         ret
  29. endp
Таким образом, например, можно доработать автокликалку для Total Commander, чтобы она висела в фоне и модифицировала заголовок окна программы, мгновенно убирая из него надпись "UNREGISTERED" в случае ее появления.

Безусловно, возможности и область применения системных событий не ограничиваются приведенными примерами. Зато теперь вы знаете, насколько это нужный и мощный инструмент, особенно при грамотном использовании.

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

Перехват и обработка Alt+Tab

13.07.2020 | Категория: Образ мышления: Assembler | Автор: ManHunter
Сегодня поэкспериментируем с системными событиями. Это очень мощный и интересный инструмент, с помощью которого можно оперативно реагировать на события до того момента, как они дойдут до приложения. В качестве примера будем перехватывать окно переключения процессов, которое появляется при нажатии комбинации Alt+Tab, а также обрабатывать выбор элементов в этом окне. Начнем с описания нужных нам констант.
  1. EVENT_SYSTEM_SWITCHSTART = 0x0014
  2. EVENT_SYSTEM_SWITCHEND   = 0x0015
  3. EVENT_OBJECT_FOCUS       = 0x8005
  4.  
  5. WINEVENT_OUTOFCONTEXT    = 0x0000
  6. WINEVENT_SKIPOWNPROCESS  = 0x0002
Затем при инициализации окна или где-нибудь в начале приложения при помощи функции SetWinEventHook подписываемся на системные события EVENT_SYSTEM_SWITCHSTART и EVENT_SYSTEM_SWITCHEND. Правильнее будет сказать, что на интервал всех событий с идентификаторами, расположенными между ними, включая границы. Но, поскольку они идут друг за другом, то получается, что только на эти два события.
  1. wminitdialog:
  2.         ; Обнулить хэндл окна Alt+Tab
  3.         mov     [hwndat],0
  4.         invoke  SetWinEventHook,EVENT_SYSTEM_SWITCHSTART,EVENT_SYSTEM_SWITCHEND,\
  5.                 NULL,WinEventProc,0,0,WINEVENT_OUTOFCONTEXT+WINEVENT_SKIPOWNPROCESS
  6.         mov     [hook],eax
Останется только оформить обработчик событий WinEventProc. Для большей универсальности он будет также отвечать за обработку выбора элементов в окне Alt+Tab.

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

Передача данных приложению с помощью WM_DROPFILES

09.07.2020 | Категория: Образ мышления: Assembler | Автор: ManHunter
Обрабатывать перетаскивание файлов в окно программы мы уже умеем, а сегодня узнаем, как сэмулировать это действие, то есть передать стороннему приложению список файлов через отправку сообщения WM_DROPFILES.

Начинаем с описания структуры DROPFILES, потому что FASM про нее ничего не знает. Так часто приходится писать подобное, что впору уже вводить какую-нибудь аббревиатуру, типа "Самостоятельно Описываем Структуры, Недостающие Интерфейсы, Константы Ассемблера" - "С.О.С.Н.И.К.А". Шутка.
  1. struct DROPFILES
  2.         pFiles dd ?
  3.         pt     POINT
  4.         fNC    dd ?
  5.         fWide  dd ?
  6. ends
Перед отправкой сообщения окну надо заполнить структуру DROPFILES. Значимыми полями являются pFiles - указатель на список файлов относительно начала структуры, и fWide - в каком формате передаются имена файлов, ASCII или юникод. Хотя на расположение списка файлов в памяти нет явных ограничений, обычно этот список размещается прямо за структурой и завершается нулевым байтом. Соответственно, указатель на этот список будет равен размеру структуры DROPFILES. Память под все это дело надо выделять с учетом нулевых разделителей между именами файлов и завершающим нулем.

Ну и сам код. Определяем размер и выделяем память, заполняем структуру и имена файлов, отправляем сообщение целевому окну.
  1.         ; Размер структуры DROPFILES
  2.         mov     ebx,sizeof.DROPFILES
  3.         inc     ebx
  4.  
  5.         ; Длина имени первого файла
  6.         invoke  lstrlen,file1
  7.         add     ebx,eax
  8.         inc     ebx
  9.  
  10.         ; Длина имени второго файла
  11.         invoke  lstrlen,file2
  12.         add     ebx,eax
  13.         inc     ebx
  14.  
  15.         ; Выделить память
  16.         invoke  GlobalAlloc,GMEM_SHARE+GMEM_MOVEABLE+GMEM_ZEROINIT,ebx
  17.         mov     [mem],eax
  18.         invoke  GlobalLock,eax
  19.         mov     [dfiles],eax
  20.  
  21.         ; Заполнить структуру DROPFILES
  22.         mov     edi,[dfiles]
  23.         mov     [edi+DROPFILES.pFiles],sizeof.DROPFILES
  24.         mov     [edi+DROPFILES.pt.x],0
  25.         mov     [edi+DROPFILES.pt.y],0
  26.         mov     [edi+DROPFILES.fNC],FALSE
  27.         mov     [edi+DROPFILES.fWide],FALSE
  28.         add     edi,sizeof.DROPFILES
  29.  
  30.         ; Дописать к ней передаваемые файлы
  31.         mov     esi,file1
  32. @@:
  33.         lodsb
  34.         stosb
  35.         or      al,al
  36.         jnz     @b
  37.  
  38.         mov     esi,file2
  39. @@:
  40.         lodsb
  41.         stosb
  42.         or      al,al
  43.         jnz     @b
  44.  
  45.         ; Завершающий нулевой байт
  46.         xor     eax,eax
  47.         stosb
  48.  
  49.         ; Отправить сообщение WM_DROPFILES
  50.         invoke  GlobalUnlock,[mem]
  51.         invoke  PostMessage,[destination_window],WM_DROPFILES,[mem],0
  52.         invoke  GlobalFree,[mem]
Обратите внимание, что отправка сообщения выполняется через PostMessage, иначе целевое приложение по какой-то причине может подвиснуть.

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

Получение информации о заголовке окна

12.06.2020 | Категория: Образ мышления: Assembler | Автор: ManHunter
Манипулировать кнопками в заголовке окна мы уже научились. А как узнать, какие кнопки отображаются в заголовке окна и в каком они состоянии? Конечно, можно пройтись по стилям, по меню, но правильнее будет воспользоваться следующей информацией. Мне кажется, она станет хорошим дополнением к статье об управлении кнопками в заголовке окна.

Для получения подробной информации о заголовке окна ему отправляется сообщение WM_GETTITLEBARINFOEX. Если все прошло успешно, на выходе получается заполненная структура TITLEBARINFOEX, в которой содержится информация о позициях и состоянии кнопок в заголовке окна, а также о размере самого заголовка.

Сперва надо описать структуру TITLEBARINFOEX и несколько констант, так как FASM в базовой комплектации о них не знает. Скорее всего это потому, что сообщение WM_GETTITLEBARINFOEX поддерживается только в Windows Vista и выше.
  1. struct TITLEBARINFOEX
  2.         cbSize        dd ?
  3.         rcTitleBar    RECT
  4.         stateTitleBar dd ?
  5.         sReserved1    dd ?
  6.         stateMinimize dd ?
  7.         stateMaximize dd ?
  8.         stateHelp     dd ?
  9.         stateClose    dd ?
  10.         rReserved0    RECT
  11.         rReserved1    RECT
  12.         rectMinimize  RECT
  13.         rectMaximize  RECT
  14.         rectHelp      RECT
  15.         rectClose     RECT
  16. ends
  17.  
  18. WM_GETTITLEBARINFOEX     = 0x033F
  19.  
  20. STATE_SYSTEM_FOCUSABLE   = 0x00100000
  21. STATE_SYSTEM_INVISIBLE   = 0x00008000
  22. STATE_SYSTEM_OFFSCREEN   = 0x00010000
  23. STATE_SYSTEM_UNAVAILABLE = 0x00000001
  24. STATE_SYSTEM_PRESSED     = 0x00000008
При описании TITLEBARINFOEX я немного отошел от MSDN'овского описания, там состояния и координаты описаны шестиэлементными массивами, а я для удобства работы дал им осмысленные имена вместо числовых индексов. Сути это не меняет, размера структуры тоже.

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

Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2022
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.19 сек. / MySQL: 3 (0.0747 сек.) / Память: 5 Mb
Наверх