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

Запуск задания 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 секунд.
Просмотров: 349 | Комментариев: 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
Читать статью целиком »
Просмотров: 949 | Комментариев: 1

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

Перезапуск приложения в случае его аварийного завершения
Небольшое дополнение к статье про обработку критических ошибок. Обработать возникшую ошибку, сохранить в лог состояние регистров на момент падения, уведомить пользователя о произошедшем - это хорошо и правильно. Но в Windows есть еще один интересный механизм обработки критических ошибок. Речь идет об автоматическом перезапуске приложения в случае возникновения нештатной ситуации типа необрабатываемого исключения или безответного зависания.
Читать статью целиком »
Просмотров: 1092 | Комментариев: 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
- ; Да, запуск выполнен через ярлык
- ...
- @@:
- ; Нет, прямой запуск
- ...
Читать статью целиком »
Просмотров: 782 | Комментариев: 0

Управление редактором реестра из своего приложения
27.05.2020 | Категория: Образ мышления: Assembler | Автор: ManHunter
Наверняка вы слышали о программе RegJump от SysInternals, ныне принадлежащая Microsoft. При помощи этой программы вы можете открыть regedit сразу же на нужной ветке реестра. Мне стало очень интересно, как она это делает. Дизассемблер в руки, отладчик в боевую готовность и вперед!Вот что мне удалось накопать. Я оставил только самый важный код, попутно упростив и оптимизировав его. Оригинальный RegJump сперва пытается найти запущенный regedit по наименованию класса окна, если такого нет, то пытается запустить regedit из системной папки. Так или иначе, вся работа выполняется с найденным окном. У меня подразумевается, что редактор реестра уже запущен.
Code (Assembler) : Убрать нумерацию
- section '.data' data readable writeable
- ; Классы окон для поиска
- szClass db 'RegEdit_RegEdit',0
- szList db 'SysTreeView32',0
- ; Название ветки реестра
- szReg db '\HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\WINDOWS\CURRENTVERSION\',0
Хэндл процесса необходим для синхронизации пользовательского ввода с окном приложения, поскольку все управление regedit выполняется через эмуляцию нажатий клавиш в списке. Для "своей" копии regedit, которая запущена RegJump, используется результат выполнения функции CreateProcess, для запущенного ранее экземпляра хэндл получается через пару функций GetWindowThreadProcessId и OpenProcess. Особых привилегий для этого не надо.
Code (Assembler) : Убрать нумерацию
- ; Найти окно редактора реестра
- invoke FindWindow,szClass,NULL
- or eax,eax
- jz loc_exit
- mov [hRWnd],eax
- ; Найти список в окне редактора реестра
- invoke FindWindowEx,[hRWnd],NULL,szList,NULL
- or eax,eax
- jz loc_exit
- mov [hWnd],eax
- ; Получить хэндл процесса-владельца
- invoke GetWindowThreadProcessId,[hRWnd],ProcessId
- invoke OpenProcess,PROCESS_QUERY_INFORMATION,0,[ProcessId]
- or eax,eax
- jz loc_exit
- mov [hProcess],eax
- ; Активировать окно редактора реестра
- invoke ShowWindow,[hRWnd],SW_RESTORE
- invoke SetForegroundWindow,[hRWnd]
- ; Установить фокус на список
- invoke SetFocus,[hWnd]
- invoke WaitForInputIdle,[hProcess],-1
- ; Вот тут непонятно :(
- invoke SendMessage,[hRWnd],WM_COMMAND,10288h,0
- invoke WaitForInputIdle,[hProcess],-1
- ; Перейти на верхний уровень списка
- mov ebx,30
- @@:
- invoke SendMessage,[hWnd],WM_KEYDOWN,VK_LEFT,0
- invoke WaitForInputIdle,[hProcess],-1
- sub ebx,1
- jnz @b
- ; Указатель на строку в названием ветки реестра
- mov esi,szReg
- loc_loop:
- lodsb
- or al,al
- jz loc_exit_clean
- cmp al,'\'
- jne @f
- ; Открыть ветку списка
- invoke SendMessage,[hWnd],WM_KEYDOWN,VK_RIGHT,0
- invoke WaitForInputIdle,[hProcess],-1
- jmp loc_loop
- @@:
- movzx eax,al
- ; Поиск строки в списке
- invoke SendMessage,[hWnd],WM_CHAR,eax,0
- invoke WaitForInputIdle,[hProcess],-1
- jmp loc_loop
- loc_exit_clean:
- invoke CloseHandle,[hProcess]
- loc_exit:
Читать статью целиком »
Просмотров: 1260 | Комментариев: 6
