Форум программистов, компьютерный форум, киберфорум
Программирование драйверов
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
78 / 78 / 34
Регистрация: 26.10.2011
Сообщений: 220
1

Маппирование памяти из user space в system space

12.11.2014, 12:07. Просмотров 1785. Ответов 7
Метки нет (Все метки)


В драйвер передается указатель из приложения, который указывает на область памяти в приложении. Можно ли маппировать эту область памяти, таким образом чтобы можно было к ней обращаться из драйвера?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
12.11.2014, 12:07
Ответы с готовыми решениями:

Доступ к PCI Configuration Space
Мне необходим доступ к PCI Configuration Space некоторого PCI устройства. Есть функции...

Kernel space и виртуальная таблица процесса
Приветствую, к примеру имеется dll файл который будет проецироваться в kernel space. Вопрос такой,...

Out of stack space
Добрый день. Разбираюсь с формами VBA, написал следующий код. Он выводит квадратный объект...

No space left on device
Всем привет. В общем, ситуация такая. Записал дистрибутив на флешку (8 гб). Начал создавать свой...

7
Студент
121 / 132 / 39
Регистрация: 07.04.2011
Сообщений: 503
12.11.2014, 16:57 2
Можно при передаче указателя запомнить процесс при помощи PsGetCurrentProcess, и потом при работе с этим указателем просто делать KeAttachProcess(результат PsGetCurrentProcess), подгрузиться адресс виртуальной таблици в того процесса в CR3 и можно работать уже с напрямую с памятью всего процесса.
1
Ушел с форума
Эксперт С++
16419 / 7394 / 1185
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
12.11.2014, 21:53 3
А зачем что-то куда-то маппировать ?
Пишите в память напрямую и все. Только в блоке __try/__except и
после проверки ProbeForRead/ProbeForWrite, в зависимости от
желаемого доступа к памяти.

Добавлено через 2 часа 49 минут
А если доступ к этой памяти нужен в контексте произвольного
потока и на IRQL >= DISPATCH_LEVEL, тогда следует воспользоваться
таким способом: создать MDL (IoAllocateMdl), залочить буфер в памяти
(MmProbeAndLockPages), а затем получить системный указатель на него
(MmGetSystemAddressForMdlSafe).
1
78 / 78 / 34
Регистрация: 26.10.2011
Сообщений: 220
12.11.2014, 22:42  [ТС] 4
Цитата Сообщение от MickeyBlueEyes Посмотреть сообщение
Можно при передаче указателя запомнить процесс при помощи PsGetCurrentProcess...
А всегда ли при вызове драйвера (DeviceIoControl) он будет находиться в контексте вызвавшего его процесса?

Цитата Сообщение от MickeyBlueEyes Посмотреть сообщение
потом при работе с этим указателем просто делать KeAttachProcess(результат PsGetCurrentProcess), подгрузиться адресс виртуальной таблици в того процесса в CR3 и можно работать уже с напрямую с памятью всего процесса.
Я так понимаю это переключение контекста процесса, оно наверно много времени занимает?
0
Студент
121 / 132 / 39
Регистрация: 07.04.2011
Сообщений: 503
12.11.2014, 23:07 5
Цитата Сообщение от sergestus Посмотреть сообщение
А всегда ли при вызове драйвера (DeviceIoControl) он будет находиться в контексте вызвавшего его процесса?
Да, всегда.
Цитата Сообщение от sergestus Посмотреть сообщение
Я так понимаю это переключение контекста процесса, оно наверно много времени занимает?
Нет ничего не будет переключаться, всё очень быстро будет, просто подгрузиться в регистр указатель на виртуальную таблицу процесса и всё, и ещё некоторые незначительные манипуляции выполнит ось, теперь можна в ядре использовать любые доступные адресса из АП.

Добавлено через 8 минут
Сверху человек ещё важные и полезные вещи сказал насчёт ProbeForRead/ProbeForWrite, если незнаем доступна память или не, то это выход.

Ах, ну если вы будете пользоваться той памятью только из контекста того же процесса, то никаких манипуляций не нужно с KeAttachProcess и тд..., это фишка если допустим мы находимся в контексте другого процесса и нужно чтото взять с другого процесса, то таким образом можна достучаться туда, но это как вариант, в ядре ещё можно заюзать ZwReadVirtualMemory.
0
78 / 78 / 34
Регистрация: 26.10.2011
Сообщений: 220
12.11.2014, 23:08  [ТС] 6
Цитата Сообщение от Убежденный Посмотреть сообщение
А зачем что-то куда-то маппировать ?
Драйвер вводит поток данных из устройства. Хочется иметь прямой доступ к данным из приложения, чтобы не делать системных вызовов.

Цитата Сообщение от Убежденный Посмотреть сообщение
А если доступ к этой памяти нужен в контексте произвольного
потока и на IRQL >= DISPATCH_LEVEL, тогда следует воспользоваться
таким способом: создать MDL (IoAllocateMdl), залочить буфер в памяти
(MmProbeAndLockPages), а затем получить системный указатель на него
(MmGetSystemAddressForMdlSafe).
Кажется это то, что мне нужно, насколько я понимаю буфер лочится в памяти при помощи MmProbeAndLockPages с параметром UserMode для буфера выделенного приложением?
0
Студент
121 / 132 / 39
Регистрация: 07.04.2011
Сообщений: 503
12.11.2014, 23:28 7
Тоже важно.
Цитата Сообщение от Убежденный Посмотреть сообщение
IRQL >= DISPATCH_LEVEL
Если память в свопе и будем на этих уровнях, то будет бсод, но я не думаю что у вас будет такой случай сейчас, а дальше уже сами дойдёте если нужно будет. А как сделать чтобы уже существующую память процесса не сбрасывалась в свап беспонятия.

