2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 Проблема - MmGetSystemAddressForMdlSafe и ProbeForRead
Сообщение16.08.2010, 23:32 


26/03/09
97
Следующий код в драйвере обрабатывающий IRP запрос:
Используется синтаксис C++
 
#define CtlCodeCopy CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
 

- генерирует исключение при обращении к выходному буферу режма ядра, а именно функция ProbeForRead :

код: [ скачать ] [ спрятать ]
Используется синтаксис C++
 
NTSTATUS Handler801(IN PDEVICE_OBJECT pDeviceObject, IN PIRP Irp, PIO_STACK_LOCATION pSL)
{
        DbgPrint("Handler801");
        PVOID pOutBuff = MmGetSystemAddressForMdlSafe (Irp->MdlAddress,HighPagePriority);
if (pOutBuff != NULL)
{
__try
 {
     ProbeForRead(pOutBuff, Irp->MdlAddress->ByteCount, TYPE_ALIGNMENT(char));
     DbgPrint("Handler801 : __try");
 }
__except (EXCEPTION_EXECUTE_HANDLER)
 {
    DbgPrint("Handler801 : __except");
    return STATUS_MEMORY_NOT_ALLOCATED;
 }
}
        Irp->IoStatus.Information = 0 ;
        return STATUS_SUCCESS;
}
 


Указатель pOutBuff не NULL, почему функция ProbeForRead вызывает исключение не пойму.
Вот лог DebugView - содержимое структур IO_STACK_LOCATION и IRP, тут всё в порядке:
00000000 0.00000000 DriverDeviceControl
00000001 0.00000301 OutputBufferLength=4096
00000002 0.00000425 InputBufferLength=4096
00000003 0.00000555 IoControlCode=2236422
00000004 0.00000669 Type3InputBuffer=0

00000005 0.00000815 Irp->MdlAddress->ByteCount=4096
00000006 0.00000939 Irp->MdlAddress->Size=32
00000007 0.00001070 Irp->MdlAddress->ByteOffset=0
00000008 0.00001207 Irp->MdlAddress->StartVa=17305600
00000009 0.00001321 IoCtl=801

Вот текст программы посылающей запрос драйверу:
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
 
hDevice = CreateFile("\\\\.\\MyDevice0",  // drive to open
                    GENERIC_READ | GENERIC_WRITE,
                    FILE_SHARE_READ |   // share mode
                    FILE_SHARE_WRITE,
                    NULL,                         // default security attributes
                    OPEN_EXISTING,        // disposition
                    0,                              // file attributes
                    NULL);                       // do not copy file attributes
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
  { return;}
...

 LPVOID lpReserv = VirtualAlloc(NULL,
                                 SystemInfo.dwAllocationGranularity,
                                 MEM_RESERVE,
                                 PAGE_READWRITE);
 LPVOID lpCommitIn = VirtualAlloc(lpReserv,
                                   SystemInfo.dwPageSize,
                                   MEM_COMMIT,
                                   PAGE_READWRITE);
  LPVOID lpCommitOut = VirtualAlloc((LPVOID) ((DWORD)lpReserv + SystemInfo.dwPageSize),
                                    SystemInfo.dwPageSize,
                                    MEM_COMMIT,
                                    PAGE_READWRITE);
...
BOOL bResult = DeviceIoControl(hDevice,  // device to be queried
                                                  CtlCodeCopy,                    // operation to perform
                                                  lpCommitIn,                       // input buffer
                                                  SystemInfo.dwPageSize,    // input buffer
                                                  lpCommitOut,                    // output buffer
                                                  SystemInfo.dwPageSize,     // output buffer
                                                  &junk,                                 // # bytes returned
                                                  (LPOVERLAPPED) NULL);     // synchronous I/O

... Do something ...

  CloseHandle(hDevice);
  VirtualFree(lpCommitOut,0,MEM_DECOMMIT);
  VirtualFree(lpCommitIn,0,MEM_DECOMMIT);
  VirtualFree(lpReserv,0,MEM_RELEASE);

  return ;
 

 Профиль  
                  
 
 Re: Проблема - MmGetSystemAddressForMdlSafe и ProbeForRead
Сообщение17.08.2010, 08:46 


16/06/10
199
Может так: т.к. TransferType = METHOD_OUT_DIRECT, по адресу Irp->MdlAddress - буфер вывода (для драйвера) и, соответственно, созданный MDL доступен только на запись.

 Профиль  
                  
 
 Re: Проблема - MmGetSystemAddressForMdlSafe и ProbeForRead
Сообщение17.08.2010, 09:24 


26/03/09
97
Пробовал по отдельности и ProbeForWrite и ProbeForRead и с выходным и с входным буфером, результат тот же, генерируется исключение:
Используется синтаксис C++
 
__try
 {
       //ProbeForRead(pOutBuff, Irp->MdlAddress->ByteCount, TYPE_ALIGNMENT(char));
        ProbeForWrite(pOutBuff, Irp->MdlAddress->ByteCount, TYPE_ALIGNMENT(char));
        //ProbeForRead(Irp->AssociatedIrp.SystemBuffer, pSL->Parameters.DeviceIoControl.InputBufferLength, 1);
        //ProbeForWrite(Irp->AssociatedIrp.SystemBuffer, pSL->Parameters.DeviceIoControl.InputBufferLength, 1);
 }
 

 Профиль  
                  
 
 Re: Проблема - MmGetSystemAddressForMdlSafe и ProbeForRead
Сообщение17.08.2010, 15:02 


16/06/10
199
Давайте разбираться.
При обработке DeviceIoControlTransferType=METHOD_xx_DIRECT) система создает MDL, который описывает физические страницы памяти, относящиеся к буферу ввода/вывода и фиксирует (lock) эти страницы в памяти. Драйвер использует MmGetSystemAddressForMdlSafe для отображения этих страниц в свое (kernel-mode) адресное пространство. Но функции ProbeForRead и ProbeForWrite используются только для проверки буферов памяти в пользовательском (user-mode) адресном пространстве:
Windows DDK писал(а):
ProbeForRead
...
Do not use this routine on kernel-mode addresses; it will raise an exception.
...
Вот если бы использовался METHOD_NEITHER...

См. подробности - User-Mode Interactions: Guidelines for Kernel-Mode Drivers.

 Профиль  
                  
 
 Re: Проблема - MmGetSystemAddressForMdlSafe и ProbeForRead
Сообщение17.08.2010, 15:44 


26/03/09
97
Точно, спасибо lim0n, как это я сам не обратил внимания, бывает...
- "If the specified range of memory is not within the user-mode address range, ProbeForRead raises the STATUS_ACCESS_VIOLATION exception. "
А я же передавал в эту функцию виртуальный адрес kernel-mode .

Попробовал записать строку из user-mode во входной буфер, передал в дравер, и потом в драйвере вернул эту строку в выходной буфер и распечатал в user-mode - всё работает !
Спаибо за помощь !

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 5 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group