Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
vazhnoe.docx
Скачиваний:
6
Добавлен:
01.07.2025
Размер:
843 Кб
Скачать
☆

51. Понятие пакета ввода-вывода (irp). Структура пакета ввода-вывода. Схема обработки пакета ввода-вывода при выполнении чтения-записи файла.

Понятие пакета IRP и его структура

Берём из предыдущего вопроса…

Схема обработки IRP при выполнении чтения-записи файла

1.Менеджер ввода-вывода обращается к драйверу файловой системы с IRP-пакетом, созданным для выполнения чтения-записи файла. Драйвер обращается к своей записи IO_STACK_LOCATION и определяет, какую именно операцию он должен выполнить.

2.Драйвер файловой системы для выполнения операции с файлом может создавать свои IRP с помощью IoAllocateIrp(). Или же он может в уже имеющемся IRP сформировать IO_STACK_LOCATION для драйвера более низкого уровня с помощью IoGetNextIrpStackLocation().

3.Если драйвер создает собственные IRP-пакеты, он должен зарегистрировать в них свою процедуру ZzzIoCompletion(), которая выполнит удаление IRP-пакетов после обработки драйверами нижнего уровня. За удаление своих IRP каждый драйвер отвечает сам. Менеджер ввода-вывода отвечает за удаление своего IRP, созданного для выполнения ввода-вывода.

Драйвер файловой системы устанавливает в IO_STACK_LOCATION указатель CompletionRoutine на свою процедуру XxxIoCompletion(), формирует IO_STACK_LOCATION для драйвера более низкого уровня с помощью IoGetNextIrpStackLocation(), вписывая нужные значения параметров, и обращается к драйверу более низкого уровня с помощью IoCallDriver().

4.Управление передается драйверу устройства процедуре YyyDispatchRead/Write(), зарегистрированной в объекте DRIVER_OBJECT под номером IRP_MJ_XXX. Драйвер устройства не может выполнить операцию ввода-вывода в синхронном режиме. Он помечает IRP-пакет с помощью IoMarkIrpPending() как требующий ожидания обработки или передачи другой процедуре YyyDispatch().

5.Менеджер ввода-вывода получает информацию, что драйвер устройства занят, и ставит IRP в очередь к объекту DEVICE_OBJECT драйвера.

6.Когда устройство освобождается, в драйвере устройства вызывается процедура обработки прерываний (ISR). Она обнаруживает IRP в очереди к устройству и с помощью IoRequestDpc() создает DPC-процедуру для обработки IRP на более низком уровне приоритета прерываний.

7.DPC-процедура с помощью IoStartNextPacket() извлекает из очереди IRP и выполняет ввод-вывод. Наконец, она устанавливает статус-код в IRP и вызывает IoCompleteRequest().

8.В каждом драйвере в стеке вызывается процедура завершения XxxIoCompletion(). В драйвере файловой системы она проверяет статус-код и либо повторяет запрос (в случае сбоя), либо завершает его удалением всех собственных IRP (если они были). В конце, IRP-пакет оказывается в распоряжении менеджера ввода-вывода, который возвращает вызывающему потоку результат в виде NTSTATUS.

РИСУНОК К ВОПРОСУ 51

52. Перехват api-вызовов ос Windows в пользовательском режиме. Внедрение dll с помощью реестра. Внедрение dll с помощью ловушек. Внедрение dll с помощью дистанционного потока.

Перехват API-вызовов ОС Windows в пользовательском режиме.

Задача – изменить поведение окна:

HWND hwnd = FindWindow(ClassName, WindowName);

SetClassLongPtr(hwnd, GWLP_WNDPROC, MyWindowProc);

Изменяемый оконный класс может находиться в адресном пространстве другого процесса, и адрес процедуры MyWindowProc будет не валиден.

Внедрение DLL с помощью реестра:

Зарегистрировать DLL в реестре (имя не должно содержать пробелы): HKLM\Software\Microsoft\Windows_NT\CurrentVersion\Windows\AppInit_DLLs

Выполнить API-перехват в DllMain (reason == DLL_PROCESS_ATTACH). Функции Kernel32.dll можно вызывать смело. С вызовами функций из других DLL могут быть проблемы.

Внедрение DLL с помощью ловушек:

HHOOK SetWindowsHookEx(int idHook, HOOKPROC lpfn, INSTANCE hMod, DWORD dwThreadId); UnhookWindowsHookEx().

Процедура ловушки:

LRESULT MyHookProc(int code, WPARAM wParam, LPARAM lParam); code: если HC_ACTION, надо обработать, если меньше нуля, – вызвать:

LRESULT CallNextHookEx(HHOOK hhook, int code, WPARAM wParam, LPARAM lParam);

Внедрение DLL с помощью дистанционного потока:

HANDLE CreateRemoteThread(HANDLE hProcess, SECURITY_ATTRIBUTES* securityAttributes, DWORD dwStackSize, THREAD_START_ROUTTNE* startAddress, void* parameter, DWORD dwCreationFlags, DWORD* pThreadId);

DWORD ThreadProc(void* parameter);

HINSTANCE LoadLibrary(PCTSTR fileName);

void* p = GetProcAddress(GetModuleHandle("Kernel32"), "LoadLibraryW");

Передача данных в дистанционный поток:

void* VirtualAllocEx (HANDLE hProcess, void* lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);

bool VirtualFreeEx(HANDLE hProcess, void* lpAddress, SIZE_T dwSize, DWORD dwFreeType);

bool WriteProcessMemory(HANDLE hProcess, void* lpBaseAddress, const void* lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesWritten);

bool ReadProcessMemory(HANDLE hProcess, void* lpBaseAddress, const void* lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead);

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]