Blog. Just Blog

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

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

Передача данных между процессами с помощью Mailslot

26.04.2023 | Категория: Образ мышления: Assembler | Автор: ManHunter
Mailslot - один из самых простых способов обмена данными между процессами, который работает еще со времен Windows 95. Каналы Mailslot позволяют передавать данные от одного или нескольких клиентов к одному или нескольким серверам, в том числе в широковещательном режиме. На локальном компьютере может быть один серверный процесс, но в сети или в домене может одновременно работать несколько серверов. Количество клиентских приложений не ограничено. Принцип работы Mailslot схож с работой электронной почты.

Основным недостатком Mailslot является то, что серверное приложение не может достоверно знать, от какого процесса и с какого компьютера было отправлено сообщение. В свою очередь, клиентское приложение не может узнать статус отправленного сообщения, то есть получено оно хоть каким-то сервером или нет. В остальном это неплохая замена сокетам, требующим сетевое подключение, или пайпам, которые могут быть открыты только двумя процессами и не поддерживают широковещательные рассылки.

Для создания канала используется функция CreateMailslot, которая в качестве одного из параметров принимает имя канала. Имя канала для серверного приложения должно иметь вид \\.\mailslot\имя_канала, при этом имя должно быть уникальным для приложения, но одинаковым в пределах клиента и сервера. Создавать канал должна серверная часть приложения. Она же определяет максимальный размер передаваемых сообщений и время ожидания. В случае необходимости этот параметр можно менять при помощи функции SetMailslotInfo.

Получив хэндл канала, сервер будет читать из него присланные сообщения. Обработчик выполняется в цикле по таймеру или же в отдельном потоке с задержкой между итерациями. Каждый шаг цикла начинается с получения состояния канала, это делается при помощи функции GetMailslotInfo, она возвращает количество сообщений в очереди на момент запроса и размер сообщения, которое будет получено первым. Если сообщений в очереди нет, то после выполнения функции параметр lpMessageCount будет равен нулю, а параметр lpNextSize примет значение MAILSLOT_NO_MESSAGE. Полученные сообщения читаются из канала функцией ReadFile, будто из обычного текстового файла.

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

Запуск задания cron с интервалом меньше 60 секунд

31.08.2022 | Категория: Web-мастеру и не только | Автор: ManHunter

Формат crontab

Как известно из документации, минимальный интервал запуска заданий в cron равен 1 минуте. Причина такого ограничения понятна, минутный интервал нужен, чтобы не перегрузить систему параллельными задачами в случае некорректных настроек. А мне понадобилось запускать определенный процесс каждые 20 секунд. Да, можно было бы написать промежуточный скрипт, который запускался бы раз в минуту по планировщику, а потом запускал процессы с нужными интервалами. Но есть более красивое решение средствами самого cron. Для того чтобы какое-либо задание запускалось каждые 20 секунд, в файле crontab нужно сделать 3 записи, что-то типа такого:

####################################################
# Запуск задания каждые 20 секунд
####################################################

* * * * * /usr/local/bin/php -f /path/to/script.php
* * * * * (sleep 20 ; /usr/local/bin/php -f /path/to/script.php)
* * * * * (sleep 40 ; /usr/local/bin/php -f /path/to/script.php)

Теперь каждую минуту будет запускаться пакет из трех заданий, но самое первое стартует незамедлительно, второе запустится через 20 секунд, а третье только через 40 секунд. Таким образом исходная задача будет решена. А, например, для запуска заданий с интервалом в 30 секунд понадобятся только две записи, и пауза перед вторым заданием, соответственно, будет 30 секунд.

Просмотров: 495 | Комментариев: 2

Отслеживание загрузки dll в память процесса

13.05.2021 | Категория: Образ мышления: Assembler | Автор: ManHunter
Ранее я уже рассказывал, как можно легко и просто получить список динамических библиотек, загруженных в ваш процесс. Сегодня расскажу о возможности отслеживания загрузки и выгрузки DLL. Начиная с Windows Vista, появилась функция LdrRegisterDllNotification. С ее помощью в приложении регистрируется callback-функция, которая будет вызываться каждый раз, как только в ваше приложение будет загружена DLL или какая-то DLL будет выгружена из его адресного пространства. Установка обработчика выполняется одной командой:
  1.         ; Зарегистрировать обработчик загрузки и выгрузки DLL
  2.         invoke  LdrRegisterDllNotification,0,LdrDllNotification,NULL,Cookie
  3.         or      eax,eax
  4.         jnz     loc_error
