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

Передача данных между процессами с помощью 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 будет выгружена из его адресного пространства. Установка обработчика выполняется одной командой:Code (Assembler) : Убрать нумерацию
- ; Зарегистрировать обработчик загрузки и выгрузки DLL
- invoke LdrRegisterDllNotification,0,LdrDllNotification,NULL,Cookie
- or eax,eax
- jnz loc_error
Code (Assembler) : Убрать нумерацию
- LDR_DLL_NOTIFICATION_REASON_LOADED = 1
- LDR_DLL_NOTIFICATION_REASON_UNLOADED = 2
- struct NOTIFICATION_DATA
- Flags dd ?
- FullDllName dd ?
- BaseDllName dd ?
- DllBase dd ?
- SizeOfImage dd ?
- ends
- proc LdrDllNotification NotificationReason:DWORD,\
- NotificationData:DWORD,Context:DWORD
- pusha
- mov eax,[NotificationReason]
- ; EAX -> действие с DLL
- ; LDR_DLL_NOTIFICATION_REASON_LOADED = загружена
- ; LDR_DLL_NOTIFICATION_REASON_UNLOADED = выгружена
- ; Получить полный путь до файла DLL
- mov eax,[NotificationData]
- mov eax,[eax+NOTIFICATION_DATA.FullDllName]
- mov eax,[eax+4]
- ; EAX -> полное имя файла DLL
- ; Получить базовый адрес DLL
- mov eax,[NotificationData]
- mov eax,[eax+NOTIFICATION_DATA.DllBase]
- ; EAX -> DllBase библиотеки
- popa
- ret
- endp
Читать статью целиком »
Просмотров: 1067 | Комментариев: 1

Перезапуск приложения в случае его аварийного завершения
23.03.2021 | Категория: Образ мышления: Assembler | Автор: ManHunter

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

Как узнать, что приложение запущено через ярлык
29.11.2020 | Категория: Образ мышления: Assembler | Автор: ManHunter
Очередная развлекушка на Ассемблере. Давайте узнаем, была ли наша программа запущена через .lnk-файл, то есть через ярлык, или же напрямую через Проводник, файловый менеджер или другой процесс. Для этого надо получить структуру STARTUPINFO, а затем проверить, установлен ли флаг STARTF_TITLEISLINKNAME в поле dwFlags.Code (Assembler) : Убрать нумерацию
- STARTF_TITLEISLINKNAME = 0x800
- ; Получить информацию запуска
- mov [sinfo.cb],sizeof.STARTUPINFO
- invoke GetStartupInfo,sinfo
- ; Флаг установлен?
- test [sinfo.dwFlags],STARTF_TITLEISLINKNAME
- jz @f
- ; Да, запуск выполнен через ярлык
- ...
- @@:
- ; Нет, прямой запуск
- ...
Читать статью целиком »
Просмотров: 837 | Комментариев: 0
