Функции для управления устройствами
Задание 2. Исследовать параметры функции NtReadFile.
Указания к выполнению.
1. Функция NtReadFile имеет следующие параметры:
- FileHandle – дескриптор файла, информацию из которого требуется прочитать;
- Event – дескриптор объекта "Событие", которое может быть установлено при завершении операции чтения (необязательный параметр);
- ApcRoutine, ApcContext – зарезервированные неиспользуемые параметры;
- IoStatusBlock – указатель на структуру IO_STATUS_BLOCK, в которой будет содержаться статус операции после завершения чтения, в частности, количество реально прочитанных байт (см. файл public\sdk\inc\ntioapi.h, строка 451);
- Buffer – указатель на область памяти (буфер), в которую будут помещены прочитанные данные;
- Length – размер буфера в байтах;
- ByteOffset – определяет для операции чтения смещение в байтах относительно начала файла;
- Key – необязательный параметр, используемый в случае блокировки файла.
Значения параметров можно посмотреть в окне Locals:
Дескриптор файла равен 1C, адрес буфера равен 0x0012FF14, размер буфера – 80 байт (0x50), смещение в файле равно нулю.
Посмотрим, что находится в данный момент в буфере:
dd 12FF14
Пока данные не прочитаны, буфер пуст.
По дескриптору файла можно узнать, что это за файл. Воспользуемся следующей командой:
!handle 1C f 8222F630
f – отображение полной информации об объекте;
8222F630 – адрес объекта EPROCESS процесса ReadFile.exe.
Как видно из рисунка, дескриптор 1C описывает файл input.txt.
Задание 3. Исследовать структуру FILE_OBJECT.
Указания к выполнению.
1. Как уже отмечалось, в строке 121 вызывается функция ObReferenceObjectByHandle, которая в переменной fileObject возвращает указатель на объект FILE_OBJECT для файла input.txt.
Вследствие оптимизации программного кода ядра значение переменной fileObject невозможно напрямую посмотреть в отладчике (например, окно Locals не показывает эту переменную, наведение указателя мыши также не дает результата). Можно определить адрес объекта FILE_OBJECT, исследуя дизассемблированный код (окно Disassembly отладчика), но мы поступим проще.
В предыдущем задании при помощи команды
!handle 1C f 8222F630
нам удалось по дескриптору определить имя файла. В результате этой же команды выводится и адрес объекта FILE_OBJECT:
Таким образом, адрес объекта FILE_OBJECT для файла input.txt равен 0x81FFF2F8.
2. Изучим информацию, содержащуюся в объекте FILE_OBJECT.
Для этого можно воспользоваться двумя способами.
Способ 1. При помощи команды:
dt FILE_OBJECT 81FFF2F8
Поле Type равно 5 – согласно константам, определенным в файле base\ntos\inc\io.h (строка 35), это тип IO_TYPE_FILE.
В структуре присутствует адрес объекта DEVICE_OBJECT, с которым связан данный файл (см. лекцию 15 "Управление устройствами", рис. 15.1 и рис. 15.2).
Способ 2. При помощи команды:
!fileobj 81FFF2F8
Здесь присутствует та же информация, что и в первом случае.
Задание 4. Исследовать структуру DEVICE_OBJECT.
Указания к выполнению.
1. В предыдущем задании в информации, выводимой об объекте FILE_OBJECT, присутствует адрес объекта DEVICE_OBJECT, на котором находится файл. Этот адрес равен 0x823ADE00.
Чтобы посмотреть информацию об объекте DEVICE_OBJECT по этому адресу, можно опять воспользоваться либо общей командой отображения типов данных dt, либо специальной командой !devobj. Продемонстрируем результат второго способа:.
!devobj 823ADE00
Данная команда сообщает имя драйвера, который управляет устройством (\Driver\Ftdisk – диспетчер томов) и адрес объекта драйвера DRIVER_OBJECT (0x82373690). Кроме того, из рисунка видно, что данное устройство отвечает за том HarddiskVolume1 (диск C).