Важное замечание. Как показала практика, в callback-функции не должно быть никаких открытий окон, вывода сообщений и прочих взаимодействий с интерфейсом. Это может привести к зацикливанию и падению приложения во время загрузки UI-библиотек.
  1. LDR_DLL_NOTIFICATION_REASON_LOADED   = 1
  2. LDR_DLL_NOTIFICATION_REASON_UNLOADED = 2
  3.  
  4. struct NOTIFICATION_DATA
  5.     Flags       dd ?
  6.     FullDllName dd ?
  7.     BaseDllName dd ?
  8.     DllBase     dd ?
  9.     SizeOfImage dd ?
  10. ends
  11.  
  12. proc LdrDllNotification NotificationReason:DWORD,\
  13.         NotificationData:DWORD,Context:DWORD
  14.  
  15.         pusha
  16.         mov     eax,[NotificationReason]
  17.         ; EAX -> действие с DLL
  18.         ; LDR_DLL_NOTIFICATION_REASON_LOADED = загружена
  19.         ; LDR_DLL_NOTIFICATION_REASON_UNLOADED = выгружена
  20.  
  21.         ; Получить полный путь до файла DLL
  22.         mov     eax,[NotificationData]
  23.         mov     eax,[eax+NOTIFICATION_DATA.FullDllName]
  24.         mov     eax,[eax+4]
  25.         ; EAX -> полное имя файла DLL
  26.  
  27.         ; Получить базовый адрес DLL
  28.         mov     eax,[NotificationData]
  29.         mov     eax,[eax+NOTIFICATION_DATA.DllBase]
  30.         ; EAX -> DllBase библиотеки
  31.  
  32.         popa
  33.         ret
  34. endp
При каждом вызове в callback-функцию передается причина вызова - загрузка или выгрузка DLL, а также заполненная структура NOTIFICATION_DATA, в которой содержится полный путь и имя файла библиотеки, базовый адрес загрузки и размер загружаемого образа. Зная эти данные, можно проверить, что за DLL пытаются подгрузить в наш процесс и принять соответствующие меры. Например, при попытке подгрузить в процесс модуль мониторинга, можно отключить некоторые ветки алгоритма или исказить выдаваемые данные, а можно просто завершить работу приложения. Если пойти дальше, то теоретически можно даже модифицировать в памяти загруженную библиотеку, нейтрализовав в ней то, чего она не должна делать с вашим процессом. Просторы для фантазии безграничны.

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

Перезапуск приложения в случае его аварийного завершения

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

Перезапуск приложения в случае его аварийного завершения

Небольшое дополнение к статье про обработку критических ошибок. Обработать возникшую ошибку, сохранить в лог состояние регистров на момент падения, уведомить пользователя о произошедшем - это хорошо и правильно. Но в Windows есть еще один интересный механизм обработки критических ошибок. Речь идет об автоматическом перезапуске приложения в случае возникновения нештатной ситуации типа необрабатываемого исключения или безответного зависания.

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

Как узнать, что приложение запущено через ярлык

29.11.2020 | Категория: Образ мышления: Assembler | Автор: ManHunter
Очередная развлекушка на Ассемблере. Давайте узнаем, была ли наша программа запущена через .lnk-файл, то есть через ярлык, или же напрямую через Проводник, файловый менеджер или другой процесс. Для этого надо получить структуру STARTUPINFO, а затем проверить, установлен ли флаг STARTF_TITLEISLINKNAME в поле dwFlags.
  1.         STARTF_TITLEISLINKNAME = 0x800
  2.  
  3.         ; Получить информацию запуска
  4.         mov     [sinfo.cb],sizeof.STARTUPINFO
  5.         invoke  GetStartupInfo,sinfo
  6.  
  7.         ; Флаг установлен?
  8.         test    [sinfo.dwFlags],STARTF_TITLEISLINKNAME
  9.         jz      @f
  10.         ; Да, запуск выполнен через ярлык
  11.         ...
  12. @@:
  13.         ; Нет, прямой запуск
  14.         ...
Ранее этот флаг относился к недокументированным, сейчас в MSDN появилось его нормальное описание. Итак, если флаг STARTF_TITLEISLINKNAME установлен, то программа была запущена через ярлык, а в параметре lpTitle структуры STARTUPINFO содержится указатель на строку с полным путем к .lnk-файлу, через который был произведен запуск.

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

prev 01 02 03 04 05
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2023
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 3 (0.0023 сек.) / Память: 4.5 Mb
Наверх