ProbeForRead по нулевому адресу
От: emusic Франция https://software.muzychenko.net/ru
Дата: 15.03.06 13:57
Оценка:
Случайно обнаружил, что ProbeForRead в запросе от приложения спокойно пропускает нулевой адрес, на котором затем успешно трапается операция доступа... Это так и надо, или глюк? WinXP SP2.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: ProbeForRead по нулевому адресу
От: Злость Россия  
Дата: 15.03.06 14:59
Оценка:
Здравствуйте, emusic, Вы писали:

E>Случайно обнаружил, что ProbeForRead в запросе от приложения спокойно пропускает нулевой адрес, на котором затем успешно трапается операция доступа... Это так и надо, или глюк? WinXP SP2.


Хочется увидеть кусок кода — где это происходит. И какие исключения ловятся.
Правда, Ложь — мне все одно — я имею свое мнение.
Если функция недокументированна — это не значит, что ее не используют все ваши конкуренты в своих продуктах.
Любой строй переходный и отрицать это значит быть закостенелым идиотом.
Re[2]: ProbeForRead по нулевому адресу
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 15.03.06 15:43
Оценка:
Здравствуйте, Злость, Вы писали:

З>Хочется увидеть кусок кода — где это происходит. И какие исключения ловятся.


        SourceWP = (KmiWavePacket *) (SL.Parameters.Read.ByteOffset.LowPart);

        Size = sizeof (WP);

        __try {

          ProbeForRead (SourceWP, Size, 1);

        } __except (EXCEPTION_EXECUTE_HANDLER) {

          Status = GetExceptionCode ();

          break;

        }

        memcpy (&WP, SourceWP, Size);


Это старый и кривой обработчик IRP_MJ_READ/WRITE из старого же legacy драйвера. Драйвер переделывался из VxD, которому каждый запрос передавался в виде унифицированного пакета, внутри которого уже задавались функции и параметры. Чтобы сильно не переделывать, сделал передачу пакета через поля Offset в OVERLAPPED Все отлично работало много лет, пока одному из юзеров не вздумалось на этот драйвер натравить Device Path Exerciser. Вот и оказалось, что ProbeForRead вполне пропускает нулевой адрес, на котором потом трапается memcpy. Когда засунул memcpy внутрь try-блока — падения прекратились.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: ProbeForRead по нулевому адресу
От: Злость Россия  
Дата: 15.03.06 16:07
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

[skip]

ЕМ>Это старый и кривой обработчик IRP_MJ_READ/WRITE из старого же legacy драйвера. Драйвер переделывался из VxD, которому каждый запрос передавался в виде унифицированного пакета, внутри которого уже задавались функции и параметры. Чтобы сильно не переделывать, сделал передачу пакета через поля Offset в OVERLAPPED Все отлично работало много лет, пока одному из юзеров не вздумалось на этот драйвер натравить Device Path Exerciser. Вот и оказалось, что ProbeForRead вполне пропускает нулевой адрес, на котором потом трапается memcpy. Когда засунул memcpy внутрь try-блока — падения прекратились.


Пропускает потому что у нее задача другая. Она говорит что определнный диапазон памяти находится в user-space.
Тоесть в итоге гарантирует что не попадет облать ядра.
Правда, Ложь — мне все одно — я имею свое мнение.
Если функция недокументированна — это не значит, что ее не используют все ваши конкуренты в своих продуктах.
Любой строй переходный и отрицать это значит быть закостенелым идиотом.
Re[4]: ProbeForRead по нулевому адресу
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 15.03.06 17:12
Оценка:
Здравствуйте, Злость, Вы писали:

З>Пропускает потому что у нее задача другая. Она говорит что определнный диапазон памяти находится в user-space. Тоесть в итоге гарантирует что не попадет облать ядра.


Чтобы определить, к какому классу адресов относится диапазон памяти, совершенно не обязательно вводить специальную функцию — достаточно банального сравнения, коли уж адресное пространство жестко поделено. В MSDN об этой функции говорится:

Kernel-mode drivers must use ProbeForRead to validate read access to buffers that are allocated in user space.


Получается, что она должна определять — доступен буфер для чтения, или нет.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: ProbeForRead по нулевому адресу
От: Злость Россия  
Дата: 15.03.06 19:03
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Здравствуйте, Злость, Вы писали:


З>>Пропускает потому что у нее задача другая. Она говорит что определнный диапазон памяти находится в user-space. Тоесть в итоге гарантирует что не попадет облать ядра.


ЕМ>Чтобы определить, к какому классу адресов относится диапазон памяти, совершенно не обязательно вводить специальную функцию — достаточно банального сравнения, коли уж адресное пространство жестко поделено. В MSDN об этой функции говорится:


ЕМ>

ЕМ>Kernel-mode drivers must use ProbeForRead to validate read access to buffers that are allocated in user space.


