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

Управление другим приложением из своей программы
12.02.2012 | Категория: Образ мышления: Assembler | Автор: ManHunter
Под управлением сторонним приложением я подразумеваю некие действия своей программы, эмулирующие действия живого человека. Например, нажатия на кнопки в диалоговых окнах. Попробуем сделать это на примере лоадера для популярного файлового менеджера Total Commander. Кто пользуется им, тот знает, что единственное различие между полной и незарегистрированной версией в том, что триалка при запуске показывает наг-скрин с предложением купить программу или нажать для продолжения одну из трех кнопок с цифрами. Конечно, кнопку можно нажать самостоятельно, но можно доверить это лоадеру.
Наг-скрин Total Commander
Чтобы работать с содержимым окна, сперва надо узнать его хэндл. Проще всего воспользоваться функцией FindWindow, указав в качестве параметра наименование класса наг-скрина. Его можно посмотреть при помощи моей программы WinDowzer или любой другой аналогичной программы. Противное окно имеет название класса TNASTYNAGSCREEN, первый шаг сделан. Теперь нам надо узнать хэндл нужной кнопки, для этого нужно изучить все связи родительских и дочерних объектов окна.
Читать статью целиком »
Просмотров: 10694 | Комментариев: 7

Принудительное обновление иконок в трее
12.01.2012 | Категория: Образ мышления: Assembler | Автор: ManHunter
В случае аварийного завершения или некорректной работы некоторых приложений, в системном трее могут оставаться "мертвые" иконки, которые уже не принадлежат ни одному запущенному процессу. Глюк хоть и не смертельный, но все равно неприятный. И основная проблема в том, что область трея никак не реагирует на внешние сообщения типа WM_REPAINT, и функции типа UpdateWindow и InvalidateRect. То есть автоматически обновить или перерисовать его, чтобы избавиться от "мертвых" иконок, не получится. Но такие иконки удаляются, если провести курсором мышки над ними. Значит единственный способ перерисовать иконки в трее - это сэмулировать движение мыши над окном трея. Как найти окно трея и его хэндл мы уже знаем, тут ничего нового. В сегменте данных те же значения: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 ? ; Хэндл окна трея
- ToolbarRect RECT ; Размер окна трея
Code (Assembler) : Убрать нумерацию
- ; Найти окно трея
- 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
Читать статью целиком »
Просмотров: 9032 | Комментариев: 21

Как получить название текущего трека из Winamp и AIMP
01.12.2011 | Категория: Образ мышления: Assembler | Автор: ManHunter
Winamp был и остается самым популярным мультимедийным плеером для Windows. Такая популярность не могла остаться незамеченной, поэтому появились программы, использующие информацию из него в своих целях. Например, плагины для интернет-мессенджеров устанавливают название воспроизводимого трека в качестве статуса, а моя программа My Music Web Agent отправляет эту информацию в интернет. Для взаимодействия сторонних приложений с Winamp был разработан интерфейс API со своими командами и синтаксисом. По какой-то причине разработчики Winamp сейчас вообще убрали с сайта информацию об API, но в интернете эти данные остались. Я приложил описание Winamp Application Programming Interface в архиве с примером программы, рекомендую ознакомиться с ним перед прочтением статьи, чтобы не возникало вопросов откуда взялись те или иные значения.Code (Assembler) : Убрать нумерацию
- ; Сегмент данных
- section '.data' data readable writeable
- ; Название класса окна Winamp/AIMP
- wcl db 'Winamp v1.x',0
- buff rb 300h ; Буфер для получения текста из заголовка окна
- play_now rb 300h ; Буфер для получения названия трека
Code (Assembler) : Убрать нумерацию
- ; Сегмент кода
- section '.code' code readable executable
- ...
- ; Получить хэндл окна Winamp
- invoke FindWindow,wcl,0
- or eax,eax
- ; Окно Winamp не найдено
- jz .no_winamp
- ; Сохранить хэндл окна
- mov ebx,eax
- ; Что-то сейчас воспроизводится?
- invoke SendMessage,ebx,WM_USER,NULL,104
- cmp eax,1
- ; Winamp не находится в состоянии "Play"
- jne .no_winamp
- ...
Читать статью целиком »
Просмотров: 8067 | Комментариев: 9