Добавлено через 10 минут
Цитата Сообщение от sergestus Посмотреть сообщение
Кажется это то, что мне нужно, насколько я понимаю буфер лочится в памяти при помощи MmProbeAndLockPages с параметром UserMode для буфера выделенного приложением?
Незнаю как насчёт буфера уже выделеного приложениям, но можна выделить в ядре сделать предложенные манипуляции с UserMode, и тогда будет указатель для ядра и для процесса. Тоесть делаете запрос из приложения н выделения буфера он выделяет память и проецирует для процесса и указатель для процесса возвращает, а системный так и останется для ядра.

Добавлено через 5 минут
Из контекста нужного процесса.
C
1
2
3
4
5
int size = 128;
char* system_ptr = (char*)ExAllocatePool(NonPagedPool, size);
PMDL mdl = IoAllocateMdl(system_ptr, size, 0, 0, 0);
MmBuildMdlForNonPagedPool(mdl);
char* user_ptr = (char*)MmMapLockedPagesSpecifyCache(mdl, UserMode, MmCached, 0, 0, NormalPagePriority);
1
Ушел с форума
Эксперт С++
16419 / 7394 / 1185
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
13.11.2014, 01:46 8
Цитата Сообщение от MickeyBlueEyes Посмотреть сообщение
Можно при передаче указателя запомнить процесс при помощи PsGetCurrentProcess, и потом при работе с этим указателем просто делать KeAttachProcess(результат PsGetCurrentProcess)
Только в этом случае следует сначала зареференсить указатель на процесс (ObReferenceObject).
А то процессы - они такие, иногда дохнут, а на их месте вырастают другие...

Цитата Сообщение от sergestus Посмотреть сообщение
А всегда ли при вызове драйвера (DeviceIoControl) он будет находиться в контексте вызвавшего его процесса?
Если это драйвер верхнего уровня, то всегда. Но если над вами в стеке устройств
сидит кто-то еще, то этот "кто-то" может отложить запрос (STATUS_PENDING), а
затем возобновить его из системного потока или work item-а, тогда мы
окажемся в контексте системы.

Цитата Сообщение от sergestus Посмотреть сообщение
Драйвер вводит поток данных из устройства. Хочется иметь прямой доступ к данным из приложения, чтобы не делать системных вызовов.
В таком случае лучше сделать объект-секцию и использовать ее.
Фактически это и есть разделяемая память, только завернутая в объектный API системы.
Поищите в Гугле документ под названием "User-Mode Interactions: Guidelines for
Kernel-Mode Drivers", там такие вещи хорошо объясняются.

Цитата Сообщение от sergestus Посмотреть сообщение
Кажется это то, что мне нужно, насколько я понимаю буфер лочится в памяти при помощи MmProbeAndLockPages с параметром UserMode для буфера выделенного приложением ?
Да.
Не забудьте про try/except (и ProbeForRead/Write, если работаете с "сырым"
буфером, который пришел из user mode), иначе любой желающий с помощью
вашего драйвера сможет легко ронять систему в BSOD (без админских прав и т.п.),
или еще чего похуже. Про capture arguments и double fetch пока не пишу,
чтобы не пугать раньше времени

Цитата Сообщение от MickeyBlueEyes Посмотреть сообщение
Если память в свопе и будем на этих уровнях, то будет бсод
Не будет. Потому что:

MmProbeAndLockPages routine
http://msdn.microsoft.com/en-u... 85%29.aspx
MmProbeAndLockPages performs the following operations:

1. If the specified memory range is paged to a backing store (disk,
network, and so on), MmProbeAndLockPages makes it resident.

2. The routine then confirms that the pages permit the operation specified
by the Operation parameter.

3. If the memory range permits the specified operation, the routine locks
the pages in memory so that they cannot be paged out.
Use the MmUnlockPages
routine to unlock the pages.

4. Finally, the routine updates the page frame number (PFN) array in
the MDL to describe the locked physical pages.
То есть, функция сделает блок памяти резидентным и заблокирует в памяти.
До вызова MmUnlockPages своппинг ему не грозит, можете писать туда
хоть на IRQL == HIGH_LEVEL

Но обращаться к этой памяти пока можно только в контексте исходного процесса,
вот зачем нужна еще MmGetSystemAddressForMdlSafe - она создаст отображение
памяти на системный диапазон, после чего работать с ней можно будет в
контексте любого процесса (разумеется, через полученный указатель, а не
через исходный).

Из контекста нужного процесса.
C
1
2
3
4
5
int size = 128;
char* system_ptr = (char*)ExAllocatePool(NonPagedPool, size);
PMDL mdl = IoAllocateMdl(system_ptr, size, 0, 0, 0);
MmBuildMdlForNonPagedPool(mdl);
char* user_ptr = (char*)MmMapLockedPagesSpecifyCache(mdl, UserMode, MmCached, 0, 0, NormalPagePriority);
Тут не хватает try/except вокруг MmMapLockedPagesSpecifyCache, и по-хорошему,
системный буфер перед тем, как мапить в user mode, следует обнулить.
Мало ли там какие данные лежали до этого - пароли, имена, явки...
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
13.11.2014, 01:46

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь или здесь.

Java heap space
Здравствуйте. Есть цикл который прогоняет около миллиона итераций. Каждая итерация сначало получает...

Установка Crystal Space
Приветствую всех. Я тут решил заняться геймдевом, пока чисто для саморазвития... Нарыл такую вещь....

OutOfMEmoryError PerGen space
Здравствуйте. Такая проблема. Есть код public class PermGenSpace { public static void...

Unbound: No buffer space available
Имеется Unbound 1.4.21 module Iterator. Обслуживает абонентскую сеть, в логи сыпятся сообщения...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.