Поля StartVa и Process в MDL
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 11.07.19 20:35
Оценка:
Перед объявлением MDL в wdm.h есть комментарий:

// Notice that while in the context of the subject thread, the base virtual
// address of a buffer mapped by an MDL may be referenced using the following:
//
// Mdl->StartVa | Mdl->ByteOffset


Однако, если я отображаю MDL, описывающий блок памяти из nonpaged pool, в адресное пространство текущего процесса (UserMode в MmMapLockedPages[SpecifyCache]), то в StartVa всегда вижу нуль, хотя страницы успешно отображаются, функции возвращают пользовательские адреса, и страницы доступны из пользовательского режима. В поле Process тоже всегда вижу нуль. MmUnmapLockedPages, вызываемая в контексте нужного процесса, тоже работает нормально.

Оно так и должно работать, или я что-то делаю не так?
mdl startva process usermode mmmaplockedpages mmmaplockedpagesspecifycache mmunmaplockedpages
Re: Поля StartVa и Process в MDL
От: EreTIk EreTIk's Box
Дата: 12.07.19 10:04
Оценка:
ЕМ>Перед объявлением MDL в wdm.h есть комментарий:

ЕМ>

ЕМ>// Notice that while in the context of the subject thread, the base virtual
ЕМ>// address of a buffer mapped by an MDL may be referenced using the following:
ЕМ>//
ЕМ>// Mdl->StartVa | Mdl->ByteOffset


ЕМ>Однако, если я отображаю MDL, описывающий блок памяти из nonpaged pool, в адресное пространство текущего процесса (UserMode в MmMapLockedPages[SpecifyCache]), то в StartVa всегда вижу нуль, хотя страницы успешно отображаются, функции возвращают пользовательские адреса, и страницы доступны из пользовательского режима. В поле Process тоже всегда вижу нуль. MmUnmapLockedPages, вызываемая в контексте нужного процесса, тоже работает нормально.


А откуда взялся этот MDL? Поле StartVa заполняется при создании макросом MmInitializeMdl(...) (есть в wdm.h), который вызывается из IoAllocateMdl(...).
Re[2]: Поля StartVa и Process в MDL
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 12.07.19 10:23
Оценка:
Здравствуйте, EreTIk, Вы писали:

ETI>А откуда взялся этот MDL?


Разные MDL берутся из разных источников. Одни — из IoAllocateMdl, другие — из MmAllocatePagesForMdl, и т.п.

ETI>Поле StartVa заполняется при создании


Я в курсе. Вопрос в том, почему это поле не корректируется при отображении MDL в адресное пространство пользовательского процесса, и не выполняется правило, приведенное в описании структуры.

Ну и для чего там поле Process, если после MmMapLockedPages[SpecifyCache] с UserMode там всегда нуль? Ни MmMapLockedPages[SpecifyCache], ни MiMapLockedPagesInUserSpace, через которую они работают, не меняет значения этого поля.

Насколько я понимаю, один MDL может быть одновременно отображен и в системное, и в пользовательское АП, но не в разные пользовательские АП.
Re: Поля StartVa и Process в MDL
От: reversecode google
Дата: 12.07.19 10:36
Оценка:
попробовать поиграться с правильным Flags при создании Mdl
что бы оно отображалось в пользовательское пространство
Re[2]: Поля StartVa и Process в MDL
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 12.07.19 10:46
Оценка:
Здравствуйте, reversecode, Вы писали:

R>попробовать поиграться с правильным Flags при создании Mdl


Зачем? Документация не предлагает клиенту управлять флагами, это уже будет хак.

R>что бы оно отображалось в пользовательское пространство


Разве я говорил, что оно не отображается?
Re[3]: Поля StartVa и Process в MDL
От: reversecode google
Дата: 12.07.19 11:11
Оценка:
хотел было переспросить вначале — так он не отображается ?
но решил что и такой совет сойдет
играть с флагом можно и на чтение
какие значения в нем находятся ?
Re[3]: Поля StartVa и Process в MDL
От: EreTIk EreTIk's Box
Дата: 12.07.19 11:12
Оценка:
ЕМ>Разные MDL берутся из разных источников. Одни — из IoAllocateMdl, другие — из MmAllocatePagesForMdl, и т.п.

ETI>>Поле StartVa заполняется при создании


ЕМ>Я в курсе. Вопрос в том, почему это поле не корректируется при отображении MDL в адресное пространство пользовательского процесса, и не выполняется правило, приведенное в описании структуры.


В стартовом сообщении был посыл, что в StartVa == NULL
  Скрытый текст
ЕМ> в StartVa всегда вижу нуль

Если оно не корректируется, то изначальный IoAllocateMdl был с аргументом VirtualAddress=NULL? Не думаю, что это правильно.

ЕМ>Ну и для чего там поле Process, если после MmMapLockedPages[SpecifyCache] с UserMode там всегда нуль? Ни MmMapLockedPages[SpecifyCache], ни MiMapLockedPagesInUserSpace, через которую они работают, не меняет значения этого поля.


Судя по исходникам WRK (функция MmProbeAndLockPages), заполненный Process означает не просто спроецированную MDL:
        //
        // Initialize the MDL process field (assume the probe will succeed).
        //

        MemoryDescriptorList->Process = CurrentProcess;
Re[4]: Поля StartVa и Process в MDL
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 12.07.19 11:34
Оценка:
Здравствуйте, reversecode, Вы писали:

R>хотел было переспросить вначале — так он не отображается ?


Зачем, если я в исходном сообщении написал, что все отображается?

R>играть с флагом можно и на чтение

R>какие значения в нем находятся ?

Везде — MDL_PAGES_LOCKED. Для отображенных в пространство ядра — MDL_MAPPED_TO_SYSTEM_VA. В зависимости от режимов — MDL_SOURCE_IS_NONPAGED_POOL, MDL_ALLOCATED_FIXED_SIZE.

Но какой смысл это обсуждать, если среди флагов MDL нет таких, что отмечали бы отображение в пользовательские АП?
Re[4]: Поля StartVa и Process в MDL
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 12.07.19 11:41
Оценка:
Здравствуйте, EreTIk, Вы писали:

ETI>Если оно не корректируется, то изначальный IoAllocateMdl был с аргументом VirtualAddress=NULL?


Нет. Изначально в StartVa записывался валидный исходный адрес, а после MmMapLockedPages[SpecifyCache] я вижу его обнуленным. Возможно, его обнуляет еще кто-то по дороге — могу присмотреться, если это имеет значение.

ETI>Не думаю, что это правильно.


Это как раз вполне правильно, поскольку MmInitializeMdl, MmCreateMdl, IoAllocateMdl не интересуются фактической валидностью этого адреса. Он им нужен только для определения потребного количества страниц в таблице. Ядро в ряде случаев явно вызывает их с указанием нулевого адреса.

ETI>Судя по исходникам WRK (функция MmProbeAndLockPages), заполненный Process означает не просто спроецированную MDL:


Ну да, туда записывается адрес описателя процесса, в АП которого отображены страницы. Но это делает только MmProbeAndLockPages, а остальные — нет. Бардак какой-то.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.