Как узнать, что программа запущена под Администратором
20.11.2011 | Категория: Образ мышления: Assembler | Автор: ManHunter
Иногда требуется узнать, запущена ли ваша программа под учетной записью с правами Администратора, или же от обычного пользователя. Для чего это нужно? Например, некоторые операции с реестром или файлами требуют права Администратора. При попытке выполнить их обычному пользователю вернется ошибка ERROR_ACCESS_DENIED, но для более точного анализа ситуации надо будет проверить права доступа и уведомить об этом пользователя. Проверить, что программа запущена под Администратором, можно несколькими способами.Первый способ наиболее универсальный и работает даже на старых операционных системах. Он заключается в том, что надо получить группы доступа для токена текущего процесса, а затем проверить, входит ли хоть одна из них в группу Администраторов локального компьютера. Вот пример реализации:
Code (Assembler) : Убрать нумерацию
- ; Сегмент данных
- section '.data' data readable writeable
- SECURITY_NT_AUTHORITY = 5
- TOKEN_READ = 0x00020008
- SECURITY_BUILTIN_DOMAIN_RID = 0x00000020
- DOMAIN_ALIAS_RID_ADMINS = 0x00000220
- TokenGroups = 0x00000002
- BUFF_SIZE = 1024h ; Размер буфера для групп доступа токена
- NtAuthority db 0,0,0,0,0,SECURITY_NT_AUTHORITY
- hTokenHandle dd ?
- dInfoSize dd ?
- psidAdmins dd ?
- hHeap dd ?
- pTokenGroups dd ?
- ;---------------------------------------------
- ; Сегмент кода
- section '.code' code readable executable
- ...
- ; Получить токен текущего процесса
- invoke GetCurrentProcess
- invoke OpenProcessToken,eax,TOKEN_READ,hTokenHandle
- ; Выделить память для массива групп
- invoke GetProcessHeap
- mov [hHeap],eax
- invoke HeapAlloc,eax,HEAP_ZERO_MEMORY,BUFF_SIZE
- mov [pTokenGroups],eax
- ; Получить информацию о группах доступа токена
- invoke GetTokenInformation,[hTokenHandle],TokenGroups,\
- [pTokenGroups],dword BUFF_SIZE,dInfoSize
- ; Прибраться за собой
- invoke CloseHandle,[hTokenHandle]
- invoke AllocateAndInitializeSid,NtAuthority,2,\
- SECURITY_BUILTIN_DOMAIN_RID,\
- DOMAIN_ALIAS_RID_ADMINS,0,0,0,0,0,0,psidAdmins
- ; Количество записей в структуре TOKEN_GROUPS
- mov esi,[pTokenGroups]
- mov ebx,dword [esi]
- ; Указатель на массив SID_AND_ATTRIBUTES
- add esi,4
- @@:
- ; Проверить соответствие SID
- mov eax,dword [esi]
- invoke EqualSid,[psidAdmins],eax
- or eax,eax
- jnz loc_admin
- ; Следующая группа
- add esi,8
- dec ebx
- or ebx,ebx
- jnz @b
- loc_not_admin:
- ; Пользователь не Администратор
- ...
- loc_admin:
- ; Пользователь Администратор
- ...
Читать статью целиком »
Просмотров: 10798 | Комментариев: 25

Диалог открытия файлов и юзабилити Windows
02.11.2011 | Категория: Образ мышления: Assembler | Автор: ManHunter
При всех удобствах Windows некоторые моменты меня очень сильно раздражают. Особенно поведение системы при вызове диалогов открытия файлов. Сперва немного предыстории. При работе с файлами через функцию GetOpenFileName или GetSaveFileName в структуре OPENFILENAME есть возможность указать путь, который должен открыться по умолчанию. Если это значение не задано, то система сама где-то запоминает папку, в которой последний раз был удачно открыт файл (то есть окно выбора файла было закрыто через кнопку "Ok"). Где именно хранится эта информация - я пока не выяснил, да и не особо надо. Второй вариант. Предположим, что некоторая программа самостоятельно запоминает путь к папке, в которой последний раз ею выполнялись какие-то действия с файлами. Это может быть, например, текстовый редактор, просмотрщик графики и т.п., не суть. Главное, что задумка очень хорошая и правильная. При следующем запуске или вызове диалога выбора файла в соответствующее поле OPENFILENAME будет подставлен сохраненный путь и пользователь продолжит работу с того места, где он в прошлый раз остановился. Что-то типа такого:Code (Assembler) : Убрать нумерацию
- ...
- invoke GetModuleHandle,0
- mov [ofn.hInstance],eax
- mov [ofn.lStructSize], sizeof.OPENFILENAME
- mov [ofn.hwndOwner],0
- mov [ofn.nMaxFile],MAX_PATH
- mov [ofn.lpstrFile],buff
- ; Открывать с последней сохраненной папки
- mov [ofn.lpstrInitialDir],saved_dir
- mov [ofn.Flags],OFN_EXPLORER+OFN_FILEMUSTEXIST
- invoke GetOpenFileName,ofn
- ...
Читать статью целиком »
Просмотров: 7394 | Комментариев: 6