ЕМ>Получается, что она должна определять — доступен буфер для чтения, или нет.


Как говорится ... доку от M$ надо уметь читать.

Note that ProbeForRead only validates that the address and length fall within the possible user-mode address range (slightly under 2 GB for a system without 4GT, for example), not whether the memory address is valid. In contrast, ProbeForWrite will try to access the first byte in each page of the length specified to verify that these are valid memory addresses.

Правда, Ложь — мне все одно — я имею свое мнение.
Если функция недокументированна — это не значит, что ее не используют все ваши конкуренты в своих продуктах.
Любой строй переходный и отрицать это значит быть закостенелым идиотом.
Re[6]: ProbeForRead по нулевому адресу
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 16.03.06 01:57
Оценка:
Здравствуйте, Злость, Вы писали:

З>

З>Note that ProbeForRead only validates that the address and length fall within the possible user-mode address range


Бааалин. Ну как всегда — комментарии в MSDN появляются спустя много лет после того, как У меня в 2004APR такой статьи нет Буду добывать более новую MSDN
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[7]: ProbeForRead по нулевому адресу
От: Злость Россия  
Дата: 16.03.06 05:15
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Здравствуйте, Злость, Вы писали:


З>>

З>>Note that ProbeForRead only validates that the address and length fall within the possible user-mode address range


ЕМ>Бааалин. Ну как всегда — комментарии в MSDN появляются спустя много лет после того, как У меня в 2004APR такой статьи нет Буду добывать более новую MSDN


В догонку — самый лучшый способ пойти посмотреть реализацию этой функции в ядре.

PAGE:004B26C1 ; __stdcall ProbeForRead(x,x,x)
PAGE:004B26C1                 public _ProbeForRead@12
PAGE:004B26C1 _ProbeForRead@12 proc near
PAGE:004B26C1
PAGE:004B26C1 arg_4           = dword ptr  8
PAGE:004B26C1 arg_8           = dword ptr  0Ch
PAGE:004B26C1 arg_C           = dword ptr  10h
PAGE:004B26C1
PAGE:004B26C1 ; FUNCTION CHUNK AT PAGE:0053095E SIZE 0000000A BYTES
PAGE:004B26C1
PAGE:004B26C1                 mov     edi, edi
PAGE:004B26C3                 push    ebp
PAGE:004B26C4                 mov     ebp, esp
PAGE:004B26C6                 mov     ecx, [ebp+arg_8]
PAGE:004B26C9                 test    ecx, ecx
PAGE:004B26CB                 jz      short loc_4B26EC
PAGE:004B26CD                 mov     eax, [ebp+arg_C]
PAGE:004B26D0                 lea     edx, [eax-1]
PAGE:004B26D3                 mov     eax, [ebp+arg_4]
PAGE:004B26D6                 test    eax, edx
PAGE:004B26D8                 jnz     loc_53095E
PAGE:004B26DE                 add     ecx, eax
PAGE:004B26E0                 cmp     ecx, eax
PAGE:004B26E2                 jb      short loc_4B26F0
PAGE:004B26E4                 cmp     ecx, _MmUserProbeAddress
PAGE:004B26EA                 ja      short loc_4B26F0
PAGE:004B26EC
PAGE:004B26EC loc_4B26EC:                             ; CODE XREF: ProbeForRead(x,x,x)+Aj
PAGE:004B26EC                                         ; ProbeForRead(x,x,x)+34j ...
PAGE:004B26EC                 pop     ebp
PAGE:004B26ED                 retn    0Ch
PAGE:004B26F0 ; ---------------------------------------------------------------------------
PAGE:004B26F0
PAGE:004B26F0 loc_4B26F0:                             ; CODE XREF: ProbeForRead(x,x,x)+21j
PAGE:004B26F0                                         ; ProbeForRead(x,x,x)+29j
PAGE:004B26F0                 call    _ExRaiseAccessViolation@0 ; ExRaiseAccessViolation()
PAGE:004B26F5                 jmp     short loc_4B26EC
PAGE:004B26F5 _ProbeForRead@12 endp


PAGE:0053095E ; START OF FUNCTION CHUNK FOR _ProbeForRead@12
PAGE:0053095E
PAGE:0053095E loc_53095E:                             ; CODE XREF: ProbeForRead(x,x,x)+17j
PAGE:0053095E                 call    _ExRaiseDatatypeMisalignment@0 ; ExRaiseDatatypeMisalignment()
PAGE:00530963                 jmp     loc_4B26EC
PAGE:00530963 ; END OF FUNCTION CHUNK FOR _ProbeForRead@12
Правда, Ложь — мне все одно — я имею свое мнение.
Если функция недокументированна — это не значит, что ее не используют все ваши конкуренты в своих продуктах.
Любой строй переходный и отрицать это значит быть закостенелым идиотом.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.