Не срабатывает VEH для отлова PAGE_GUARD

Тема в разделе "WASM.WIN32", создана пользователем d2k9, 29 авг 2009.

  1. d2k9

    d2k9 Алексей

    Публикаций:
    0
    Регистрация:
    14 сен 2008
    Сообщения:
    325
    Пишу на дельфи, детям и женщинам с чувствительной психикой не читать.
    Собственно сабж: при обращении к странице с атрибутом PAGE_GUARD не возникает обработки исключения, хотя сам PAGE_GUARD отрабатывает как положено и при следующем обращении к этой странице она становится доступной. ОС Windows 7 x64 RTM.

    Код (Text):
    1. function AddVectoredExceptionHandler(FirstHandle: ULONG; VectoredHandler : Pointer): PVOID; stdcall; external 'kernel32.dll';
    2.  
    3. var
    4. pHandler, pMem: Pointer;
    5. s: string;
    6. numWr: DWORD;
    7.  
    8. // собственно сам обработчик, который просто фиксирует исключение
    9. function MyVectoredHandler(ExceptionInfo: PExceptionPointers): Longint; stdcall;
    10. begin
    11.    writeln('Vectored exception handled');
    12. end;
    13.  
    14. begin
    15. // добавляем обработчик первым в цепочке, здесь всё ОК
    16. pHandler := AddVectoredExceptionHandler(1, @MyVectoredHandler);
    17.  if pHandler = nil then MessageBox(0, PChar(SysErrorMessage(GetLastError)), 'Last Error', MB_OK);
    18.  
    19. // здесь тоже всё ОК, PAGE_GUARD назначается как и положено
    20. pMem:=VirtualAlloc(nil,4,MEM_RESERVE or MEM_COMMIT,PAGE_EXECUTE_READWRITE or PAGE_GUARD);
    21.  if pMem=nil then writeln('pMem nil');
    22.  s:='1234';
    23.  
    24. // запись в страницу с PAGE_GUARD
    25. WriteProcessMemory(GetCurrentProcess, pMem, @s[1], 4, numWr);
    26. // всё ОК, записано 0, но эксепта в обработчике почему-то нету...
    27. Writeln(numWr);
     
  2. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    Пишет сервис же, из ядра. Точнее, пытается писать – но наталкивается на PAGE_GUARD, в ядре возникает сепшн, ядром обрабатывается, PAGE_GUARD снимается, и сервис тут же возвращает ошибку. Всё в соответствии с msdn. Если в данном случае попытаться напрямую записать\считать из страницы с PAGE_GUARD (не через сервис), то сепшн будет получен в юзермоде и хендлер _будет_ вызван.

    P.S. Если удастся воспроизвести ситуацию, когда сервис вернёт ошибку, а PAGE_GUARD не будет снят – просьба сообщить.
     
  3. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Вопрос - зачем так делать? Никогда не понимал, зачем люди вызывают Read/WriteProcessMemory с псевдохендлом текущего процесса. Неужели memcpy() (а принеобходимости + VirtualProtect) отменили?
     
  4. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    В случае если несколько потоков обращаются к сторожевой странице или ядро обращается к ней, следует полностью запретить доступ(PAGE_NOACCESS).
     
  5. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Clerk
    Забей, ничего, туплю по утру.
     
  6. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Great
    Не совсем понял что это значит. Кстате обратится к сторожевой странице без генерации сепшена и снятием атрибута PAGE_GUARD можно просто, загрузить начало и конец сторожевого региона в TIB(TEB.Tib.StackBase и StackLimit), после чего можно успешно юзать память :)
     
  7. d2k9

    d2k9 Алексей

    Публикаций:
    0
    Регистрация:
    14 сен 2008
    Сообщения:
    325
    Эээ, народ, понятно, что в пятницу все отдыхали и утром голова болит, но сейчас днём может кто-то конкретно объяснить что происходит касательно кода в посте #1 без вопросов зачем так делать и как это можно обойти.
    +++
    Точнее подтвердить то, что написано в посте #2 и таким образом получается я никак не могу обработать исключение из юзермода при записи кем-то|чем-то в юзермоде в мой процесс по адресу сторожевой страницы.

    P.S. Все эти извращения как думаю многие догадались для юзермодного запрета записи в память своего процесса с возможностью использования на х86_64.
     
  8. x0man

    x0man New Member

    Публикаций:
    0
    Регистрация:
    23 мар 2008
    Сообщения:
    358
    #1
    Код (Text):
    1. function AddVectoredExceptionHandler(FirstHandle: ULONG; VectoredHandler : Pointer): Pointer; stdcall; external 'kernel32.dll';
    2.  
    3. var
    4.   pMem: Pointer;
    5.   dWrd : DWORD;
    6.  
    7. function MyVectoredHandler(ExceptionInfo: Pointer): Longint; stdcall;
    8. begin
    9.   MessageBox(0,'Exception',0,0);
    10. end;
    11.  
    12. begin
    13.   AddVectoredExceptionHandler(1, @MyVectoredHandler);
    14.   pMem:=VirtualAlloc(nil,4,MEM_RESERVE or MEM_COMMIT,PAGE_EXECUTE_READWRITE or PAGE_GUARD);
    15.   dWrd := 1233;
    16.   asm
    17.     push eax
    18.     mov eax, pMem
    19.     push dWrd
    20.     pop dword ptr [eax]
    21.     pop eax
    22.   end;
    23.   Readln;
    24. end.
    хз...
     
  9. x0man

    x0man New Member

    Публикаций:
    0
    Регистрация:
    23 мар 2008
    Сообщения:
    358
    чот протупил)
    Код (Text):
    1.   AddVectoredExceptionHandler(1, @MyVectoredHandler);
    2.   pMem:=VirtualAlloc(nil,4,MEM_RESERVE or MEM_COMMIT,PAGE_EXECUTE_READWRITE or PAGE_GUARD);
    3.   PDWORD(pMem)^ := 123;
    4.   Readln;
    :)
     
  10. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    d2k9
    Вам Sol_Ksacap понятно обьяснил почему атрибут снимается. Любой сервис, который юзает память из юзермпэйса ставит сех в начале своей работы, далее при обращении к сторожевой странице сепшен обрабатывается в этом сех и управление возвращается. При этом код ошибки будет возвращён, никакой диспетчер исключений не будет вызван.